WritingRegion.hxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG)
00003  *                         UNIVERSITAT POMPEU FABRA
00004  *
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00022 #ifndef __WritingRegion_hxx__
00023 #define __WritingRegion_hxx__
00024 
00025 #include "ReadingRegion.hxx"
00026 #include "StreamImpl.hxx"
00027 
00028 #include <iostream> // TODO: remove
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);  // TODO decide if operator[0] is the best option to get the data chunk  
00072         bool FulfilsInvariant();
00073         int LogicalStreamSize();
00074         Region* ProducerRegion();
00075 
00079         void ClearData();
00080 
00081 
00082         /*
00083          * Synchronizes Follower Region and returns last written Tokens
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          * This method checks that all the regions have even size and are located at the correct position (the beginning of the buffer )
00094          */
00095         void CheckRegionsAreEven();
00096         void CenterReadingRegions( int centralIndex );
00097 
00098         /*
00099          *  Synchronizes the follower region with the last zone written, with the same size and hop than the writer.
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         //TODO: writer must be even?    
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( &region );
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         // reserve stream tokens for next position
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 //      CLAM_ASSERT( physicalIndex < mStream.LogicalSize(), "WritingRegion GetLastWrittenData - Out of bounds access"  );
00323         return mStream.operator[]( physicalIndex );
00324 }
00325 
00326 } // namespace CLAM
00327 
00328 #endif // __WritingRegion_hxx__
00329 
Generated by  doxygen 1.6.3