PhantomBuffer.hxx
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef _PHANTOM_BUFFER_H
00023 #define _PHANTOM_BUFFER_H
00024
00025
00026 #include <vector>
00027 #include <iostream>
00028 #include "Assert.hxx"
00029
00030 namespace CLAM {
00031
00032 template<class T>
00033 class PhantomBuffer
00034 {
00035 public:
00036 PhantomBuffer();
00037 T* Read(unsigned int pos, unsigned int size);
00038
00044 void Touch(unsigned int pos, unsigned int size);
00045
00051 void Write(unsigned int pos, unsigned int size,const T* data);
00052
00053 unsigned LogicalSize() const {return mLogicalSize;}
00054
00055 unsigned int PhantomSize() const { return mBuffer.size() - mLogicalSize; }
00056
00057 void Resize(unsigned int size,
00058 unsigned int phantom,
00059 unsigned int insert_pos);
00060
00067 void FulfilsInvariant() const;
00068
00069 private:
00074 void UpdatePhantom(unsigned int pos, unsigned int size);
00079 void UpdateBeginning(unsigned int pos, unsigned int size);
00080
00081 unsigned int AllocatedSize() const
00082 {
00083 return mBuffer.size();
00084 }
00085
00086
00087
00088 std::vector<T> mBuffer;
00089 unsigned mLogicalSize;
00090 };
00091
00092
00093 template<class T>
00094 PhantomBuffer<T>::PhantomBuffer()
00095 : mLogicalSize(0)
00096 {}
00097
00098
00099 template<class T>
00100 void PhantomBuffer<T>::UpdatePhantom(unsigned int pos, unsigned int size)
00101 {
00102 CLAM_DEBUG_ASSERT(pos+size <= PhantomSize(),
00103 "PhantomBuffer::UpdatePhantom():"
00104 "Requested region falls outside phantom zone");
00105 unsigned int s,d;
00106 for (s=pos, d=mLogicalSize+pos; s<pos+size; s++, d++)
00107 mBuffer[d] = mBuffer[s];
00108 }
00109
00110 template<class T>
00111 void PhantomBuffer<T>::UpdateBeginning(unsigned int pos, unsigned int size)
00112 {
00113 CLAM_DEBUG_ASSERT(pos+size <= PhantomSize(),
00114 "PhantomBuffer::UpdateBeginning():"
00115 "Requested region falls outside beginning zone");
00116 unsigned int s,d;
00117 for (d=pos, s=mLogicalSize+pos; d<size; d++, s++)
00118 mBuffer[d] = mBuffer[s];
00119 }
00120
00121
00122 template<class T>
00123 void PhantomBuffer<T>::Resize(unsigned int newLogicalSize, unsigned int newPhantomSize, unsigned int insertionPos)
00124 {
00125 CLAM_ASSERT(insertionPos <= LogicalSize(),
00126 "PhantomBuffer::Resize(): "
00127 "Insertion position can not be greater than previous size.");
00128 CLAM_ASSERT(newPhantomSize <= newLogicalSize,
00129 "PhantomBuffer::Resize(): Phantom Size can not be greater than size.");
00130
00131 if ( newLogicalSize <= LogicalSize() )
00132 return;
00133
00134 CLAM_ASSERT(newPhantomSize >= PhantomSize(),
00135 "PhantomBuffer::Resize(): PhantomSize can not be decreased.");
00136
00137 unsigned int logicalElementsToInsert = newLogicalSize - LogicalSize();
00138 unsigned int phantomElementsToInsert = newPhantomSize - PhantomSize();
00139
00140 typename std::vector<T>::iterator it = mBuffer.begin();
00141 it += insertionPos;
00142 mBuffer.insert(it, logicalElementsToInsert, T());
00143
00144 mBuffer.insert( mBuffer.end(), phantomElementsToInsert, T());
00145
00146
00147 mLogicalSize = newLogicalSize;
00148 }
00149
00150
00151 template<class T>
00152 T* PhantomBuffer<T>::Read(unsigned int pos, unsigned int size)
00153 {
00154 CLAM_DEBUG_ASSERT( (pos+size-1) <= ( AllocatedSize() ),
00155 "PhantomBuffer::Read(): Position outside bounds");
00156 return &mBuffer[pos];
00157 }
00158
00159
00160 template<class T>
00161 void PhantomBuffer<T>::Touch(unsigned int pos, unsigned int size)
00162 {
00163 CLAM_DEBUG_ASSERT( (pos+size) <= ( AllocatedSize() ),
00164 "PhantomBuffer::Write(): Position outside bounds");
00165 unsigned int writen_area_end = pos+size;
00166
00167 if (writen_area_end > mLogicalSize)
00168 {
00169 unsigned int update_start;
00170 if (mLogicalSize > pos)
00171 update_start = 0;
00172 else
00173 update_start = pos-mLogicalSize;
00174 UpdateBeginning(update_start, writen_area_end - mLogicalSize - update_start);
00175 }
00176 else if ( pos < PhantomSize() )
00177 {
00178 int update_end;
00179 if (PhantomSize() < writen_area_end )
00180 update_end = PhantomSize();
00181 else
00182 update_end = writen_area_end;
00183 UpdatePhantom(pos,update_end-pos);
00184 }
00185 }
00186
00187
00188 template<class T>
00189 void PhantomBuffer<T>::Write(unsigned int pos, unsigned int size,const T* data)
00190 {
00191 CLAM_DEBUG_ASSERT( (pos+size) <= ( AllocatedSize() ),
00192 "PhantomBuffer::Write(): Position outside bounds");
00193 unsigned int s,d;
00194
00195 for (s=0, d=pos; s<size; s++, d++)
00196 mBuffer[d] = data[s];
00197 Touch(pos,size);
00198 }
00199
00200
00201 template<class T>
00202 void PhantomBuffer<T>::FulfilsInvariant() const
00203 {
00204 CLAM_ASSERT(mBuffer.size() == AllocatedSize(),
00205 "PhantomBuffer<T>::FulfilsInvariant(): "
00206 "internal vector size unconsistency");
00207 CLAM_ASSERT(PhantomSize() <= mLogicalSize,
00208 "PhantomBuffer<T>::FulfilsInvariant(): "
00209 "Phantom size biger than logical size");
00210 unsigned int i;
00211 for (i=0; i<PhantomSize(); i++)
00212 CLAM_ASSERT(mBuffer[i] == mBuffer[i+mLogicalSize],
00213 "PhantomBuffer<T>::FulfilsInvariant(): "
00214 "Phantom data is unconsistent!");
00215
00216 }
00217
00218 }
00219
00220 #endif
00221