Skip to content
Simon Y. Blackwell edited this page Apr 21, 2015 · 6 revisions

Prototype Enhancement

Constructor Re-Writes

Database Indexing

Every object added to a JOQULAR database is fully indexed using a nested JavaScript object first by its constructor, then by its keys, then value types, then (except in the case of functions) values. The terminal value key stores a final object whose keys are the unique ids of the objects that are instances of the constructor with the referenced keys, value, and type, e.g.

function MyClass(config) {
   for(var key in config) { this[key] = config[key] };
}
(MyClass.prototype.isMinor = function() { return this.age<21; }).predicate = true;
MyClass = JOQULAR.createIndex(MyClass);
new MyClass({name: 'Joe', age: 10});
new MyClass({name: 'Bill' age: 21});
new MyClass({name: 'Mary' age: 10});

effectively creates the index

MyClass.ids = {0: {name: 'Joe', age: 10}, 1: {name: 'Bill' age: 21}, 2: {name: 'Mary' age: 10}};
MyClass.index = {name: {string: {Joe: [0]}}, age: {number: {10: [0,2], 21: [1]}}, isMinor: [1,2,3] }};

Not shown above is the fact that the objects associated with MyClass.ids are actual instances and do support the isMinor function.

For primitive types, at run-time the value keys below the type keys are coerced into the type, sorted in an ascending manner, and have the operators specified in the JOQULAR match pattern applied to them. The application of operators takes advantage of the sort, e.g. eq' is actually tested using a binary search. The sorted values are cached until a new value is added to the index at the named key, e.g. adding new MyClass({name: 'John'}) will flush the cache for the namekey but not theage` key.

For function names stored as keys, each object identifier is de-referenced to the object itself and then the named function is invoked on the object. If the predicate length property is 0, then the pattern value is compared to the return value. If the length is greater than 0, i.e. the predicate takes arguments, then the pattern value is provided as arguments. Due to JSON constraints, these will always be an array if the predicate takes multiple arguments. See pseudo code below with variable values filled in for clarity.

MyClass.jocularFind({isMinor: true});
...
var key = "isMinor"; // value provided for clarity, will actually be bound in a loop
var value = pattern[key];
if(typeof(object[key])==="function" && object[key].predicate) {
  if(object[key].length===0) return value === object[`isMinor`]();
  else return  object[`isMinor`].apply(object,(value instanceof Array ? value : [value]));
}
...
Clone this wiki locally