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 ) {
00027 return this->nextSequence();
00028 } else {
00029 rval++;
00030 return ++cval;
00031 }
00032 }
00033 int nextSequence()
00034 {
00035 rval += this->runLength();
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 {
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
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 ) {
00104 this->flush();
00105 run = erun; start = elt;
00106 } else if ( elt == start + run ) {
00107 run += erun;
00108 } else {
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