00001 #ifndef SEQUENCE_H_
00002 #define SEQUENCE_H_
00003
00004 #include "cksequence_factory.h"
00005 #include "cksequence_internal.h"
00006 #include "pup.h"
00007
00008 #include <list>
00009 #include <math.h>
00010
00011 #define CHAR_SIZE 8
00012
00021 template <typename T>
00022 class CkSequenceIterator {
00023 public:
00024
00025 CkSequenceIterator() {}
00026
00027 CkSequenceIterator(CkSequenceIteratorInternal<T>* it) : it_(it) {}
00028
00035 CkSequenceIterator(typename std::list<CkSequenceInternal<T> *>::iterator
00036 subsequence_list_it,
00037 typename std::list<CkSequenceInternal<T> *>::iterator
00038 subsequence_list_it_end) {
00039 subsequence_list_it_ = subsequence_list_it;
00040 subsequence_list_it_end_ = subsequence_list_it_end;
00041 if (subsequence_list_it_ == subsequence_list_it_end_) {
00042 it_ = NULL;
00043 it_end_ = NULL;
00044 } else {
00045 it_ = (*subsequence_list_it_)->begin();
00046 it_end_ = (*subsequence_list_it_)->end();
00047 }
00048 }
00049
00050 ~CkSequenceIterator() {
00051
00052 }
00053
00054 T operator*() {
00055 return **it_;
00056 }
00057
00058 void operator++() {
00059 ++(*it_);
00060 if (*it_ == *it_end_) {
00061 if (++subsequence_list_it_ == subsequence_list_it_end_) {
00062 it_ = NULL;
00063 it_end_ = NULL;
00064 } else {
00065 it_ = (*subsequence_list_it_)->begin();
00066 it_end_ = (*subsequence_list_it_)->end();
00067 }
00068 }
00069 }
00070
00071 void operator++(int) {
00072 ++(*it_);
00073 if (*it_ == *it_end_) {
00074 if (++subsequence_list_it_ == subsequence_list_it_end_) {
00075 it_ = NULL;
00076 it_end_ = NULL;
00077 } else {
00078 it_ = (*subsequence_list_it_)->begin();
00079 it_end_ = (*subsequence_list_it_)->end();
00080 }
00081 }
00082
00083 }
00084
00085 bool operator==(const CkSequenceIterator& rhs) const {
00086 if (it_ == NULL || rhs.it_ == NULL) {
00087 return (this->it_ == rhs.it_);
00088 }
00089 return (*(this->it_) == *(rhs.it_));
00090 }
00091
00092 bool operator!=(const CkSequenceIterator& rhs) const {
00093 if (it_ == NULL || rhs.it_ == NULL) {
00094 return (this->it_ != rhs.it_);
00095 }
00096 return (*(this->it_) != *(rhs.it_));
00097 }
00098
00099 private:
00100 CkSequenceIteratorInternal<T>* it_;
00101 CkSequenceIteratorInternal<T>* it_end_;
00102 typename std::list<CkSequenceInternal<T>* >::iterator subsequence_list_it_;
00103 typename std::list<CkSequenceInternal<T>* >::iterator subsequence_list_it_end_;
00104 int index_;
00105 };
00106
00119 template <typename T>
00120 class CkSequence {
00121
00122 public:
00123
00124
00128 CkSequence() : bit_vector_(NULL), compact_(false) {}
00129
00136 template <typename GenericIterator>
00137 CkSequence(const GenericIterator begin, const GenericIterator end) {
00138 compact_ = false;
00139 min_ = 0;
00140 max_ = 0;
00141 num_elements_ = 0;
00142 if (begin == end) {
00143 return;
00144 }
00145
00146
00147 min_ = *begin;
00148 for (GenericIterator it = begin; it != end; ++it) {
00149 num_elements_++;
00150 if (max_ < *it) {
00151 max_ = *it;
00152 }
00153 if (*it < min_) {
00154 min_ = *it;
00155 }
00156 }
00157
00158
00159 bit_vector_ = (char *) malloc ((max_+1)/CHAR_SIZE + 1);
00160 memset(bit_vector_, 0, (max_+1)/CHAR_SIZE + 1);
00161
00162 for (GenericIterator it = begin; it != end; ++it) {
00163 Set(bit_vector_, (*it));
00164 }
00165 }
00166
00167 template <typename GenericIterator>
00168 void Insert(const GenericIterator begin, const GenericIterator end) {
00169 compact_ = false;
00170 min_ = 0;
00171 max_ = 0;
00172 num_elements_ = 0;
00173 if (begin == end) {
00174 return;
00175 }
00176
00177
00178 min_ = *begin;
00179 for (GenericIterator it = begin; it != end; ++it) {
00180 num_elements_++;
00181 if (max_ < *it) {
00182 max_ = *it;
00183 }
00184 if (*it < min_) {
00185 min_ = *it;
00186 }
00187 }
00188
00189
00190 bit_vector_ = (char *) malloc ((max_+1)/CHAR_SIZE + 1);
00191 memset(bit_vector_, 0, (max_+1)/CHAR_SIZE + 1);
00192
00193 for (GenericIterator it = begin; it != end; ++it) {
00194 Set(bit_vector_, (*it));
00195 }
00196 }
00197
00198
00199 ~CkSequence() {
00200 if (bit_vector_ != NULL) {
00201 delete bit_vector_;
00202 bit_vector_ = NULL;
00203 }
00204 for (int i = 0; i < subsequence_list_.size(); i++) {
00205
00206 }
00207 }
00208
00214 void Insert(const T& element);
00215
00216 void InsertIntoStrided(typename std::list<CkSequenceInternal<T> *>::iterator
00217 iter, const T& element);
00218
00224 void Remove(const T& element);
00225
00230 void DoneInserting();
00231
00241 int num_elements() const;
00242
00243 int mem_size() const;
00244
00245 typedef CkSequenceIterator<T> iterator;
00246
00254 iterator begin() {
00255 if (compact_) {
00256 return iterator(subsequence_list_.begin(), subsequence_list_.end());
00257 } else {
00258 return iterator(new BitVectorIterator<T>(bit_vector_, 0, min_, max_));
00259 }
00260 }
00261
00269 iterator end() {
00270 if (compact_) {
00271 return iterator(NULL);
00272 } else {
00273 return iterator(new BitVectorIterator<T>(bit_vector_, 0, max_+1, max_));
00274 }
00275 }
00276
00277 void pup(PUP::er &p) {
00278 p|min_;
00279 p|max_;
00280 p|num_elements_;
00281 p|compact_;
00282 if (p.isUnpacking() && !compact_) {
00283 bit_vector_ = (char *) malloc((max_+1)/CHAR_SIZE + 1);
00284 }
00285 if (!compact_) {
00286 PUParray(p, bit_vector_, (max_+1)/CHAR_SIZE + 1);
00287 }
00288 if (!p.isUnpacking()) {
00289 int size = subsequence_list_.size();
00290 p|size;
00291 int type;
00292 for (typename std::list<CkSequenceInternal<T>*>::iterator it =
00293 subsequence_list_.begin(); it != subsequence_list_.end(); it++) {
00294 type = (*it)->type();
00295 p|type;
00296 p|(**it);
00297 }
00298 } else {
00299 int size;
00300 int type;
00301 p|size;
00302
00303 for (int i=0; i < size; i++) {
00304 p|type;
00305 CkSequenceInternal<T>* seq_internal;
00306 if (type == STRIDE) {
00307 seq_internal = new StridedSequence<T>();
00308 } else {
00309 seq_internal = new RandomSequence<T>();
00310 }
00311 p|(*seq_internal);
00312 subsequence_list_.push_back(seq_internal);
00313 }
00314 }
00315 }
00316
00317 private:
00318
00319 void Compact();
00320
00321 T min_;
00322 T max_;
00323 T num_elements_;
00324
00325
00326 bool compact_;
00327 char* bit_vector_;
00328
00329
00330
00331 std::list<CkSequenceInternal<T>*> subsequence_list_;
00332 };
00333
00334
00335 template <class T>
00336 inline void CkSequence<T>::Insert(const T& element) {
00337 if (compact_) {
00338 CkAbort("Cannot insert after DoneInserting() is called\n");
00339 }
00340 if ((element/CHAR_SIZE) > ((max_+1)/CHAR_SIZE)) {
00341 bit_vector_ = (char *) realloc(bit_vector_, (element+1)/CHAR_SIZE + 1);
00342 int diff = ((element + 1) / CHAR_SIZE) - ((max_+1) / CHAR_SIZE);
00343 memset(&bit_vector_[((max_+1)/CHAR_SIZE) + 1], 0, diff);
00344 }
00345
00346 Set(bit_vector_, element);
00347
00348 if (element > max_) {
00349 max_ = element;
00350 } else if (element < min_) {
00351 min_ = element;
00352 }
00353 }
00354
00355 template <class T>
00356 inline void CkSequence<T>::Remove(const T& element) {
00357 if (compact_) {
00358 CkAbort("Cannot insert after DoneInserting() is called\n");
00359 }
00360 Reset(bit_vector_, element);
00361 }
00362
00363 template <class T>
00364 inline int CkSequence<T>::num_elements() const {
00365 if (subsequence_list_.size() <= 0) {
00366 return 0;
00367 }
00368
00369 }
00370
00371 template <class T>
00372 inline int CkSequence<T>::mem_size() const {
00373 int sum = 0;
00374 for (int i = 0; i < subsequence_list_.size(); ++i) {
00375
00376 }
00377 return sum;
00378 }
00379
00380 template <typename T>
00381 inline void CkSequence<T>::Compact() {
00382 compact_ = true;
00383 std::cout << "Compacting!!!\n";
00384 int seq_begin_ele = min_;
00385 int prev_ele = min_;
00386 int prev_prev_ele = min_;
00387 int prev_prev_prev_ele = min_;
00388
00389 int end_stride = min_;
00390
00391 int start_random = min_;
00392 int end_random = min_;
00393
00394 int stride = -1;
00395 std::cout << "Current size " << ((max_+1)/CHAR_SIZE + 1) << std::endl;
00396
00397
00398 int tmp_stride = 0;
00399 bool is_strided = false;
00400
00401 for (T i = min_+ 1; i <= max_; i++) {
00402 if (IsSet(bit_vector_,i)) {
00403 tmp_stride = i - prev_ele;
00404
00405 if (tmp_stride == stride) {
00406
00407 if (!is_strided && seq_begin_ele != prev_prev_ele) {
00408 std::cout << "Create random " << seq_begin_ele << " end " << prev_prev_prev_ele<< std::endl;
00409 CkSequenceInternal<T>* sequence_internal =
00410 CkSequenceFactory<T>::CreateRandomSequence(bit_vector_,
00411 seq_begin_ele, prev_prev_prev_ele);
00412 subsequence_list_.push_back(sequence_internal);
00413 seq_begin_ele = prev_prev_ele;
00414 }
00415
00416 is_strided = true;
00417 end_stride = i;
00418 } else if (tmp_stride != stride) {
00419
00420 if (is_strided) {
00421 std::cout << "Create stride " << seq_begin_ele<< " stride " << stride
00422 << " end stride " << end_stride << " new seq end " << i << " count " << (end_stride - seq_begin_ele)/stride + 1<< std::endl;
00423
00424 CkSequenceInternal<T>* sequence_internal =
00425 CkSequenceFactory<T>::CreateStridedSequence(seq_begin_ele, stride,
00426 end_stride);
00427 subsequence_list_.push_back(sequence_internal);
00428 seq_begin_ele = i;
00429 prev_prev_prev_ele = i;
00430 prev_prev_ele = i;
00431 tmp_stride = -1;
00432 }
00433
00434 start_random = i;
00435 is_strided = false;
00436 }
00437 prev_prev_prev_ele = prev_prev_ele;
00438 prev_prev_ele = prev_ele;
00439 stride = tmp_stride;
00440 prev_ele = i;
00441 }
00442 }
00443
00444 if (is_strided) {
00445 std::cout << "Create stride " << seq_begin_ele<< " stride " << stride
00446 << " end stride " << end_stride << " count " << (end_stride - seq_begin_ele)/stride + 1<< std::endl;
00447 CkSequenceInternal<T>* sequence_internal =
00448 CkSequenceFactory<T>::CreateStridedSequence(seq_begin_ele, stride, end_stride);
00449 subsequence_list_.push_back(sequence_internal);
00450 } else {
00451 CkSequenceInternal<T>* sequence_internal =
00452 CkSequenceFactory<T>::CreateRandomSequence(bit_vector_, seq_begin_ele,start_random);
00453 subsequence_list_.push_back(sequence_internal);
00454 }
00455 delete bit_vector_;
00456 bit_vector_ = NULL;
00457 }
00458
00459 template <class T>
00460 inline void CkSequence<T>::DoneInserting() {
00461 std::cout << "Done inserting\n";
00462 Compact();
00463 }
00464
00465 #endif // SEQUENCE_H_