diff --git a/lib/indexes.js b/lib/indexes.js index 27f98ef..de361b8 100644 --- a/lib/indexes.js +++ b/lib/indexes.js @@ -26,12 +26,24 @@ function Index (options) { this.unique = options.unique || false; this.sparse = options.sparse || false; - if (this.sparse) { this.nonindexedDocs = []; } + this.treeOptions = { unique: this.unique, compareKeys: model.compareThings, checkValueEquality: checkValueEquality }; - this.tree = new BinarySearchTree({ unique: this.unique, compareKeys: model.compareThings, checkValueEquality: checkValueEquality }); + this.reset(); // No data in the beginning } +/** + * Reset an index + * @param {Document or Array of documents} newData Optional, data to initialize the index with + */ +Index.prototype.reset = function (newData) { + this.tree = new BinarySearchTree(this.treeOptions); + if (this.sparse) { this.nonindexedDocs = []; } + + if (newData) { this.insert(newData); } +}; + + /** * Insert a new document in the index * If an array is passed, we insert all its elements @@ -87,6 +99,7 @@ Index.prototype.update = function (oldDoc, newDoc) { /** * Get all documents in index that match the query on fieldName * For now only works with field equality (i.e. can't use the index for $lt query for example) + * And doesn't return non indexed docs * @param {Thing} value Value to match the key against * @return {Array od documents} */ diff --git a/test/db.test.js b/test/db.test.js index e5e8c41..de9dae3 100644 --- a/test/db.test.js +++ b/test/db.test.js @@ -1109,7 +1109,7 @@ describe('Database', function () { }); // ==== End of 'Remove' ==== // - describe.only('Using indexes', function () { + describe('Using indexes', function () { describe('ensureIndex', function () { @@ -1187,7 +1187,6 @@ describe('Database', function () { }); }); }); - }); }); diff --git a/test/indexes.test.js b/test/indexes.test.js index 01b100f..4d2d3aa 100644 --- a/test/indexes.test.js +++ b/test/indexes.test.js @@ -245,4 +245,103 @@ describe('Indexes', function () { }); // ==== End of 'Get matching documents' ==== // + + describe('Resetting', function () { + + it('Can reset an index without any new data, the index will be empty afterwards', function () { + var idx = new Index({ fieldName: 'tf' }) + , doc1 = { a: 5, tf: 'hello' } + , doc2 = { a: 8, tf: 'world' } + , doc3 = { a: 2, tf: 'bloup' } + ; + + idx.insert(doc1); + idx.insert(doc2); + idx.insert(doc3); + + idx.tree.getNumberOfKeys().should.equal(3); + idx.getMatching('hello').length.should.equal(1); + idx.getMatching('world').length.should.equal(1); + idx.getMatching('bloup').length.should.equal(1); + + idx.reset(); + idx.tree.getNumberOfKeys().should.equal(0); + idx.getMatching('hello').length.should.equal(0); + idx.getMatching('world').length.should.equal(0); + idx.getMatching('bloup').length.should.equal(0); + }); + + it('Can reset an index and initialize it with one document', function () { + var idx = new Index({ fieldName: 'tf' }) + , doc1 = { a: 5, tf: 'hello' } + , doc2 = { a: 8, tf: 'world' } + , doc3 = { a: 2, tf: 'bloup' } + , newDoc = { a: 555, tf: 'new' } + ; + + idx.insert(doc1); + idx.insert(doc2); + idx.insert(doc3); + + idx.tree.getNumberOfKeys().should.equal(3); + idx.getMatching('hello').length.should.equal(1); + idx.getMatching('world').length.should.equal(1); + idx.getMatching('bloup').length.should.equal(1); + + idx.reset(newDoc); + idx.tree.getNumberOfKeys().should.equal(1); + idx.getMatching('hello').length.should.equal(0); + idx.getMatching('world').length.should.equal(0); + idx.getMatching('bloup').length.should.equal(0); + idx.getMatching('new')[0].a.should.equal(555); + }); + + it('Can reset an index and initialize it with an array of documents', function () { + var idx = new Index({ fieldName: 'tf' }) + , doc1 = { a: 5, tf: 'hello' } + , doc2 = { a: 8, tf: 'world' } + , doc3 = { a: 2, tf: 'bloup' } + , newDocs = [{ a: 555, tf: 'new' }, { a: 666, tf: 'again' }] + ; + + idx.insert(doc1); + idx.insert(doc2); + idx.insert(doc3); + + idx.tree.getNumberOfKeys().should.equal(3); + idx.getMatching('hello').length.should.equal(1); + idx.getMatching('world').length.should.equal(1); + idx.getMatching('bloup').length.should.equal(1); + + idx.reset(newDocs); + idx.tree.getNumberOfKeys().should.equal(2); + idx.getMatching('hello').length.should.equal(0); + idx.getMatching('world').length.should.equal(0); + idx.getMatching('bloup').length.should.equal(0); + idx.getMatching('new')[0].a.should.equal(555); + idx.getMatching('again')[0].a.should.equal(666); + }); + + it('Resetting a sparse index resets the nonindexed docs array', function () { + var idx = new Index({ fieldName: 'tf', sparse: true}) + , doc1 = { a: 5, tf: 'hello' } + , doc2 = { a: 8, no: 'world' } + , doc3 = { a: 2, no: 'bloup' } + ; + + idx.insert(doc1); + idx.insert(doc2); + idx.insert(doc3); + + idx.tree.getNumberOfKeys().should.equal(1); + idx.getMatching('hello').length.should.equal(1); + idx.nonindexedDocs.length.should.equal(2); + + idx.reset(); + idx.tree.getNumberOfKeys().should.equal(0); + idx.nonindexedDocs.length.should.equal(0); + }); + + }); // ==== End of 'Resetting' ==== // + });