00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef __WritingRegion_hxx__
00023 #define __WritingRegion_hxx__
00024
00025 #include "ReadingRegion.hxx"
00026 #include "StreamImpl.hxx"
00027
00028 #include <iostream>
00029
00030 namespace CLAM
00031 {
00032
00033 template< typename Token, template <class> class DataStructure = PhantomBuffer>
00034 class WritingRegion : public Region
00035 {
00036 public:
00037 typedef StreamImpl< Token, DataStructure > ProperStream;
00038 typedef Token ProperToken;
00039 typedef ReadingRegion< WritingRegion<Token,DataStructure> > ProperReadingRegion;
00040
00041 WritingRegion();
00042 virtual ~WritingRegion();
00043
00044 Region::ReadingRegionsIterator BeginReaders();
00045 Region::ReadingRegionsIterator EndReaders();
00046 void LinkRegions( ProperReadingRegion & reader);
00047 void RemoveRegion( Region & region );
00048
00053 void CenterEvenRegions();
00054
00058 ProperStream& Stream();
00059
00061 int RearmostReadingPos();
00062
00068 bool CanProduce();
00069 void Produce();
00070
00071 Token& operator[](int offset);
00072 bool FulfilsInvariant();
00073 int LogicalStreamSize();
00074 Region* ProducerRegion();
00075
00079 void ClearData();
00080
00081
00082
00083
00084
00085 Token & GetLastWrittenData( int offset = 0);
00086 private:
00088 WritingRegion(const WritingRegion<Token>& original){}
00089 void SizeChanged(const int & newSize);
00090 int GetGreatestReaderRegionSize();
00091
00092
00093
00094
00095 void CheckRegionsAreEven();
00096 void CenterReadingRegions( int centralIndex );
00097
00098
00099
00100
00101 void SyncFollowerRegion();
00102
00103 ReadingRegionsList mReadingRegions;
00104 ProperStream mStream;
00105 ProperReadingRegion mFollowerRegion;
00106 };
00107
00109
00110 template< typename Token, template <class> class DataStructure>
00111 WritingRegion< Token, DataStructure >::WritingRegion()
00112 {
00113 SizeChanged( Size() );
00114 }
00115
00116 template< typename Token, template <class> class DataStructure>
00117 WritingRegion< Token, DataStructure >::~WritingRegion()
00118 {
00119 ReadingRegionsIterator it;
00120 for(it=BeginReaders(); it!=EndReaders(); it++)
00121 (*it)->RemoveProducer();
00122 mReadingRegions.clear();
00123 }
00124
00125 template< typename Token, template <class> class DataStructure>
00126 Region::ReadingRegionsIterator WritingRegion< Token, DataStructure >::BeginReaders()
00127 {
00128 return mReadingRegions.begin();
00129 }
00130
00131 template< typename Token, template <class> class DataStructure>
00132 Region::ReadingRegionsIterator WritingRegion< Token, DataStructure >::EndReaders()
00133 {
00134 return mReadingRegions.end();
00135 }
00136
00137 template< typename Token, template <class> class DataStructure>
00138 void WritingRegion< Token, DataStructure >::LinkRegions( ProperReadingRegion & reader)
00139 {
00140 mReadingRegions.push_back(&reader);
00141 reader.LinkProducerRegion(*this);
00142 reader.LinkAndNotifySizeToStream( Stream() );
00143 }
00144
00145 template< typename Token, template <class> class DataStructure>
00146 int WritingRegion< Token, DataStructure >::GetGreatestReaderRegionSize()
00147 {
00148 int maxSize = 0;
00149
00150 ReadingRegionsIterator it;
00151 for(it=BeginReaders(); it!=EndReaders(); it++)
00152 {
00153 if(((*it)->Size())>maxSize)
00154 maxSize = (*it)->Size();
00155 }
00156
00157 return maxSize;
00158 }
00159
00160 template< typename Token, template <class> class DataStructure>
00161 void WritingRegion<Token, DataStructure >::CheckRegionsAreEven()
00162 {
00163
00164 CLAM_ASSERT( Size()%2==0, "WritingRegion::CheckRegionsAreEven - Writer's size must be even for centering." );
00165
00166 ReadingRegionsIterator it;
00167 for(it=BeginReaders(); it!=EndReaders(); it++)
00168 {
00169 CLAM_ASSERT( (*it)->Size()%2==0, "WritingRegion::CheckRegionsAreEven - Reader's size must be even for centering.");
00170 }
00171
00172 }
00173
00174 template< typename Token, template <class> class DataStructure>
00175 void WritingRegion< Token, DataStructure >::ClearData()
00176 {
00177 for( int i=0; i<Size(); i++ )
00178 operator[](i) = Token();
00179 }
00180
00181 template< typename Token, template <class> class DataStructure>
00182 void WritingRegion< Token, DataStructure >::CenterReadingRegions( int centralIndex )
00183 {
00184 ReadingRegionsIterator it;
00185 for(it=BeginReaders(); it!=EndReaders(); it++)
00186 {
00187 int hopToMove = centralIndex - (*it)->Size()/2;
00188 (*it)->Pos( hopToMove );
00189 (*it)->BeginDistance( hopToMove );
00190 }
00191 }
00192
00193 template< typename Token, template <class> class DataStructure>
00194 void WritingRegion< Token, DataStructure >::CenterEvenRegions()
00195 {
00196 CheckRegionsAreEven();
00197 int centralIndex = GetGreatestReaderRegionSize()/2;
00198
00199 Pos( 0 );
00200 BeginDistance( 0);
00201
00202 int currentHop = Hop();
00203 int currentSize = Size();
00204
00205 Size( centralIndex);
00206 Hop( centralIndex );
00207
00208 ClearData();
00209
00210
00211 CenterReadingRegions( centralIndex );
00212
00213 Produce();
00214 Size( currentSize );
00215 Hop( currentHop );
00216
00217
00218
00219 }
00220
00221 template< typename Token, template <class> class DataStructure>
00222 void WritingRegion< Token, DataStructure >::RemoveRegion( Region & region )
00223 {
00224 CLAM_ASSERT( region.ProducerRegion()==this, "Region::RemoveRegion() - Trying to remove an unlinked region");
00225
00226 mReadingRegions.remove( ®ion );
00227 region.RemoveProducer();
00228 }
00229
00230 template< typename Token, template <class> class DataStructure>
00231 typename WritingRegion< Token, DataStructure>::ProperStream& WritingRegion< Token, DataStructure >::Stream()
00232 {
00233 return mStream;
00234 }
00235
00236 template< typename Token, template <class> class DataStructure>
00237 int WritingRegion< Token, DataStructure >::RearmostReadingPos()
00238 {
00239 int result = Pos();
00240 ReadingRegionsIterator it;
00241 for(it=mReadingRegions.begin(); it!=mReadingRegions.end(); it++)
00242 if( (*it)->Pos() < result) result = (*it)->Pos();
00243
00244 return result;
00245 }
00246
00247 template< typename Token, template <class> class DataStructure>
00248 bool WritingRegion< Token, DataStructure >::CanProduce()
00249 {
00250 CLAM_DEBUG_ASSERT( FulfilsInvariant(), "WritingRegion::canProduce() - fulfils invariant checking failed" );
00251 return !mStream.ExistsCircularOverlap( RearmostReadingPos(), Pos()+Size() );
00252 }
00253
00254 template< typename Token, template <class> class DataStructure>
00255 void WritingRegion< Token, DataStructure >::Produce()
00256 {
00257 CLAM_DEBUG_ASSERT( CanProduce(), "WritingRegion::produce() - WritingRegion can't produce" );
00258 Pos( Pos() + Hop());
00259
00260 mStream.WriterHasAdvanced( *this );
00261 }
00262
00263 template< typename Token, template <class> class DataStructure>
00264 Token& WritingRegion< Token, DataStructure >::operator[](int offset)
00265 {
00266
00267 CLAM_DEBUG_ASSERT(0 <= offset && offset < Size(), "WritingRegion::operator [] - Index out of bounds" );
00268 int physicalIndex = BeginDistance() + offset;
00269
00270 if (offset==0)
00271 return mStream.Read(physicalIndex, Size());
00272 return mStream[physicalIndex];
00273 }
00274
00275 template< typename Token, template <class> class DataStructure>
00276 bool WritingRegion< Token, DataStructure >::FulfilsInvariant()
00277 {
00278 ReadingRegionsIterator it;
00279 for(it=mReadingRegions.begin(); it!=mReadingRegions.end(); it++)
00280 if( (*it)->Pos() >= Pos()+Size() )
00281 return false;
00282 return true;
00283 }
00284
00285 template< typename Token, template <class> class DataStructure>
00286 int WritingRegion< Token, DataStructure >::LogicalStreamSize()
00287 {
00288 return mStream.LogicalSize();
00289 }
00290
00291 template< typename Token, template <class> class DataStructure>
00292 Region* WritingRegion< Token, DataStructure >::ProducerRegion()
00293 {
00294 return 0;
00295 }
00296
00297 template< typename Token, template <class> class DataStructure>
00298 void WritingRegion< Token, DataStructure >::SizeChanged(const int & newSize)
00299 {
00300 mStream.NewWritingRegionSize( *this );
00301 }
00302
00303 template< typename Token, template <class> class DataStructure>
00304 void WritingRegion< Token, DataStructure >::SyncFollowerRegion()
00305 {
00306 mFollowerRegion.LinkProducerRegion(*this);
00307 mFollowerRegion.Size( Size() );
00308 mFollowerRegion.Hop( Hop() );
00309 mFollowerRegion.LinkAndNotifySizeToStream( Stream() );
00310
00311 mFollowerRegion.Pos( Pos() - Hop() );
00312 mFollowerRegion.BeginDistance( BeginDistance() - Hop() );
00313 if(mFollowerRegion.BeginDistance() < 0 )
00314 mFollowerRegion.BeginDistance( mFollowerRegion.BeginDistance() + mStream.LogicalSize() );
00315 }
00316
00317 template< typename Token, template <class> class DataStructure>
00318 Token & WritingRegion< Token, DataStructure >::GetLastWrittenData( int offset)
00319 {
00320 SyncFollowerRegion();
00321 int physicalIndex = mFollowerRegion.BeginDistance() + offset;
00322
00323 return mStream.operator[]( physicalIndex );
00324 }
00325
00326 }
00327
00328 #endif // __WritingRegion_hxx__
00329