Rewrote pinnedRanges.
This commit is contained in:
parent
fe30fbbd74
commit
d2d631ff30
2 changed files with 149 additions and 21 deletions
|
@ -198,18 +198,111 @@ static inline long roundUp(long x, long quant) {
|
||||||
return (((x-1) / quant) + 1) * quant;
|
return (((x-1) / quant) + 1) * quant;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pinnedRanges(const rangeTracker * rt, const range * request, rangeTracker * ret, int delta) {
|
||||||
|
transition key;
|
||||||
|
// we will start looking at the tree at the first transition after key.pos.
|
||||||
|
// DEL OLD COMMENT: the -1 gives us >= instead of > when we pass RB_LUGREAT into rblookup.
|
||||||
|
key.pos = roundDown(request->start, rt->quantization);
|
||||||
|
const transition * t = &key;
|
||||||
|
|
||||||
|
int in_range = 0; // 0 if the last transition marked the end of a range.
|
||||||
|
int have_range = 0; // 1 once we have encountered the first range.
|
||||||
|
range cur;
|
||||||
|
|
||||||
|
range expanded_range;
|
||||||
|
expanded_range.start = roundDown(request->start, rt->quantization);
|
||||||
|
expanded_range.stop = roundUp(request->stop, rt->quantization);
|
||||||
|
|
||||||
|
while((t = rblookup(RB_LUGREAT, t, rt->ranges))) {
|
||||||
|
assert(t->delta);
|
||||||
|
// printf("%s\n", transitionToString(t));
|
||||||
|
if(t->pos >= expanded_range.stop) {
|
||||||
|
if(in_range) {
|
||||||
|
assert(t->pins);
|
||||||
|
assert(have_range);
|
||||||
|
cur.stop = expanded_range.stop;
|
||||||
|
assert(cur.stop != cur.start);
|
||||||
|
in_range = 0;
|
||||||
|
} else {
|
||||||
|
if(!have_range) {
|
||||||
|
// we are at first transition
|
||||||
|
if(t->pins) {
|
||||||
|
cur = expanded_range;
|
||||||
|
have_range = 1;
|
||||||
|
} else {
|
||||||
|
// no ranges are pinned.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Pretend we hit the end of the tree.
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
if(in_range) {
|
||||||
|
assert(have_range);
|
||||||
|
assert(t->pins);
|
||||||
|
if(!(t->pins + t->delta)) {
|
||||||
|
cur.stop = roundUp(t->pos, rt->quantization);
|
||||||
|
assert(cur.stop != cur.start);
|
||||||
|
in_range = 0;
|
||||||
|
} else {
|
||||||
|
assert(in_range);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// not in range.
|
||||||
|
if(!have_range) {
|
||||||
|
// we are at first transition
|
||||||
|
if(t->pins) {
|
||||||
|
cur.start = expanded_range.start;
|
||||||
|
in_range = t->pins + t->delta;
|
||||||
|
if(! in_range) {
|
||||||
|
cur.stop = roundUp(t->pos, rt->quantization);
|
||||||
|
assert(cur.stop != cur.start);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cur.start = roundDown(t->pos, rt->quantization);
|
||||||
|
in_range = 1;
|
||||||
|
assert(t->pins + t->delta);
|
||||||
|
}
|
||||||
|
have_range = 1;
|
||||||
|
} else {
|
||||||
|
assert(! t->pins);
|
||||||
|
assert(t->pins + t->delta);
|
||||||
|
// do we need to merge this transition with the range, or output the old range?
|
||||||
|
if(cur.stop >= roundDown(t->pos, rt->quantization)) {
|
||||||
|
// do nothing; start position doesn't change.
|
||||||
|
} else {
|
||||||
|
// output old range, reset start position
|
||||||
|
rangeTrackerDelta(ret, &cur, delta);
|
||||||
|
cur.start = roundDown(t->pos, rt->quantization);
|
||||||
|
}
|
||||||
|
in_range = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(!in_range);
|
||||||
|
if(have_range) {
|
||||||
|
rangeTrackerDelta(ret, &cur, delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//#define DBGPINS(...) printf(__VA_ARGS__)
|
||||||
|
#define DBGPINS(...)
|
||||||
/**
|
/**
|
||||||
@return a set of ranges that are pinned, and that overlap the request range.
|
@return a set of ranges that are pinned, and that overlap the request range.
|
||||||
*/
|
*/
|
||||||
static rangeTracker * pinnedRanges(const rangeTracker * rt, const range * request, rangeTracker * ret, int delta) {
|
static rangeTracker * pinnedRangesOLD(const rangeTracker * rt, const range * request, rangeTracker * ret, int delta) {
|
||||||
transition key;
|
transition key;
|
||||||
const transition * t;
|
const transition * t;
|
||||||
|
DBGPINS("Call ");
|
||||||
key.pos = roundDown(request->start, rt->quantization);
|
key.pos = roundDown(request->start, rt->quantization);
|
||||||
|
|
||||||
t = rblookup(RB_LUGTEQ, &key, rt->ranges);
|
t = rblookup(RB_LUGTEQ, &key, rt->ranges);
|
||||||
|
|
||||||
if(!t) {
|
if(!t) {
|
||||||
|
DBGPINS("at End\n");
|
||||||
// No ranges after request->start, so no ranges can overlap.
|
// No ranges after request->start, so no ranges can overlap.
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -224,6 +317,7 @@ static rangeTracker * pinnedRanges(const rangeTracker * rt, const range * reques
|
||||||
long putative_range_stop;
|
long putative_range_stop;
|
||||||
|
|
||||||
if(t) {
|
if(t) {
|
||||||
|
DBGPINS("T %ld", t->pos);
|
||||||
if(roundDown(t->pos, rt->quantization) >= roundUp(request->stop, rt->quantization)) {
|
if(roundDown(t->pos, rt->quantization) >= roundUp(request->stop, rt->quantization)) {
|
||||||
if(t->pins) {
|
if(t->pins) {
|
||||||
// entire range is pinned.
|
// entire range is pinned.
|
||||||
|
@ -234,51 +328,80 @@ static rangeTracker * pinnedRanges(const rangeTracker * rt, const range * reques
|
||||||
assert(tmp_r.start >= roundDown(request->start, rt->quantization) && tmp_r.stop <= roundUp(request->stop, rt->quantization));
|
assert(tmp_r.start >= roundDown(request->start, rt->quantization) && tmp_r.stop <= roundUp(request->stop, rt->quantization));
|
||||||
rangeTrackerDelta(ret, &tmp_r, delta);
|
rangeTrackerDelta(ret, &tmp_r, delta);
|
||||||
|
|
||||||
// printf("0 %s\n", rangeToString(&tmp_r));
|
// DBGPINS("0 %s\n", rangeToString(&tmp_r));
|
||||||
} else {
|
} else {
|
||||||
// none of the range is pinned.
|
// none of the range is pinned.
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
} else if(t->pins) {
|
||||||
if(t->pins) {
|
DBGPINS("startPin ");
|
||||||
// The beginning of request is a range.
|
// The beginning of request is a range.
|
||||||
range_start = roundDown(request->start, rt->quantization);
|
range_start = roundDown(request->start, rt->quantization);
|
||||||
if(0 == t->pins + t->delta) {
|
if(0 == t->pins + t->delta) {
|
||||||
|
DBGPINS("!in ");
|
||||||
in_range = 0;
|
in_range = 0;
|
||||||
// even though we're not in range, we need to see if the next
|
// even though we're not in range, we need to see if the next
|
||||||
// transition starts a range on the same page before returning a
|
// transition starts a range on the same page before returning a
|
||||||
// new range.
|
// new range.
|
||||||
putative_range_stop = roundUp(t->pos, rt->quantization);
|
putative_range_stop = roundUp(t->pos, rt->quantization);
|
||||||
} else {
|
} else {
|
||||||
|
DBGPINS("in ");
|
||||||
in_range = 1;
|
in_range = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
DBGPINS("start!Pin ");
|
||||||
// The beginning of the request is not a range.
|
// The beginning of the request is not a range.
|
||||||
range_start = roundDown(t->pos, rt->quantization);
|
range_start = roundDown(t->pos, rt->quantization);
|
||||||
|
DBGPINS("A ");
|
||||||
in_range = 1;
|
in_range = 1;
|
||||||
assert(t->delta);
|
assert(t->delta);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
DBGPINS("!T ");
|
||||||
}
|
}
|
||||||
while((t = rblookup(RB_LUGREAT, t, rt->ranges))) {
|
while((t = rblookup(RB_LUGREAT, t, rt->ranges))) {
|
||||||
|
DBGPINS("W %ld", t->pos);
|
||||||
assert(t->delta);
|
assert(t->delta);
|
||||||
|
|
||||||
if(roundUp(t->pos, rt->quantization) >= roundUp(request->stop, rt->quantization)) {
|
if(roundUp(t->pos, rt->quantization) >= roundUp(request->stop, rt->quantization)) {
|
||||||
|
DBGPINS("Break ");
|
||||||
if(in_range) {
|
if(in_range) {
|
||||||
|
assert(t->pins);
|
||||||
// if we're in range, part of the last page must be pinned.
|
// if we're in range, part of the last page must be pinned.
|
||||||
in_range = 0;
|
in_range = 0;
|
||||||
putative_range_stop = roundUp(request->stop, rt->quantization);
|
putative_range_stop = roundUp(request->stop, rt->quantization);
|
||||||
} else {
|
} else {
|
||||||
|
// deal with range that ended before this transition.
|
||||||
|
range tmp_r;
|
||||||
|
assert(t->pins == 0);
|
||||||
|
|
||||||
|
if(roundUp(putative_range_stop, rt->quantization) < roundDown(t->pos, rt->quantization)) {
|
||||||
|
|
||||||
|
// There is a gap between the last range and this range.
|
||||||
|
tmp_r.start = range_start;
|
||||||
|
tmp_r.stop = putative_range_stop;
|
||||||
|
if(tmp_r.start != tmp_r.stop) {
|
||||||
|
rangeTrackerDelta(ret, &tmp_r, delta);
|
||||||
|
}
|
||||||
// is this transition in the last page? If so, part of the last page must be pinned.
|
// is this transition in the last page? If so, part of the last page must be pinned.
|
||||||
if(t->pos < roundUp(request->stop, rt->quantization)) {
|
if(t->pos < roundUp(request->stop, rt->quantization)) {
|
||||||
// in_range == 0
|
// in_range == 0
|
||||||
assert(t->pins == 0);
|
|
||||||
range_start = roundDown(t->pos, rt->quantization);
|
range_start = roundDown(t->pos, rt->quantization);
|
||||||
putative_range_stop = roundUp(request->stop, rt->quantization);
|
putative_range_stop = roundUp(request->stop, rt->quantization);
|
||||||
|
} else {
|
||||||
|
in_range = 2;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// There is no gap between the last range and this range.
|
||||||
|
putative_range_stop = roundUp(request->stop, rt->quantization);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(t->pins) {
|
if(t->pins) {
|
||||||
|
DBGPINS("P ");
|
||||||
assert(in_range);
|
assert(in_range);
|
||||||
|
|
||||||
if(!(t->pins + t->delta)) {
|
if(!(t->pins + t->delta)) {
|
||||||
|
@ -287,6 +410,7 @@ static rangeTracker * pinnedRanges(const rangeTracker * rt, const range * reques
|
||||||
}
|
}
|
||||||
|
|
||||||
} else { // ! t->pins
|
} else { // ! t->pins
|
||||||
|
DBGPINS("!P ");
|
||||||
assert(!in_range);
|
assert(!in_range);
|
||||||
|
|
||||||
if(putative_range_stop < roundDown(t->pos, rt->quantization)) {
|
if(putative_range_stop < roundDown(t->pos, rt->quantization)) {
|
||||||
|
@ -297,7 +421,7 @@ static rangeTracker * pinnedRanges(const rangeTracker * rt, const range * reques
|
||||||
if(tmp_r.start != tmp_r.stop) {
|
if(tmp_r.start != tmp_r.stop) {
|
||||||
assert(tmp_r.start >= roundDown(request->start, rt->quantization) && tmp_r.stop <= roundUp(request->stop, rt->quantization));
|
assert(tmp_r.start >= roundDown(request->start, rt->quantization) && tmp_r.stop <= roundUp(request->stop, rt->quantization));
|
||||||
rangeTrackerDelta(ret, &tmp_r, delta);
|
rangeTrackerDelta(ret, &tmp_r, delta);
|
||||||
// printf("1 %s\n", rangeToString(&tmp_r));
|
// DBGPINS("1 %s\n", rangeToString(&tmp_r));
|
||||||
}
|
}
|
||||||
range_start = roundDown(t->pos, rt->quantization);
|
range_start = roundDown(t->pos, rt->quantization);
|
||||||
} else {
|
} else {
|
||||||
|
@ -306,16 +430,20 @@ static rangeTracker * pinnedRanges(const rangeTracker * rt, const range * reques
|
||||||
in_range = 1;
|
in_range = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(!in_range);
|
assert(in_range==0 || in_range ==2);
|
||||||
|
if(!in_range) {
|
||||||
range tmp_r;
|
range tmp_r;
|
||||||
tmp_r.start = range_start;
|
tmp_r.start = range_start;
|
||||||
tmp_r.stop = putative_range_stop;
|
tmp_r.stop = putative_range_stop;
|
||||||
if(tmp_r.start != tmp_r.stop) {
|
if(tmp_r.start != tmp_r.stop) {
|
||||||
|
DBGPINS("2 ");
|
||||||
assert(tmp_r.start >= roundDown(request->start, rt->quantization) && tmp_r.stop <= roundUp(request->stop, rt->quantization));
|
assert(tmp_r.start >= roundDown(request->start, rt->quantization) && tmp_r.stop <= roundUp(request->stop, rt->quantization));
|
||||||
rangeTrackerDelta(ret, &tmp_r, delta);
|
rangeTrackerDelta(ret, &tmp_r, delta);
|
||||||
// printf("2 %s\n", rangeToString(&tmp_r));
|
// DBGPINS("2 %s\n", rangeToString(&tmp_r));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
DBGPINS("\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -276,7 +276,7 @@ START_TEST (rangeTracker_randomTest) {
|
||||||
|
|
||||||
gettimeofday(&time,0);
|
gettimeofday(&time,0);
|
||||||
|
|
||||||
long seed = time.tv_usec + time.tv_sec * 1000000;// 1170727703805787; //
|
long seed = time.tv_usec + time.tv_sec * 1000000; //1170807889195512; //time.tv_usec + time.tv_sec * 1000000; //1170729550013502; //time.tv_usec + time.tv_sec * 1000000;// 1170727703805787; // 1170810757441165; 1170811024737237; //
|
||||||
printf("\nSeed = %ld\n", seed);
|
printf("\nSeed = %ld\n", seed);
|
||||||
srandom(seed);
|
srandom(seed);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue