Point Cloud Library (PCL)
1.7.0
|
00001 /* 00002 Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho 00003 All rights reserved. 00004 00005 Redistribution and use in source and binary forms, with or without modification, 00006 are permitted provided that the following conditions are met: 00007 00008 Redistributions of source code must retain the above copyright notice, this list of 00009 conditions and the following disclaimer. Redistributions in binary form must reproduce 00010 the above copyright notice, this list of conditions and the following disclaimer 00011 in the documentation and/or other materials provided with the distribution. 00012 00013 Neither the name of the Johns Hopkins University nor the names of its contributors 00014 may be used to endorse or promote products derived from this software without specific 00015 prior written permission. 00016 00017 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 00018 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES 00019 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 00020 SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00021 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00022 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 00023 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00024 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00025 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00026 DAMAGE. 00027 */ 00028 00029 #ifndef ALLOCATOR_INCLUDED 00030 #define ALLOCATOR_INCLUDED 00031 #include <vector> 00032 00033 namespace pcl 00034 { 00035 namespace poisson 00036 { 00037 class AllocatorState{ 00038 public: 00039 int index,remains; 00040 }; 00041 /** This templated class assists in memory allocation and is well suited for instances 00042 * when it is known that the sequence of memory allocations is performed in a stack-based 00043 * manner, so that memory allocated last is released first. It also preallocates memory 00044 * in chunks so that multiple requests for small chunks of memory do not require separate 00045 * system calls to the memory manager. 00046 * The allocator is templated off of the class of objects that we would like it to allocate, 00047 * ensuring that appropriate constructors and destructors are called as necessary. 00048 */ 00049 template<class T> 00050 class Allocator{ 00051 int blockSize; 00052 int index,remains; 00053 std::vector<T*> memory; 00054 public: 00055 Allocator(void){ 00056 blockSize=index=remains=0; 00057 } 00058 ~Allocator(void){ 00059 reset(); 00060 } 00061 00062 /** This method is the allocators destructor. It frees up any of the memory that 00063 * it has allocated. */ 00064 void reset(void){ 00065 for(size_t i=0;i<memory.size();i++){delete[] memory[i];} 00066 memory.clear(); 00067 blockSize=index=remains=0; 00068 } 00069 /** This method returns the memory state of the allocator. */ 00070 AllocatorState getState(void) const{ 00071 AllocatorState s; 00072 s.index=index; 00073 s.remains=remains; 00074 return s; 00075 } 00076 00077 00078 /** This method rolls back the allocator so that it makes all of the memory previously 00079 * allocated available for re-allocation. Note that it does it not call the constructor 00080 * again, so after this method has been called, assumptions about the state of the values 00081 * in memory are no longer valid. */ 00082 void rollBack(void){ 00083 if(memory.size()){ 00084 for(size_t i=0;i<memory.size();i++){ 00085 for(int j=0;j<blockSize;j++){ 00086 memory[i][j].~T(); 00087 new(&memory[i][j]) T(); 00088 } 00089 } 00090 index=0; 00091 remains=blockSize; 00092 } 00093 } 00094 /** This method rolls back the allocator to the previous memory state and makes all of the memory previously 00095 * allocated available for re-allocation. Note that it does it not call the constructor 00096 * again, so after this method has been called, assumptions about the state of the values 00097 * in memory are no longer valid. */ 00098 void rollBack(const AllocatorState& state){ 00099 if(state.index<index || (state.index==index && state.remains<remains)){ 00100 if(state.index<index){ 00101 for(int j=state.remains;j<blockSize;j++){ 00102 memory[state.index][j].~T(); 00103 new(&memory[state.index][j]) T(); 00104 } 00105 for(int i=state.index+1;i<index-1;i++){ 00106 for(int j=0;j<blockSize;j++){ 00107 memory[i][j].~T(); 00108 new(&memory[i][j]) T(); 00109 } 00110 } 00111 for(int j=0;j<remains;j++){ 00112 memory[index][j].~T(); 00113 new(&memory[index][j]) T(); 00114 } 00115 index=state.index; 00116 remains=state.remains; 00117 } 00118 else{ 00119 for(int j=0;j<state.remains;j<remains){ 00120 memory[index][j].~T(); 00121 new(&memory[index][j]) T(); 00122 } 00123 remains=state.remains; 00124 } 00125 } 00126 } 00127 00128 /** This method initiallizes the constructor and the blockSize variable specifies the 00129 * the number of objects that should be pre-allocated at a time. */ 00130 void set( int blockSize){ 00131 reset(); 00132 this->blockSize=blockSize; 00133 index=-1; 00134 remains=0; 00135 } 00136 00137 /** This method returns a pointer to an array of elements objects. If there is left over pre-allocated 00138 * memory, this method simply returns a pointer to the next free piece of memory, otherwise it pre-allocates 00139 * more memory. Note that if the number of objects requested is larger than the value blockSize with which 00140 * the allocator was initialized, the request for memory will fail. 00141 */ 00142 T* newElements( int elements=1){ 00143 T* mem; 00144 if(!elements){return NULL;} 00145 if(elements>blockSize){ 00146 fprintf(stderr,"Allocator Error, elements bigger than block-size: %d>%d\n",elements,blockSize); 00147 return NULL; 00148 } 00149 if(remains<elements){ 00150 if(index==memory.size()-1){ 00151 mem=new T[blockSize]; 00152 if(!mem){fprintf(stderr,"Failed to allocate memory\n");exit(0);} 00153 memory.push_back(mem); 00154 } 00155 index++; 00156 remains=blockSize; 00157 } 00158 mem=&(memory[index][blockSize-remains]); 00159 remains-=elements; 00160 return mem; 00161 } 00162 }; 00163 00164 00165 } 00166 } 00167 00168 #endif // ALLOCATOR_INCLUDE