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 logicalSizeCandidate = anyRegion.Size()*2;
00189
00190 if(logicalSizeCandidate <= LogicalSize())
00191 return;
00192
00193 Region & producer = anyRegion.ProducerRegion() ? (*anyRegion.ProducerRegion()) : anyRegion;
00194 int insertionPos = producer.BeginDistance();
00195
00196 int newLogicalSize = 1 << ExponentOfClosestGreaterPowerOfTwo(logicalSizeCandidate);
00197
00198 CLAM_DEBUG_ASSERT(newLogicalSize > LogicalSize(), "StreamImpl::commonNewRegionSize() - new logical size"
00199 "must be greater than the older logical size" );
00200 int tokensToInsert = newLogicalSize - LogicalSize();
00201
00202 mDataImpl.Resize(
00203 newLogicalSize,
00204 anyRegion.Size()*2,
00205 insertionPos );
00206
00207 UpdateBeginDistanceOfReadingRegions( producer, tokensToInsert );
00208 }
00209
00210 template< typename Token >
00211 bool StreamImpl<Token, PhantomBuffer>::ReaderAffectedByInsertion( Region & reader, Region & writer ) const
00212 {
00213
00214
00215
00216 if (reader.BeginDistance() > writer.BeginDistance())
00217 return true;
00218
00219
00220
00221
00222 if( reader.BeginDistance()==writer.BeginDistance() && reader.Pos() < writer.Pos() )
00223 return true;
00224 return false;
00225 }
00226
00227 template< typename Token >
00228 void StreamImpl<Token, PhantomBuffer>::UpdateBeginDistanceOfReadingRegions( Region & writer, int tokensInserted )
00229 {
00232 Region::ReadingRegionsIterator actualReader;
00233
00234 for ( actualReader=writer.BeginReaders(); actualReader!=writer.EndReaders(); actualReader++)
00235 if( ReaderAffectedByInsertion(**actualReader, writer) )
00236 (*actualReader)->BeginDistance( (*actualReader)->BeginDistance() + tokensInserted );
00237 }
00238
00239 template< typename Token >
00240 void StreamImpl<Token, PhantomBuffer>::RegionHasAdvanced( Region& region )
00241 {
00242 region.BeginDistance( region.BeginDistance() + region.Hop());
00243 if (region.BeginDistance() >= LogicalSize() )
00244 region.BeginDistance( region.BeginDistance() - LogicalSize());
00245 }
00246
00247 template< typename Token >
00248 void StreamImpl<Token, PhantomBuffer>::WriterHasAdvanced( Region& writer )
00249 {
00250 mDataImpl.Touch( writer.BeginDistance(), writer.Size() );
00251 RegionHasAdvanced( writer );
00252 }
00253
00254 template< typename Token >
00255 void StreamImpl<Token, PhantomBuffer>::ReaderHasAdvanced( Region& reader )
00256 {
00257 RegionHasAdvanced( reader );
00258 }
00259
00260 template< typename Token >
00261 Token& StreamImpl<Token, PhantomBuffer>::Read(int physicalIndex, int size)
00262 {
00263 return *mDataImpl.Read( physicalIndex, size );
00264 }
00265
00266 template< typename Token >
00267 Token& StreamImpl<Token, PhantomBuffer>::operator[](int physicalIndex)
00268 {
00269 CLAM_DEBUG_ASSERT( physicalIndex < LogicalSize()+PhantomSize(), "StreamImpl::operator[] - Index out of bounds" );
00270 return Read( physicalIndex, 1);
00271 }
00272
00273 template< typename Token >
00274 int StreamImpl<Token, PhantomBuffer>::LogicalSize() const
00275 {
00276 return mDataImpl.LogicalSize();
00277 }
00278
00279 template< typename Token >
00280 int StreamImpl<Token, PhantomBuffer>::PhantomSize()
00281 {
00282 return mDataImpl.PhantomSize();
00283 }
00284
00285 template< typename Token >
00286 bool StreamImpl<Token, PhantomBuffer>::ExistsCircularOverlap(int rear, int writingHead) const
00287 {
00288 return writingHead - rear > LogicalSize();
00289 }
00290
00291 template< typename Token >
00292 int StreamImpl<Token, PhantomBuffer>::ExponentOfClosestGreaterPowerOfTwo( int newSize)
00293 {
00294 int newLogicalSize = 1;
00295 int power = 0;
00296 while( newLogicalSize < newSize )
00297 {
00298 newLogicalSize <<= 1;
00299 power++;
00300 }
00301 return power;
00302 }
00303
00304 }
00305
00306 #endif // StreamImpl_hxx
00307