Main Page   Modules   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages  

IndexSetUtilities.hh

00001 #ifndef INDEXSETUTILITES
00002 #define INDEXSETUTILITES
00003 
00004 #include "IotrUtilities.hh"
00005 #include<vector>
00006 #include<assert.h>
00007 
00012 class IndexSetIterator {
00013   const int * index;
00014   int n, k, end, cval, rval, notFoundValue;
00015 public:
00016   int currentValue() { return cval; }
00017   int rangeValue() { return rval; }
00018   int runLength() { return end - cval + 1; }
00019   int endSequence() { return end; }
00020   IndexSetIterator( const int * ii, int nn, int nf ) :
00021     index(ii), n(nn), k(0), end(-1), cval(0), rval(0), notFoundValue(nf)
00022   {}
00023   int empty() { return cval == notFoundValue; }
00024   int next()
00025   {
00026     if( cval >= end ) { // No more elts in the run, start a new sequence
00027       return this->nextSequence();
00028     } else { 
00029       rval++;
00030       return ++cval;
00031     }
00032   }
00033   int nextSequence()
00034   {
00035     rval += this->runLength(); // skipping "run" values in the range
00036     if( k < n ) { 
00037       int ind = index[k++];
00038       if( ind >= 0 ) {
00039         end = ind;
00040         return cval = ind;
00041       } else {
00042         cval = index[k++];
00043         end = cval - ind - 1;
00044         return cval;
00045       }
00046     } else { // Empty stack
00047       end = notFoundValue;  k = n;
00048       return cval = notFoundValue;
00049     }
00050   }
00052   int next( int n )
00053   {
00054     rval += n;
00055     int i = n;
00056     while( i > 0 ) {
00057       if( cval + i <= end ) {
00058         cval += i; i = 0;
00059       } else {
00060         i -= this->runLength();
00061         this->nextSequence();
00062       }
00063     }
00064     return cval;
00065   }
00067   int seekAtLeast( int val )
00068   {
00069     while( cval != notFoundValue && val > end ) {
00070       // val is not in the current sequence
00071       this->nextSequence();
00072     }
00073     if( cval != notFoundValue && val > cval ) {
00074       rval += (val - cval);
00075       cval  = val;
00076     }
00077     return cval;
00078   }
00079 };
00080 
00081 
00086 class IndexSetCollector {
00087   std::vector<int> index;
00088   int run, start,  mRange;
00089 public:
00090   IndexSetCollector() : run(0), start(0), mRange(0) {}
00091   IndexSetCollector( int capacity ) :
00092     run(0), start(0), mRange(0)
00093   {
00094     index.reserve( capacity );
00095   }
00096   void reserve( int n ) { index.reserve( n ); }
00097   int * indices() { return index.size() > 0 ? &index[0] : 0; }
00098   int nindices() { return index.size(); }
00099   int range() { return mRange; }
00100   int last() { return mRange - 1; }
00101 
00102   int writeSequence( int elt, int erun ) {
00103     if( elt > start + run ) { // New sequence, write the old
00104       this->flush();
00105       run = erun;  start = elt;
00106     } else if ( elt == start + run ) {
00107       run += erun; 
00108     } else { // an invalid elt to write
00109       return 1;
00110     }
00111     mRange += erun;
00112     return 0;
00113   }
00114   int write( int val )
00115   {
00116     return this->writeSequence( val, 1 );
00117   }
00118   void flush()
00119   {
00120     if( run == 1 ) {
00121       index.push_back(start);
00122     } else if( run > 2 ) {
00123       index.push_back(-run); index.push_back(start);
00124     } else if ( run == 2 ) {
00125       index.push_back( start ); index.push_back( start + 1 );
00126     }
00127   }
00128 };
00129 
00130 
00131 template<class T> inline void 
00132 condensed_index_loop( const int index[], int n, const T & op )
00133 {
00134   int i = 0;
00135   int k = 0;
00136   while( k < n ) {
00137     int ind = index[k]; k++;
00138     if( ind >= 0 ) {
00139       op( i, ind );
00140       i++;
00141     } else {
00142       int start  = index[k]; k++;
00143       int end    = start - ind;
00144       for( int j = start; j < end; j++ ) {
00145         op( i, j );
00146         i++;
00147       }
00148     }
00149   }
00150 }
00151 
00152 
00153 #endif

Generated on Wed Aug 27 10:03:41 2003 for iotr by doxygen1.2.18