00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef StreamImpl_hxx
00023 #define StreamImpl_hxx
00024
00025 #include "Region.hxx"
00026 #include <list>
00027 #include <vector>
00028 #include "PhantomBuffer.hxx"
00029 namespace CLAM
00030 {
00031
00033 template <typename T>
00034 class StdList : public std::list<T>
00035 {};
00036
00037 template <typename T>
00038 class StdVector : public std::vector<T>
00039 {};
00040
00041
00042
00043 template< typename Token, template <class> class DataStructure >
00044 class StreamImpl
00045 {
00046
00047 public:
00048 void NewWritingRegionSize( Region& writer );
00050 void NewReadingRegionSize( Region& );
00051 void WriterHasAdvanced( Region& writer );
00052 void ReaderHasAdvanced( Region& reader );
00056 Token& Read(int physicalIndex, int size);
00057 Token& operator[](int physicalIndex);
00058 int LogicalSize() const;
00059 bool ExistsCircularOverlap(int rear, int writingHead) const;
00060
00061 private:
00062 void RegionHasAdvanced( Region& region );
00063
00064 DataStructure<Token> mDataImpl;
00065 };
00066
00068
00069 template< typename Token, template <class> class DataStructure >
00070 void StreamImpl<Token,DataStructure>::NewWritingRegionSize( Region& writer )
00071 {
00072 if ( writer.Size() <= LogicalSize() ) return;
00073 int newTokens = writer.Size() - LogicalSize();
00074 for( int i=0; i<newTokens; i++)
00075 mDataImpl.push_back(Token());
00076 }
00077
00078 template< typename Token, template <class> class DataStructure >
00079 void StreamImpl<Token,DataStructure>::RegionHasAdvanced( Region& region )
00080 {
00081 region.BeginDistance( region.BeginDistance() + region.Hop() );
00082
00083 if (region.BeginDistance() >= LogicalSize() )
00084 region.BeginDistance( region.BeginDistance() - LogicalSize() );
00085 }
00086
00087 template< typename Token, template <class> class DataStructure >
00088 void StreamImpl<Token,DataStructure>::NewReadingRegionSize( Region& )
00089 {
00090 }
00091
00092 template< typename Token, template <class> class DataStructure >
00093 void StreamImpl<Token,DataStructure>::WriterHasAdvanced( Region& writer )
00094 {
00095 for( int i=0; i<writer.Hop(); i++)
00096 mDataImpl.push_back(Token());
00097
00098 RegionHasAdvanced( writer );
00099 }
00100
00101 template< typename Token, template <class> class DataStructure >
00102 void StreamImpl<Token,DataStructure>::ReaderHasAdvanced( Region& reader )
00103 {
00104
00105 RegionHasAdvanced( reader);
00106 }
00107
00108 template< typename Token, template <class> class DataStructure >
00109 Token& StreamImpl<Token,DataStructure>::Read(int physicalIndex, int size)
00110 {
00111 return operator[](physicalIndex);
00112 }
00113
00114 template< typename Token, template <class> class DataStructure >
00115 Token& StreamImpl<Token,DataStructure>::operator[](int physicalIndex)
00116 {
00117 CLAM_DEBUG_ASSERT( physicalIndex < int(mDataImpl.size()), "StreamImpl operator[] - Index out of bounds" );
00118 typename DataStructure<Token>::iterator it;
00119 int i;
00120 for(i=0, it = mDataImpl.begin(); i<physicalIndex; it++, i++);
00121 return (*it);
00122 }
00123
00124 template< typename Token, template <class> class DataStructure >
00125 int StreamImpl<Token,DataStructure>::LogicalSize() const
00126 {
00127 return int(mDataImpl.size());
00128 }
00129
00130 template< typename Token, template <class> class DataStructure >
00131 bool StreamImpl<Token,DataStructure>::ExistsCircularOverlap(int rear, int writingHead) const
00132 {
00133 return false;
00134 }
00135
00136
00137
00138 template< typename Token >
00139 class StreamImpl<Token, PhantomBuffer>
00140 {
00141
00142 public:
00143 void NewWritingRegionSize( Region& writer );
00144 void NewReadingRegionSize( Region& reader );
00146 void WriterHasAdvanced( Region& writer );
00147 void ReaderHasAdvanced( Region& reader );
00148
00149 Token& Read(int physicalIndex, int size);
00150 Token& operator[](int physicalIndex);
00151 int LogicalSize() const;
00156 int PhantomSize();
00157 bool ExistsCircularOverlap(int rear, int writingHead) const;
00158 private:
00159 int ExponentOfClosestGreaterPowerOfTwo( int newSize);
00160 void CommonNewRegionSize( Region& anyRegion );
00161 bool ReaderAffectedByInsertion( Region & reader, Region & writer ) const;
00162 void UpdateBeginDistanceOfReadingRegions( Region & writer, int tokensInserted );
00163 void RegionHasAdvanced( Region& region );
00164
00165 PhantomBuffer<Token> mDataImpl;
00166 };
00167
00169
00170 template< typename Token >
00171 void StreamImpl<Token, PhantomBuffer>::NewWritingRegionSize( Region& writer )
00172 {
00173 CLAM_DEBUG_ASSERT( writer.Size()>0, "StreamImpl::newWritingRegionSize() - size must be greater than 0" );
00174 CLAM_DEBUG_ASSERT( !writer.ProducerRegion(), "StreamImpl::newWritingRegionSize() - region must be a WritingRegion" );
00175 CommonNewRegionSize( writer );
00176 }
00177
00178 template< typename Token >
00179 void StreamImpl<Token, PhantomBuffer>::NewReadingRegionSize( Region& reader )
00180 {
00181 CLAM_DEBUG_ASSERT( reader.ProducerRegion(), "StreamImpl::newReadingRegionSize() - region must be a ReadingRegion" );
00182 CommonNewRegionSize(reader);
00183 }
00184
00185 template< typename Token >
00186 void StreamImpl<Token, PhantomBuffer>::CommonNewRegionSize( Region& anyRegion )
00187 {
00188 int newLogicalSize;
00189 int newPhantomSize;
00190
00191 if(anyRegion.Size()==1)
00192 {
00193 newLogicalSize = anyRegion.Size();
00194 newPhantomSize = 0;
00195 }
00196 else
00197 {
00198 int logicalSizeCandidate = anyRegion.Size()*2;
00199 newLogicalSize = 1 << ExponentOfClosestGreaterPowerOfTwo(logicalSizeCandidate);
00200 newPhantomSize = anyRegion.Size()-1;
00201 }
00202
00203 if(newLogicalSize <= LogicalSize())
00204 return;
00205
00206 CLAM_DEBUG_ASSERT(newLogicalSize > LogicalSize(), "StreamImpl::commonNewRegionSize() - new logical size"
00207 "must be greater than the older logical size" );
00208
00209 Region & producer = anyRegion.ProducerRegion() ? (*anyRegion.ProducerRegion()) : anyRegion;
00210 int insertionPos = producer.BeginDistance();
00211
00212 int tokensToInsert = newLogicalSize - LogicalSize();
00213
00214 mDataImpl.Resize(
00215 newLogicalSize,
00216 std::max(newPhantomSize,PhantomSize()),
00217 insertionPos );
00218
00219 UpdateBeginDistanceOfReadingRegions( producer, tokensToInsert );
00220 }
00221
00222 template< typename Token >
00223 bool StreamImpl<Token, PhantomBuffer>::ReaderAffectedByInsertion( Region & reader, Region & writer ) const
00224 {
00225
00226
00227
00228 if (reader.BeginDistance() > writer.BeginDistance())
00229 return true;
00230
00231
00232
00233
00234 if( reader.BeginDistance()==writer.BeginDistance() && reader.Pos() < writer.Pos() )
00235 return true;
00236 return false;
00237 }
00238
00239 template< typename Token >
00240 void StreamImpl<Token, PhantomBuffer>::UpdateBeginDistanceOfReadingRegions( Region & writer, int tokensInserted )
00241 {
00244 Region::ReadingRegionsIterator actualReader;
00245
00246 for ( actualReader=writer.BeginReaders(); actualReader!=writer.EndReaders(); actualReader++)
00247 if( ReaderAffectedByInsertion(**actualReader, writer) )
00248 (*actualReader)->BeginDistance( (*actualReader)->BeginDistance() + tokensInserted );
00249 }
00250
00251 template< typename Token >
00252 void StreamImpl<Token, PhantomBuffer>::RegionHasAdvanced( Region& region )
00253 {
00254 region.BeginDistance( region.BeginDistance() + region.Hop());
00255 if (region.BeginDistance() >= LogicalSize() )
00256 region.BeginDistance( region.BeginDistance() - LogicalSize());
00257 }
00258
00259 template< typename Token >
00260 void StreamImpl<Token, PhantomBuffer>::WriterHasAdvanced( Region& writer )
00261 {
00262 mDataImpl.Touch( writer.BeginDistance(), writer.Size() );
00263 RegionHasAdvanced( writer );
00264 }
00265
00266 template< typename Token >
00267 void StreamImpl<Token, PhantomBuffer>::ReaderHasAdvanced( Region& reader )
00268 {
00269 RegionHasAdvanced( reader );
00270 }
00271
00272 template< typename Token >
00273 Token& StreamImpl<Token, PhantomBuffer>::Read(int physicalIndex, int size)
00274 {
00275 return *mDataImpl.Read( physicalIndex, size );
00276 }
00277
00278 template< typename Token >
00279 Token& StreamImpl<Token, PhantomBuffer>::operator[](int physicalIndex)
00280 {
00281 CLAM_DEBUG_ASSERT( physicalIndex < LogicalSize()+PhantomSize(), "StreamImpl::operator[] - Index out of bounds" );
00282 return Read( physicalIndex, 1);
00283 }
00284
00285 template< typename Token >
00286 int StreamImpl<Token, PhantomBuffer>::LogicalSize() const
00287 {
00288 return mDataImpl.LogicalSize();
00289 }
00290
00291 template< typename Token >
00292 int StreamImpl<Token, PhantomBuffer>::PhantomSize()
00293 {
00294 return mDataImpl.PhantomSize();
00295 }
00296
00297 template< typename Token >
00298 bool StreamImpl<Token, PhantomBuffer>::ExistsCircularOverlap(int rear, int writingHead) const
00299 {
00300 return writingHead - rear > LogicalSize();
00301 }
00302
00303 template< typename Token >
00304 int StreamImpl<Token, PhantomBuffer>::ExponentOfClosestGreaterPowerOfTwo( int newSize)
00305 {
00306 int newLogicalSize = 1;
00307 int power = 0;
00308 while( newLogicalSize < newSize )
00309 {
00310 newLogicalSize <<= 1;
00311 power++;
00312 }
00313 return power;
00314 }
00315
00316 }
00317
00318 #endif // StreamImpl_hxx
00319