UNPKG

forerunnerdb

Version:

A NoSQL document store database for browsers and Node.js.

270 lines (214 loc) 5.25 kB
"use strict"; var Shared = require('./Shared'); var BinaryTree = function (data, compareFunc, hashFunc) { this.init.apply(this, arguments); }; BinaryTree.prototype.init = function (data, index, compareFunc, hashFunc) { this._store = []; if (index !== undefined) { this.index(index); } if (compareFunc !== undefined) { this.compareFunc(compareFunc); } if (hashFunc !== undefined) { this.hashFunc(hashFunc); } if (data !== undefined) { this.data(data); } }; Shared.addModule('BinaryTree', BinaryTree); Shared.mixin(BinaryTree.prototype, 'Mixin.ChainReactor'); Shared.mixin(BinaryTree.prototype, 'Mixin.Sorting'); Shared.mixin(BinaryTree.prototype, 'Mixin.Common'); Shared.synthesize(BinaryTree.prototype, 'compareFunc'); Shared.synthesize(BinaryTree.prototype, 'hashFunc'); Shared.synthesize(BinaryTree.prototype, 'indexDir'); Shared.synthesize(BinaryTree.prototype, 'index', function (index) { if (index !== undefined) { if (!(index instanceof Array)) { // Convert the index object to an array of key val objects index = this.keys(index); } } return this.$super.call(this, index); }); BinaryTree.prototype.keys = function (obj) { var i, keys = []; for (i in obj) { if (obj.hasOwnProperty(i)) { keys.push({ key: i, val: obj[i] }); } } return keys; }; BinaryTree.prototype.data = function (val) { if (val !== undefined) { this._data = val; if (this._hashFunc) { this._hash = this._hashFunc(val); } return this; } return this._data; }; BinaryTree.prototype.push = function (val) { if (val !== undefined) { this._store.push(val); return this; } return false; }; BinaryTree.prototype.pull = function (val) { if (val !== undefined) { var index = this._store.indexOf(val); if (index > -1) { this._store.splice(index, 1); return true; } } return false; }; /** * Default compare method. Can be overridden. * @param a * @param b * @returns {number} * @private */ BinaryTree.prototype._compareFunc = function (a, b) { // Loop the index array var i, indexData, result = 0; for (i = 0; i < this._index.length; i++) { indexData = this._index[i]; if (indexData.val === 1) { result = this.sortAsc(a[indexData.key], b[indexData.key]); } else if (indexData.val === -1) { result = this.sortDesc(a[indexData.key], b[indexData.key]); } if (result !== 0) { return result; } } return result; }; /** * Default hash function. Can be overridden. * @param obj * @private */ BinaryTree.prototype._hashFunc = function (obj) { /*var i, indexData, hash = ''; for (i = 0; i < this._index.length; i++) { indexData = this._index[i]; if (hash) { hash += '_'; } hash += obj[indexData.key]; } return hash;*/ return obj[this._index[0].key]; }; BinaryTree.prototype.insert = function (data) { var result, inserted, failed, i; if (data instanceof Array) { // Insert array of data inserted = []; failed = []; for (i = 0; i < data.length; i++) { if (this.insert(data[i])) { inserted.push(data[i]); } else { failed.push(data[i]); } } return { inserted: inserted, failed: failed }; } if (!this._data) { // Insert into this node (overwrite) as there is no data this.data(data); //this.push(data); return true; } result = this._compareFunc(this._data, data); if (result === 0) { this.push(data); // Less than this node if (this._left) { // Propagate down the left branch this._left.insert(data); } else { // Assign to left branch this._left = new BinaryTree(data, this._index, this._compareFunc, this._hashFunc); } return true; } if (result === -1) { // Greater than this node if (this._right) { // Propagate down the right branch this._right.insert(data); } else { // Assign to right branch this._right = new BinaryTree(data, this._index, this._compareFunc, this._hashFunc); } return true; } if (result === 1) { // Less than this node if (this._left) { // Propagate down the left branch this._left.insert(data); } else { // Assign to left branch this._left = new BinaryTree(data, this._index, this._compareFunc, this._hashFunc); } return true; } return false; }; BinaryTree.prototype.lookup = function (data, resultArr) { var result = this._compareFunc(this._data, data); resultArr = resultArr || []; if (result === 0) { if (this._left) { this._left.lookup(data, resultArr); } resultArr.push(this._data); if (this._right) { this._right.lookup(data, resultArr); } } if (result === -1) { if (this._right) { this._right.lookup(data, resultArr); } } if (result === 1) { if (this._left) { this._left.lookup(data, resultArr); } } return resultArr; }; BinaryTree.prototype.inOrder = function (type, resultArr) { resultArr = resultArr || []; if (this._left) { this._left.inOrder(type, resultArr); } switch (type) { case 'hash': resultArr.push(this._hash); break; case 'key': resultArr.push(this._data); break; default: resultArr.push({ key: this._key, arr: this._store }); break; } if (this._right) { this._right.inOrder(type, resultArr); } return resultArr; }; Shared.finishModule('BinaryTree'); module.exports = BinaryTree;