|
|
@@ -475,9 +475,9 @@ void mkeyQSortSuf( |
|
|
}
|
|
|
|
|
|
struct QSortRange {
|
|
|
- size_t begin;
|
|
|
- size_t end;
|
|
|
- size_t depth;
|
|
|
+ size_t begin;
|
|
|
+ size_t end;
|
|
|
+ size_t depth;
|
|
|
};
|
|
|
|
|
|
template<typename T>
|
|
|
@@ -494,29 +494,29 @@ void mkeyQSortSuf2( |
|
|
size_t upto = OFF_MASK,
|
|
|
std::vector<size_t>* boundaries = NULL)
|
|
|
{
|
|
|
- std::vector<std::vector<QSortRange> > block_list;
|
|
|
+ std::vector<std::vector<QSortRange> > block_list;
|
|
|
while(true) {
|
|
|
- size_t begin = 0, end = 0, depth = 0;
|
|
|
+ size_t begin = 0, end = 0, depth = 0;
|
|
|
if(block_list.size() == 0) {
|
|
|
- begin = _begin;
|
|
|
+ begin = _begin;
|
|
|
end = _end;
|
|
|
depth = _depth;
|
|
|
} else {
|
|
|
- if(block_list.back().size() > 0) {
|
|
|
- begin = block_list.back()[0].begin;
|
|
|
+ if(block_list.back().size() > 0) {
|
|
|
+ begin = block_list.back()[0].begin;
|
|
|
end = block_list.back()[0].end;
|
|
|
depth = block_list.back()[0].depth;
|
|
|
block_list.back().erase((block_list.back()).begin());
|
|
|
} else {
|
|
|
- block_list.resize(block_list.size() - 1);
|
|
|
+ block_list.resize(block_list.size() - 1);
|
|
|
if(block_list.size() == 0) {
|
|
|
- break;
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if(depth == upto) {
|
|
|
- if(boundaries != NULL) {
|
|
|
- (*boundaries).push_back(end);
|
|
|
+ if(boundaries != NULL) {
|
|
|
+ (*boundaries).push_back(end);
|
|
|
}
|
|
|
continue;
|
|
|
}
|
|
|
@@ -525,19 +525,19 @@ void mkeyQSortSuf2( |
|
|
size_t a, b, c, d, /*e,*/ r;
|
|
|
size_t n = end - begin;
|
|
|
if(n <= 1) { // 1-element list already sorted
|
|
|
- if(n == 1 && boundaries != NULL) {
|
|
|
- boundaries->push_back(end);
|
|
|
- }
|
|
|
- continue;
|
|
|
+ if(n == 1 && boundaries != NULL) {
|
|
|
+ boundaries->push_back(end);
|
|
|
+ }
|
|
|
+ continue;
|
|
|
}
|
|
|
CHOOSE_AND_SWAP_PIVOT(SWAP2, CHAR_AT_SUF); // pick pivot, swap it into [begin]
|
|
|
int v = CHAR_AT_SUF(begin, depth); // v <- randomly-selected pivot value
|
|
|
#ifndef NDEBUG
|
|
|
{
|
|
|
- bool stillInBounds = false;
|
|
|
+ bool stillInBounds = false;
|
|
|
for(size_t i = begin; i < end; i++) {
|
|
|
- if(depth < (hlen-s[i])) {
|
|
|
- stillInBounds = true;
|
|
|
+ if(depth < (hlen-s[i])) {
|
|
|
+ stillInBounds = true;
|
|
|
break;
|
|
|
} else { /* already fell off this suffix */ }
|
|
|
}
|
|
|
@@ -547,29 +547,29 @@ void mkeyQSortSuf2( |
|
|
a = b = begin;
|
|
|
c = d = /*e =*/ end-1;
|
|
|
while(true) {
|
|
|
- // Invariant: everything before a is = pivot, everything
|
|
|
- // between a and b is <
|
|
|
- int bc = 0; // shouldn't have to init but gcc on Mac complains
|
|
|
- while(b <= c && v >= (bc = CHAR_AT_SUF(b, depth))) {
|
|
|
- if(v == bc) {
|
|
|
- SWAP2(s, s2, a, b); a++;
|
|
|
- }
|
|
|
- b++;
|
|
|
- }
|
|
|
- // Invariant: everything after d is = pivot, everything
|
|
|
- // between c and d is >
|
|
|
- int cc = 0; // shouldn't have to init but gcc on Mac complains
|
|
|
- while(b <= c && v <= (cc = CHAR_AT_SUF(c, depth))) {
|
|
|
- if(v == cc) {
|
|
|
- SWAP2(s, s2, c, d); d--; /*e--;*/
|
|
|
- }
|
|
|
- //else if(c == e && v == hi) e--;
|
|
|
- c--;
|
|
|
- }
|
|
|
- if(b > c) break;
|
|
|
- SWAP2(s, s2, b, c);
|
|
|
- b++;
|
|
|
- c--;
|
|
|
+ // Invariant: everything before a is = pivot, everything
|
|
|
+ // between a and b is <
|
|
|
+ int bc = 0; // shouldn't have to init but gcc on Mac complains
|
|
|
+ while(b <= c && v >= (bc = CHAR_AT_SUF(b, depth))) {
|
|
|
+ if(v == bc) {
|
|
|
+ SWAP2(s, s2, a, b); a++;
|
|
|
+ }
|
|
|
+ b++;
|
|
|
+ }
|
|
|
+ // Invariant: everything after d is = pivot, everything
|
|
|
+ // between c and d is >
|
|
|
+ int cc = 0; // shouldn't have to init but gcc on Mac complains
|
|
|
+ while(b <= c && v <= (cc = CHAR_AT_SUF(c, depth))) {
|
|
|
+ if(v == cc) {
|
|
|
+ SWAP2(s, s2, c, d); d--; /*e--;*/
|
|
|
+ }
|
|
|
+ //else if(c == e && v == hi) e--;
|
|
|
+ c--;
|
|
|
+ }
|
|
|
+ if(b > c) break;
|
|
|
+ SWAP2(s, s2, b, c);
|
|
|
+ b++;
|
|
|
+ c--;
|
|
|
}
|
|
|
assert(a > begin || c < end-1); // there was at least one =s
|
|
|
assert_lt(/*e*/d-c, n); // they can't all have been > pivot
|
|
|
@@ -583,24 +583,24 @@ void mkeyQSortSuf2( |
|
|
block_list.push_back(tmp1);
|
|
|
block_list.back().clear();
|
|
|
if(r > 0) { // recurse on <'s
|
|
|
- QSortRange tmp2;
|
|
|
+ QSortRange tmp2;
|
|
|
block_list.back().push_back(tmp2);
|
|
|
block_list.back().back().begin = begin;
|
|
|
block_list.back().back().end = begin + r;
|
|
|
block_list.back().back().depth = depth;
|
|
|
}
|
|
|
// Do not recurse on ='s if the pivot was the off-the-end value;
|
|
|
// they're already fully sorted
|
|
|
- if(v != hi) { // recurse on ='s
|
|
|
- QSortRange tmp3;
|
|
|
+ //if(v != hi) { // recurse on ='s
|
|
|
+ QSortRange tmp3;
|
|
|
block_list.back().push_back(tmp3);
|
|
|
block_list.back().back().begin = begin + r;
|
|
|
block_list.back().back().end = begin + r + (a-begin) + (end-d-1);
|
|
|
block_list.back().back().depth = depth + 1;
|
|
|
- }
|
|
|
+ //}
|
|
|
r = d-c; // r <- # of >'s excluding those exhausted
|
|
|
- if(r > 0 && v < hi-1) { // recurse on >'s
|
|
|
- QSortRange tmp4;
|
|
|
+ if(r > 0 /*&& v < hi-1*/) { // recurse on >'s
|
|
|
+ QSortRange tmp4;
|
|
|
block_list.back().push_back(tmp4);
|
|
|
block_list.back().back().begin = end - r;
|
|
|
block_list.back().back().end = end;
|
|
|
|
0 comments on commit
9b177c5