rdf.js | |
---|---|
An in-memory RDF store with support for:
| define(['lib/collections/sorted-set', 'lib/collections/iterator'],
function(SortedSet, Iterator){ |
Private Variables
| var cantor = function(a, b){
return (a+b)*(a+b+1)/2+b;
}; |
IDs and ValuesThroughout this RDF module, the terms "subject", "predicate", and "object" refer to integer ids that map to elements of an RDF triple of the form (subject, predicate, object). | var idsAndValues = (function(){ |
Code that maps between IDs and values is located here. | var i = 1, ids = {}, values = {};
return {
id: function(value){
var id = ids[value];
if(!id){
id = ids[value] = i++;
values[id] = value;
}
return id;
}, |
The | value: function(id){
return values[id];
}
};
})(); |
Indices | var indices = { |
| s: new SortedSet(), |
| p: new SortedSet(), |
| o: new SortedSet(), |
| po: {}, |
| so: {}, |
| sp: {},
|
| |
| qiw: {}, |
| qwi: {}, |
| iqw: {}, |
| wqi: {}, |
| iwq: {}, |
| wiq: {}
};
var prefixes = {
'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
'rdfs': 'http://www.w3.org/2000/01/rdf-schema#'
}; |
Public API | var rdf = { |
| id: idsAndValues.id, |
| value: idsAndValues.value, |
| insert: (function(){
function indexInsert(index, key, value){
var sortedSet = index[key];
if(!sortedSet)
sortedSet = index[key] = new SortedSet();
sortedSet.add(value);
};
return function(s, p, o){
indices.s.add(s);
indices.p.add(p);
indices.o.add(o);
indexInsert(indices.sp, cantor(s, p), o);
indexInsert(indices.po, cantor(p, o), s);
indexInsert(indices.so, cantor(s, o), p);
indexInsert(indices.qiw, p, s);
indexInsert(indices.qwi, o, s);
indexInsert(indices.iqw, s, p);
indexInsert(indices.wqi, o, p);
indexInsert(indices.iwq, s, o);
indexInsert(indices.wiq, p, o);
}
})(), |
| query: function(s, p, o){
if(s === '?' && p === '*' && o === '*')
return indices.s.iterate();
if(s === '*' && p === '?' && o === '*')
return indices.p.iterate();
if(s === '*' && p === '*' && o === '?')
return indices.o.iterate();
if(s === '?' && p != '*' && o != '*')
return indices.po[cantor(p, o)].iterate();
if(s != '*' && p === '?' && o != '*')
return indices.so[cantor(s, o)].iterate();
if(s != '*' && p != '*' && o === '?')
return indices.sp[cantor(s, p)].iterate();
if(s === '?' && p != '*' && o === '*')
return indices.qiw[p].iterate();
if(s === '?' && p === '*' && o != '*')
return indices.qwi[o].iterate();
if(s != '*' && p === '?' && o === '*')
return indices.iqw[s].iterate();
if(s === '*' && p === '?' && o != '*')
return indices.wqi[o].iterate();
if(s != '*' && p === '*' && o === '?')
return indices.iwq[s].iterate();
if(s === '*' && p != '*' && o === '?')
return indices.wiq[p].iterate();
},
and: function(it1, it2){
var nextValue, next1, next2;
var findNextValue = function(){
nextValue = undefined;
next1 = next2 = NaN;
while(!nextValue){
try{
if(next1 === next2)
nextValue = next1;
else
if(next1 < next2 || isNaN(next1))
next1 = it1.next();
else if(next2 < next1 || isNaN(next2))
next2 = it2.next();
}
catch(e){ |
Flow goes here when iteration ends | break;
}
}
};
findNextValue();
return {
next: function(){
var currentValue = nextValue;
if(currentValue != undefined){
findNextValue();
return currentValue;
}
else |
StopIteration is thrown for all collections when iteration terminates. It is a global injected by Iterator.js. | throw StopIteration;
}
};
},
qn: function(qName){
var arr = qName.split(':'),
prefix = arr[0],
localPart = arr[1];
return rdf.id(prefixes[prefix] + localPart);
}
};
return rdf;
});
|