fix rbt traversal.

This commit is contained in:
Christopher Jeffrey 2016-07-03 09:50:42 -07:00
parent 0d0b6c562e
commit 1e8c3a4487
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -479,24 +479,13 @@ RBT.prototype.snapshot = function snapshot() {
*/
RBT.prototype.traverse = function traverse(test) {
var current = this.root;
var stack = [];
var current = this.min(this.root);
var items = [];
for (;;) {
if (!current.isNull()) {
if (test(current))
items.push(current.copy());
stack.push(current);
current = current.left;
continue;
}
if (stack.length === 0)
break;
current = stack.pop();
current = current.right;
while (!current.isNull()) {
if (test(current))
items.push(current.copy());
current = this.successor(current);
}
return items;
@ -519,8 +508,8 @@ RBT.prototype.dump = function dump() {
*/
RBT.prototype.range = function range(gte, lte) {
var current = this.root;
var stack = [];
var root = this.root;
var current = SENTINEL;
var items = [];
var cmp;
@ -530,63 +519,44 @@ RBT.prototype.range = function range(gte, lte) {
if (typeof lte === 'string')
lte = new Buffer(lte, 'ascii');
for (;;) {
if (!current.isNull()) {
cmp = this.rangeCompare(current.key, gte, lte);
if (gte) {
// Find the node closest to our gte key.
while (!root.isNull()) {
cmp = this.compare(gte, root.key);
if (cmp === 0) {
items.push(current.copy());
stack.push(current);
current = root;
break;
}
if (cmp <= 0)
current = current.left;
else
current = current.right;
continue;
if (cmp < 0) {
current = root;
root = root.left;
} else {
root = root.right;
}
}
} else {
// Descend into the left subtree.
current = this.min(root);
}
// Walk the tree in order.
while (!current.isNull()) {
if (lte) {
// Stop once we hit a key above our lte key.
cmp = this.compare(current.key, lte);
if (cmp > 0)
break;
}
if (stack.length === 0)
break;
current = stack.pop();
current = current.right;
items.push(current.copy());
current = this.successor(current);
}
return items;
};
/**
* Comparator for {@link RBT#range}.
* @param {Buffer} key
* @param {Buffer} gteKey
* @param {Buffer} lteKey
* @returns {Number}
*/
RBT.prototype.rangeCompare = function rangeCompare(key, gteKey, lteKey) {
var gte, lte;
if (gteKey)
gte = this.compare(key, gteKey);
else
gte = 0;
if (lteKey)
lte = this.compare(key, lteKey);
else
lte = 0;
if (gte >= 0 && lte <= 0)
return 0;
if (lte > 0)
return -1;
if (gte < 0)
return 1;
assert(false);
};
/**
* Open the database (leveldown method).
* @param {Object?} options