StreamImpl.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 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() ) // circular movement
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         // TODO: discard old tokens
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, // phantom buffer size
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         // a reader will be affected by the insertion of new tokens due a writer's resize if:
00214         
00215         // a) the reader is physically positioned (beginDistance) at the rear of the writer.
00216         if (reader.BeginDistance() > writer.BeginDistance()) 
00217                 return true;
00218         
00219         // b) the reader is physically positioned (beginDistance) at the same position than the writer AND
00220         // is logically position (pos) after the writer. It means that the writer is exactly at
00221         // LogicalSize() positions before the reader.
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() ) // circular movement
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 } // namespace CLAM
00305 
00306 #endif // StreamImpl_hxx
00307 

Generated on Tue Aug 12 22:33:45 2008 for CLAM by  doxygen 1.5.5