UNPKG

riffle

Version:

Forward and reverse iteration of a Strata b-tree.

119 lines (107 loc) 3.58 kB
var cadence = require('cadence') function Forward (cursor, inclusive) { this._cursor = cursor this.last = this._cursor.page.right.address == null this._inclusive = inclusive this._index = null } Forward.prototype.get = function () { return this._items[this._index++] } Forward.prototype.next = cadence(function (async) { if (this._index === null) { var index = this._cursor.index this._index = index < 0 ? ~index : this._inclusive ? index : index + 1 this._items = this._cursor.page.items return [ this._index < this._items.length ] } async(function () { this._cursor.next(async()) }, function (more) { if (!more) { return [ false ] } this.last = this._cursor.page.right.address === null this._items = this._cursor.page.items this._index = this._cursor.page.ghosts return [ true ] }) }) Forward.prototype.unlock = function (callback) { this._cursor.unlock(callback) } exports.forward = cadence(function (async, strata, key, inclusive) { var condition = key == null ? strata.left : strata.key(key) inclusive = inclusive == null ? true : inclusive async(function () { strata.iterator(condition, async()) }, function (cursor) { return new Forward(cursor, inclusive) }) }) function Reverse (strata, cursor, inclusive) { var index = cursor.index this._strata = strata this._cursor = cursor this._index = null this._inclusive = inclusive this.last = false } Reverse.prototype.get = function () { if (this._index < this._ghosts) { return null } return this._items[this._index--] } Reverse.prototype.next = cadence(function (async) { if (this._index !== null && this._cursor.page.address == 1) { return [ false ] } if (this._index === null) { var index = this._cursor.index index = index < 0 ? ~index - 1 : this._inclusive ? index : index - 1 if (index < this._cursor.page.ghosts && this._cursor.page.address === 1) { this._index = -1 return [ false ] } this._items = this._cursor.page.items this._index = index return [ true ] } var address = this._cursor.page.address, key async(function () { key = this._cursor.page.items[0].key async(function () { this._cursor.unlock(async()) }, function () { exports._racer(key, async()) }, function () { this._strata.iterator(this._strata.leftOf(key), async()) }) }, function (cursor) { this.last = cursor.page.address === 1 this._cursor = cursor this._items = cursor.page.items this._ghosts = cursor.page.ghosts if (this._cursor.page.right.address === address) { this._index = this._cursor.page.items.length - 1 } else { var index = this._cursor.index this._index = (index < 0 ? ~index : index) - 1 } return [ true ] }) }) Reverse.prototype.unlock = function (callback) { this._cursor.unlock(callback) } exports.reverse = cadence(function (async, strata, key, inclusive) { inclusive = inclusive == null ? true : inclusive var condition = key == null ? strata.right : strata.key(key) async(function () { strata.iterator(condition, async()) }, function (cursor) { return new Reverse(strata, cursor, inclusive) }) }) exports._racer = function (key, callback) { callback() }