Skip to content

Commit

Permalink
feat: added extra basic nested object support (#6)
Browse files Browse the repository at this point in the history
* feat: added extra basic nested object feature

No search.

* test: added finding doc tests

* chore(package): bump to 2.1.0

* test: added remove to benchmark

* fix: basic verification on elements being returned

* fix(getAll): deal with resolvedP being array.

* test: correctly perform specific query
  • Loading branch information
Alex-Werner committed Oct 9, 2019
1 parent d36136f commit 3a00b49
Show file tree
Hide file tree
Showing 11 changed files with 127 additions and 41 deletions.
11 changes: 9 additions & 2 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
## 2.1.0 (2019-10-08)
https://github.com/Alex-Werner/SBTree/pull/6

- feat: added basic nested object support

## 2.0.1 (2019-10-08)
https://github.com/Alex-Werner/SBTree/pull/5

- https://github.com/Alex-Werner/SBTree/pull/5
- fix: FsAdapter support for 2.0.0

## 2.0.0 (2019-10-08)
https://github.com/Alex-Werner/SBTree/pull/4

- https://github.com/Alex-Werner/SBTree/pull/4
- feat: added remove documents supports

## 1.3.0 (2019-09-)
## 1.2.1 (2019-09-07)
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sbtree",
"version": "2.0.1",
"version": "2.1.0",
"description": "Optimised document store using B+ Tree for fields. Adapters support for In-Memory and FileSystem",
"main": "index.js",
"scripts": {
Expand Down
8 changes: 6 additions & 2 deletions src/adapters/MemoryAdapter/methods/getDocument.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
module.exports = async function getDocument(identifier){
return JSON.parse(JSON.stringify(this.documents[identifier]));
}
const doc = this.documents[identifier];
if(doc){
return JSON.parse(JSON.stringify(this.documents[identifier]));
}
return {_id:identifier};
};
4 changes: 3 additions & 1 deletion src/types/SBFNode/methods/remove.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ async function remove(remCmd){
});

const leaf = this.childrens[leafIndex];
await leaf.remove(remCmd);
if(leaf){
await leaf.remove(remCmd);
}
};
module.exports = remove;

13 changes: 11 additions & 2 deletions src/types/SBFRoot/methods/getAll.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,17 @@ async function getAll() {
.all(p)
.then((res) => {
res.forEach((resolvedP) => {
result.identifiers.push(...resolvedP.identifiers);
result.keys.push(...resolvedP.keys);
if(resolvedP.identifiers){
result.identifiers.push(...resolvedP.identifiers);
result.keys.push(...resolvedP.keys);
}else if(Array.isArray(resolvedP)){
resolvedP.forEach((item) => {
result.identifiers.push(...item.identifiers);
result.keys.push(...item.keys);
});
}else{
throw new Error(`Unexpected type of resolvedP - type : ${typeof resolvedP}`)
}
});
resolve(result);
});
Expand Down
10 changes: 6 additions & 4 deletions src/types/SBFRoot/methods/remove.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ async function remove(remCmd){
});

const leaf = this.childrens[leafIndex];
await leaf.remove(remCmd);
if(leaf){
await leaf.remove(remCmd);

// This has been added for the case where previous also contains the same value
if(this.childrens[leafIndex-1]){
await this.childrens[leafIndex-1].remove(remCmd);
// This has been added for the case where previous also contains the same value
if(this.childrens[leafIndex-1]){
await this.childrens[leafIndex-1].remove(remCmd);
}
}
};
module.exports = remove;
23 changes: 15 additions & 8 deletions src/types/SBTree/ops/insert.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,22 @@ async function insert(document) {
const id = document._id.toString();

for (const _fieldName in document) {
const _fieldValue = document[_fieldName]
if (_fieldName !== '_id') {
if (!this.getFieldTree(_fieldName)) {
this.setFieldTree({fieldName:_fieldName});
}
const fieldTree = this.getFieldTree(_fieldName);
if(fieldTree){
await fieldTree.insert(id, _fieldValue);
const _fieldValue = document[_fieldName];

const _fieldType = typeof _fieldValue;

if (['string','number'].includes(_fieldType)) {
if(_fieldName !== '_id'){
if (!this.getFieldTree(_fieldName)) {
this.setFieldTree({fieldName:_fieldName});
}
const fieldTree = this.getFieldTree(_fieldName);
if(fieldTree){
await fieldTree.insert(id, _fieldValue);
}
}
}else{
this.verbose && console.log(`No index for ${_fieldName} : Typeof ${_fieldType} : ${JSON.stringify(_fieldValue)}`)
}
}
await this.adapter.saveDocument(document);
Expand Down
30 changes: 30 additions & 0 deletions test/e2e/use.case.2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const {expect} = require('chai');
const {SBTree} = require('../..');
describe('E2E - Classic UseCase', function suite() {
describe('RegUser DB', () => {
const customTree = new SBTree({
order: 3,
});
const alex = {
_id: "5d9d74a2668f032206e4dc01",
name:"Alex",
infos:{
job:{
sector: "IT"
}
}
};
it('should allow to insert documents with basic nested support', async function () {
await customTree.insertDocuments(alex);
});
it('should allow to find the document', async function () {
const doc = await customTree.findDocuments({name:"Alex"});
expect(doc).to.deep.equal([alex])
});
it('should not be able to find document on nested',async function () {
// May be we should warn user in some way ?
const doc = await customTree.findDocuments({infos:{job:{sector:"IT"}}});
expect(doc).to.deep.equal([]);
});
});
})
5 changes: 1 addition & 4 deletions test/unit/types/SBTree/ops/insert.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,7 @@ describe('SBTree - ops - insert', () => {
['setFieldTree', 'email'],
['getFieldTree', 'email'],

['getFieldTree', 'address'],
['setFieldTree', 'address'],
['getFieldTree', 'address'],

// Address is not called as we discard it (type is object)
['savedDocument', '5d6ebb7e21f1df6ff7482631'],
]);
});
Expand Down
60 changes: 44 additions & 16 deletions test/z_benchmark/1.standard.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ let standard = {
executedOp: 0,
duration: 0,
ops: 0
},
removeOp: {
maxOp: fakeData.length,
executedOp: 0,
duration: 0,
ops: 0
}
}
describe('SBTree - Performance - Standard Benchmark within test ', async function () {
Expand All @@ -41,29 +47,50 @@ describe('SBTree - Performance - Standard Benchmark within test ', async functio
const writeData = JSON.parse(JSON.stringify(fakeData));
const findData = JSON.parse(JSON.stringify(fakeData));
const getData = JSON.parse(JSON.stringify(fakeData));
const removeData = JSON.parse(JSON.stringify(fakeData));

const jobs = [
['writeOp', async () => {
const document = writeData.splice(Math.floor(Math.random() * (writeData.length - 1 + 1) + 0), 1)[0];
return tree.insertDocuments(document);
const len = writeData.length;
if (len > 0) {
const document = writeData.splice(Math.floor(Math.random() * (writeData.length - 1 + 1) + 0), 1)[0];
return tree.insertDocuments(document);
}
}],
['getOp', async () => {
const data = getData.splice(Math.floor(Math.random() * (getData.length - 1 + 1) + 0), 1)[0];
return tree.getDocument(data._id);
const len = getData.length;
if (len > 0) {
const data = getData.splice(Math.floor(Math.random() * (getData.length - 1 + 1) + 0), 1)[0];
return tree.getDocument(data._id);
}
}],
['findOp', async () => {
const rand = Math.floor(Math.random() * (findData.length - 1 + 1) + 0);
const query = {age:findData.splice(rand, 1)[0]};
return tree.findDocuments(query)
const len = findData.length;
if (len > 0) {
const rand = Math.floor(Math.random() * (findData.length - 1 + 1) + 0);
const query = findData.splice(rand, 1)[0];
return tree.findDocuments(query)
}
}],
['removeOp', async () => {
const len = removeData.length;
if (len > 0) {
const rand = Math.floor(Math.random() * (removeData.length - 1 + 1) + 0);
const query = {_id: removeData.splice(rand, 1)[0]._id};
return tree.deleteDocuments(query)
}
}]
];

const processNext = async (jobFn, jobName) => {
await jobFn();
standard[jobName].executedOp += 1;
if (standard[jobName].executedOp < standard[jobName].maxOp) {
await processNext(jobFn, jobName)
}
return new Promise(async (resolve, reject) =>{
await jobFn();
standard[jobName].executedOp += 1;
if (standard[jobName].executedOp < standard[jobName].maxOp) {
await processNext(jobFn, jobName)
}
resolve();
})
};

for (let _job of jobs) {
Expand All @@ -80,14 +107,15 @@ describe('SBTree - Performance - Standard Benchmark within test ', async functio
console.log(`Finished ${jobName} in ${timer.duration.ms} ms [${standard[jobName].ops}] ops`)
}
});
it('should display result', function (done) {
const totalDuration = standard.writeOp.duration + standard.getOp.duration + standard.findOp.duration;
const totalOps = standard.writeOp.executedOp + standard.getOp.executedOp + standard.findOp.executedOp;
const avgOps = (standard.writeOp.ops + standard.getOp.ops + standard.findOp.ops) / 3;
it('should display result', async function (done) {
const totalDuration = standard.writeOp.duration + standard.getOp.duration + standard.findOp.duration + standard.removeOp.duration;
const totalOps = standard.writeOp.executedOp + standard.getOp.executedOp + standard.findOp.executedOp + standard.removeOp.executedOp;
const avgOps = (standard.writeOp.ops + standard.getOp.ops + standard.findOp.ops + standard.removeOp.ops) / 4;
console.log(`======== SBTree ${version} - Benchmark from mocha`)
console.log(`= Write : ${standard.writeOp.ops} op/s [${standard.writeOp.executedOp}]`)
console.log(`= Get : ${standard.getOp.ops} op/s [${standard.getOp.executedOp}]`)
console.log(`= Find : ${standard.findOp.ops} op/s [${standard.findOp.executedOp}]`)
console.log(`= Remove : ${standard.removeOp.ops} op/s [${standard.removeOp.executedOp}]`)
console.log(`= ======== Summary`)
console.log(`= Total : ${totalOps} operations`)
console.log(`= Duration : ${totalDuration} s`)
Expand Down

0 comments on commit 3a00b49

Please sign in to comment.