Fixed bugs in gc iterator.
This commit is contained in:
parent
3179b46ce3
commit
651299716e
2 changed files with 112 additions and 36 deletions
|
@ -46,8 +46,49 @@ inline const byte * toByteArray(stlSetIterator<STLITER,ROW> * const t);
|
|||
template <class ROW, class ITER>
|
||||
class gcIterator {
|
||||
public:
|
||||
explicit gcIterator(ITER * i, ITER * iend, epoch_t beginning_of_time, column_number_t ts_col) : i_(i), newest_(), newTS_(-1), iend_(iend), freeIt(0), beginning_of_time_(beginning_of_time), ts_col_(ts_col) { /*++(*i);*/ if(*i_ != *iend_) { ++(*this);} }
|
||||
explicit gcIterator(gcIterator& t) : i_(new ITER(*(t.i_))), newest_(t.newest_), newTS_(t.newTS_), iend_(t.iend_), freeIt(1), beginning_of_time_(t.beginning_of_time_), ts_col_(t.ts_col_) { }
|
||||
explicit gcIterator(ITER * i, ITER * iend, epoch_t beginning_of_time, column_number_t ts_col)
|
||||
: i_(i),
|
||||
newest_(),
|
||||
current_(),
|
||||
have_newest_(0),
|
||||
have_current_(0),
|
||||
went_back_(0),
|
||||
at_end_(0),
|
||||
//newTS_(-1),
|
||||
iend_(iend),
|
||||
freeIt(0),
|
||||
beginning_of_time_(beginning_of_time),
|
||||
ts_col_(ts_col) {
|
||||
get_next();
|
||||
if(have_newest_) {
|
||||
have_current_ = true; // needed by ++.
|
||||
++(*this);
|
||||
// assert(have_current_); // Should pass; commented out for perf.
|
||||
}
|
||||
}
|
||||
explicit gcIterator()
|
||||
: i_(0),
|
||||
newest_(),
|
||||
current_(),
|
||||
have_newest_(false),
|
||||
have_current_(false),
|
||||
at_end_(true),
|
||||
freeIt(0),
|
||||
beginning_of_time_(0),
|
||||
ts_col_(0) {}
|
||||
|
||||
explicit gcIterator(gcIterator& t)
|
||||
: i_(new ITER(*(t.i_))),
|
||||
newest_(t.newest_),
|
||||
current_(t.current_),
|
||||
have_newest_(t.have_newest_),
|
||||
have_current_(t.have_current_),
|
||||
went_back_(t.went_back_),
|
||||
at_end_(t.at_end_),
|
||||
iend_(t.iend_),
|
||||
freeIt(1),
|
||||
beginning_of_time_(t.beginning_of_time_),
|
||||
ts_col_(t.ts_col_) { }
|
||||
|
||||
~gcIterator() {
|
||||
if (freeIt) {
|
||||
|
@ -55,41 +96,72 @@ class gcIterator {
|
|||
}
|
||||
}
|
||||
ROW & operator*() {
|
||||
return newest_;
|
||||
// Both should pass, comment out for perf
|
||||
//assert(!went_back_);
|
||||
//assert(have_current_);
|
||||
return current_;
|
||||
}
|
||||
bool get_next() {
|
||||
// assert(!went_back_);
|
||||
// assert(!at_end_);
|
||||
while(!have_newest_) {
|
||||
have_newest_ = true;
|
||||
newest_ = **i_;
|
||||
if(ts_col_ != INVALID_COL) {
|
||||
epoch_t newest_time = *(epoch_t*)newest_.get(ts_col_);
|
||||
while(1) {
|
||||
++(*i_);
|
||||
if(*i_ == *iend_) { at_end_=true; return true; }
|
||||
if(!myTupCmp(newest_,**i_)) { break; }
|
||||
if(newest_time >= beginning_of_time_) { break; }
|
||||
|
||||
epoch_t this_time = *(epoch_t*)(**i_).get(ts_col_);
|
||||
if(this_time > newest_time) {
|
||||
newest_= **i_;
|
||||
newest_time = this_time;
|
||||
}
|
||||
}
|
||||
// is it a tombstone we can forget?
|
||||
if (newest_time & 0x1 && newest_time < beginning_of_time_) {
|
||||
have_newest_ = 0;
|
||||
}
|
||||
} else {
|
||||
++(*i_);
|
||||
if(*i_ == *iend_) { at_end_=true; return false; }
|
||||
}
|
||||
}
|
||||
return true; // newest_;
|
||||
}
|
||||
inline bool operator==(const gcIterator &a) const {
|
||||
return (*i_) == (*a.i_);
|
||||
// return (*i_) == (*a.i_);
|
||||
if((!have_current_) && at_end_) { return a.at_end_; }
|
||||
return false;
|
||||
}
|
||||
inline bool operator!=(const gcIterator &a) const {
|
||||
return (*i_) != (*a.i_);
|
||||
// return (*i_) != (*a.i_);
|
||||
return !(*this == a);
|
||||
}
|
||||
inline void operator++() {
|
||||
do {
|
||||
if(*i_ == *iend_) { return; }
|
||||
assert(*i_ != *iend_);
|
||||
newest_ = **i_;
|
||||
newTS_ = *(epoch_t*)newest_.get(ts_col_);
|
||||
++(*i_);
|
||||
while(ts_col_ != INVALID_COL && (*i_ != *iend_) && myTupCmp(newest_,**i_)) {
|
||||
const ROW& r = (**i_);
|
||||
epoch_t ts = *(epoch_t*)r.get(ts_col_); //r.column_count()-1);
|
||||
|
||||
if(ts >= newTS_) {
|
||||
// if(*(int*)((**i_).get((**i_).column_count()-1)) >= newTS_) {
|
||||
// newTS_ = *(int*)(**i_).get((**i_).column_count()-1);
|
||||
newTS_ = ts;
|
||||
|
||||
newest_ = r;//**i_;
|
||||
if(went_back_) {
|
||||
went_back_ = false;
|
||||
} else {
|
||||
// assert(have_current_);
|
||||
if(have_newest_) {
|
||||
current_ = newest_;
|
||||
have_current_ = have_newest_;
|
||||
have_newest_ = false;
|
||||
if(!at_end_) {
|
||||
get_next();
|
||||
}
|
||||
++(*i_);
|
||||
} else {
|
||||
// assert(at_end_);
|
||||
have_current_ = false;
|
||||
}
|
||||
/* if (((newTS_ & 0x1) && (newTS_ < beginning_of_time_) && (ts_col_ != INVALID_COL))) {
|
||||
printf("gc'ed tombstone!!!\n");
|
||||
} */
|
||||
} while ((newTS_ & 0x1) && (newTS_ < beginning_of_time_) && (ts_col_ != INVALID_COL));
|
||||
}
|
||||
}
|
||||
inline void operator--() {
|
||||
(*i_)--;
|
||||
// assert(!went_back_);
|
||||
went_back_ = true;
|
||||
}
|
||||
/* inline gcIterator* end() {
|
||||
return new gcIterator(i_->end());
|
||||
|
@ -124,12 +196,17 @@ class gcIterator {
|
|||
return 1;
|
||||
}
|
||||
|
||||
explicit gcIterator() { abort(); }
|
||||
//explicit gcIterator() { abort(); }
|
||||
void operator=(gcIterator & t) { abort(); }
|
||||
int operator-(gcIterator & t) { abort(); }
|
||||
ITER * i_;
|
||||
ROW newest_;
|
||||
epoch_t newTS_;
|
||||
ROW current_;
|
||||
bool have_newest_;
|
||||
bool have_current_;
|
||||
bool went_back_;
|
||||
bool at_end_;
|
||||
// epoch_t newTS_;
|
||||
ITER * iend_;
|
||||
bool freeIt;
|
||||
epoch_t beginning_of_time_;
|
||||
|
@ -247,7 +324,7 @@ class treeIterator {
|
|||
currentPage_ = (PAGELAYOUT*)p_->impl;
|
||||
|
||||
readTuple = currentPage_->recordRead(-1,slot_, &scratch_);
|
||||
assert(readTuple);
|
||||
// assert(readTuple);
|
||||
} else {
|
||||
// past end of iterator! "end" should contain the pageid of the
|
||||
// last leaf, and 1+ numslots on that page.
|
||||
|
@ -370,7 +447,7 @@ class mergeIterator {
|
|||
const ROW& operator* () {
|
||||
if(curr_ == A) { return *a_; }
|
||||
if(curr_ == B || curr_ == BOTH) { return *b_; }
|
||||
// abort();
|
||||
abort();
|
||||
curr_ = calcCurr(A);
|
||||
if(curr_ == A) { return *a_; }
|
||||
if(curr_ == B || curr_ == BOTH) { return *b_; }
|
||||
|
|
|
@ -222,18 +222,17 @@ namespace rose {
|
|||
<PAGELAYOUT,versioningIterator<mergeIterator<ITERA,ITERB,typename PAGELAYOUT::FMT::TUP>, typename PAGELAYOUT::FMT::TUP> >
|
||||
(xid, &vBegin, &vEnd,tree->r_,a->pageAlloc,a->pageAllocState,&insertedTuples); */
|
||||
|
||||
/* mergedPages = compressData
|
||||
/*mergedPages = compressData
|
||||
<PAGELAYOUT,mergeIterator<ITERA,ITERB,typename PAGELAYOUT::FMT::TUP> >
|
||||
(xid, &mBegin, &mEnd,tree->r_,a->pageAlloc,a->pageAllocState,&insertedTuples); */
|
||||
|
||||
gcIterator<typename PAGELAYOUT::FMT::TUP,mergeIterator<ITERA,ITERB,typename PAGELAYOUT::FMT::TUP> > gcBegin(&mBegin, &mEnd, current_timestamp, a->ts_col);
|
||||
gcIterator<typename PAGELAYOUT::FMT::TUP,mergeIterator<ITERA,ITERB,typename PAGELAYOUT::FMT::TUP> > gcEnd(&mEnd, &mEnd, current_timestamp, a->ts_col);
|
||||
|
||||
//++gcBegin;
|
||||
gcIterator<typename PAGELAYOUT::FMT::TUP,mergeIterator<ITERA,ITERB,typename PAGELAYOUT::FMT::TUP> > gcEnd;
|
||||
|
||||
mergedPages = compressData
|
||||
<PAGELAYOUT, gcIterator<typename PAGELAYOUT::FMT::TUP,mergeIterator<ITERA,ITERB,typename PAGELAYOUT::FMT::TUP> > >
|
||||
(xid, &gcBegin, &gcEnd,tree->r_,a->pageAlloc,a->pageAllocState,&insertedTuples);
|
||||
(xid, &gcBegin, &gcEnd,tree->r_,a->pageAlloc,a->pageAllocState,&insertedTuples);
|
||||
|
||||
// these tree iterators keep pages pinned! Don't call force until they've been deleted, or we'll deadlock.
|
||||
|
||||
} // free all the stack allocated iterators...
|
||||
|
|
Loading…
Reference in a new issue