From 0bdaf053f0d38ea3817fe7cdc905e5ba63e65899 Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Fri, 19 Apr 2019 00:29:38 -0700 Subject: [PATCH] initial RAD > < but need to decide default behavior --- lib/radisk.js | 21 +++++++++++++----- lib/radix.js | 14 ++++++++---- lib/rfs.js | 40 ++++------------------------------ lib/rindexed.js | 22 ++++++++++--------- lib/rls.js | 22 ++++++++++--------- lib/rmem.js | 22 +++++++++++++++++++ lib/store.js | 14 +++++++++--- test/rad/rad.js | 57 +++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 144 insertions(+), 68 deletions(-) create mode 100644 lib/rmem.js diff --git a/lib/radisk.js b/lib/radisk.js index 01847461..a575bb51 100644 --- a/lib/radisk.js +++ b/lib/radisk.js @@ -42,18 +42,18 @@ var r = function(key, val, cb){ key = ''+key; if(val instanceof Function){ - var o = cb; + var o = cb || {}; cb = val; val = r.batch(key); if(u !== val){ - cb(u, val, o); + cb(u, r.range(val, o), o); if(atomic(val)){ return } // if a node is requested and some of it is cached... the other parts might not be. } if(r.thrash.at){ val = r.thrash.at(key); if(u !== val){ - cb(u, val, o); + cb(u, r.range(val, o), o); if(atomic(val)){ cb(u, val, o); return } // if a node is requested and some of it is cached... the other parts might not be. } @@ -213,6 +213,17 @@ f.write(); } + r.range = function(tree, o){ + if(!tree || !o){ return } + if(u === o.start && u === o.end){ return tree } + if(atomic(tree)){ return tree } + var sub = Radix(); + Radix.map(tree, function(v,k){ + sub(k,v); + }, o) + return sub(''); + } + ;(function(){ var Q = {}; r.read = function(key, cb, o){ @@ -228,7 +239,7 @@ var g = function Get(){}, tmp; g.lex = function(file){ file = (u === file)? u : decodeURIComponent(file); - if(!file || file > (o.next || key)){ + if(!file || file > (o.next || key || o.start || '')){ if(o.next){ g.file = file } if(tmp = Q[g.file]){ tmp.push({key: key, ack: cb, file: g.file, opt: o}); @@ -249,7 +260,7 @@ } g.ack = function(as){ if(!as.ack){ return } - var tmp = as.key, o = as.opt, info = g.info, rad = g.disk || noop, data = rad(tmp), last = rad.last; + var tmp = as.key, o = as.opt, info = g.info, rad = g.disk || noop, data = r.range(rad(tmp), o), last = rad.last; o.parsed = (o.parsed || 0) + (info.parsed||0); o.chunks = (o.chunks || 0) + 1; if(!o.some){ o.some = (u !== data) } diff --git a/lib/radix.js b/lib/radix.js index 03fa31bb..6198c762 100644 --- a/lib/radix.js +++ b/lib/radix.js @@ -8,6 +8,7 @@ delete (radix.$||{})[_]; } t = t || radix.$ || (radix.$ = {}); + if(!key && Object.keys(t).length){ return t } var i = 0, l = key.length-1, k = key[i], at, tmp; while(!(at = t[k]) && i < l){ k += key[++i]; @@ -55,16 +56,21 @@ if(!t){ return } var keys = (t[_]||no).sort || (t[_] = function $(){ $.sort = Object.keys(t).sort(); return $ }()).sort; //var keys = Object.keys(t).sort(); + opt = (true === opt)? {branch: true} : (opt || {}); + var start = opt.start, end = opt.end; var i = 0, l = keys.length; - for(;i < l; i++){ var key = keys[i], tree = t[key], tmp, p; + for(;i < l; i++){ var key = keys[i], tree = t[key], tmp, p, pt; if(!tree || '' === key || _ === key){ continue } p = pre.slice(); p.push(key); + pt = p.join(''); + if(start && pt < start.slice(0,pt.length)){ continue } + if(end && end < pt){ continue } if(u !== (tmp = tree[''])){ - tmp = cb(tmp, p.join(''), key, pre); + tmp = cb(tmp, pt, key, pre); if(u !== tmp){ return tmp } } else - if(opt){ - tmp = cb(u, pre.join(''), key, pre); + if(opt.branch){ + tmp = cb(u, pt, key, pre); if(u !== tmp){ return tmp } } pre = p; diff --git a/lib/rfs.js b/lib/rfs.js index 42a49e23..7473f258 100644 --- a/lib/rfs.js +++ b/lib/rfs.js @@ -1,9 +1,7 @@ -var Gun = (typeof window !== "undefined")? window.Gun : require('../gun'); - function Store(opt){ opt = opt || {}; + opt.log = opt.log || console.log; opt.file = String(opt.file || 'radata'); - if(Gun.TESTING){ opt.file = 'radatatest' } var fs = require('fs'), u; var store = function Store(){}; @@ -21,18 +19,13 @@ function Store(opt){ if('ENOENT' === (err.code||'').toUpperCase()){ return cb(null); } - Gun.log("ERROR:", err) + opt.log("ERROR:", err) } cb(err, data); }); }; - store.list = function(cb, match){ - fs.readdir(opt.file, function(err, dir){ - Gun.obj.map(dir, cb) || cb(); // Stream interface requires a final call to know when to be done. - }); - }; + if(!fs.existsSync(opt.file)){ fs.mkdirSync(opt.file) } - //store.list(function(){ return true }); function move(oldPath, newPath, cb) { fs.rename(oldPath, newPath, function (err) { @@ -61,29 +54,4 @@ function Store(opt){ return store; } -function Mem(opt){ - opt = opt || {}; - opt.file = String(opt.file || 'radata'); - var storage = Mem.storage || (Mem.storage = {}); - var store = function Store(){}, u; - store.put = function(file, data, cb){ - setTimeout(function(){ - storage[file] = data; - cb(null, 1); - }, 1); - }; - store.get = function(file, cb){ - setTimeout(function(){ - var tmp = storage[file] || u; - cb(null, tmp); - }, 1); - }; - store.list = function(cb, match){ // supporting this is no longer needed! Optional. - setTimeout(function(){ - Gun.obj.map(Object.keys(storage), cb) || cb(); - }, 1); - }; - return store; -} - -module.exports = Store;//Gun.TESTING? Mem : Store; +module.exports = Store; \ No newline at end of file diff --git a/lib/rindexed.js b/lib/rindexed.js index e27f8d6c..0ec5c16c 100644 --- a/lib/rindexed.js +++ b/lib/rindexed.js @@ -1,15 +1,8 @@ ;(function(){ - var Gun = (typeof window !== "undefined")? window.Gun : require('../gun'); - - Gun.on('create', function(root){ - this.to.next(root); - root.opt.store = root.opt.store || Store(root.opt); - }); function Store(opt){ opt = opt || {}; opt.file = String(opt.file || 'radata'); - if(Gun.TESTING){ opt.file = 'radatatest' } opt.chunk = opt.chunk || (1024 * 1024); // 1MB var db = null, u; @@ -53,9 +46,18 @@ return store; } - if(Gun.window){ - Gun.window.RindexedDB = Store; + if(typeof window !== "undefined"){ + window.RindexedDB = Store; } else { - module.exports = Store; + try{ module.exports = Store }catch(e){} } + + try{ + var Gun = Gun || require('../gun'); + Gun.on('create', function(root){ + this.to.next(root); + root.opt.store = root.opt.store || Store(root.opt); + }); + }catch(e){} + }()); \ No newline at end of file diff --git a/lib/rls.js b/lib/rls.js index f01f7801..8c271cdb 100644 --- a/lib/rls.js +++ b/lib/rls.js @@ -1,15 +1,8 @@ ;(function(){ - var Gun = (typeof window !== "undefined")? window.Gun : require('../gun'); - - Gun.on('create', function(root){ - this.to.next(root); - root.opt.store = root.opt.store || Store(root.opt); - }); function Store(opt){ opt = opt || {}; opt.file = String(opt.file || 'radata'); - if(Gun.TESTING){ opt.file = 'radatatest' } var store = function Store(){}; var ls = localStorage; @@ -19,9 +12,18 @@ return store; } - if(Gun.window){ - Gun.window.RlocalStorage = Store; + if(typeof window !== "undefined"){ + window.RlocalStorage = Store; } else { - module.exports = Store; + try{ module.exports = Store }catch(e){} } + + try{ + var Gun = Gun || require('../gun'); + Gun.on('create', function(root){ + this.to.next(root); + root.opt.store = root.opt.store || Store(root.opt); + }); + }catch(e){} + }()); \ No newline at end of file diff --git a/lib/rmem.js b/lib/rmem.js new file mode 100644 index 00000000..f2361d22 --- /dev/null +++ b/lib/rmem.js @@ -0,0 +1,22 @@ +function Rmem(){ + var opt = {}, store = {}, u; + opt.put = function(file, data, cb){ + //setTimeout(function(){ // make async + store[file] = data; + cb(null, 1); + //}, 1); + }; + opt.get = function(file, cb){ + //setTimeout(function(){ // make async + var tmp = store[file] || u; + cb(null, tmp); + //}, 1); + }; + return opt; +} + +if(typeof window !== "undefined"){ + window.Rmem = Rmem; +} else { + try{ module.exports = Rmem }catch(e){} +} \ No newline at end of file diff --git a/lib/store.js b/lib/store.js index 0b7b1e38..ab826842 100644 --- a/lib/store.js +++ b/lib/store.js @@ -4,6 +4,7 @@ Gun.on('create', function(root){ this.to.next(root); var opt = root.opt, u; if(false === opt.radisk){ return } + if(Gun.TESTING){ opt.file = 'radatatest' } var Radisk = (Gun.window && Gun.window.Radisk) || require('./radisk'); var Radix = Radisk.Radix; @@ -36,27 +37,34 @@ Gun.on('create', function(root){ root.on('get', function(msg){ this.to.next(msg); var id = msg['#'], get = msg.get, soul = msg.get['#'], has = msg.get['.']||'', opt = {}, graph, lex, key, tmp, force; - if(typeof soul == 'string'){ + if('string' == typeof soul){ key = soul; } else if(soul){ if(u !== (tmp = soul['*'])){ opt.limit = force = 1 } + if(u !== soul['>']){ opt.start = soul['>'] } + if(u !== soul['<']){ opt.end = soul['<'] } key = force? (''+tmp) : tmp || soul['=']; + force = null; } if(key && !opt.limit){ // a soul.has must be on a soul, and not during soul* - if(typeof has == 'string'){ + if('string' == typeof has){ key = key+esc+(opt.atom = has); } else if(has){ + if(u !== has['>']){ opt.start = has['>']; opt.limit = 1 } + if(u !== has['<']){ opt.end = has['<']; opt.limit = 1 } if(u !== (tmp = has['*'])){ opt.limit = force = 1 } - if(key){ key = key+esc + (force? (''+tmp) : tmp || (opt.atom = has['='])) } + if(key){ key = key+esc + (force? (''+(tmp||'')) : tmp || (opt.atom = has['='] || '')) } } } if((tmp = get['%']) || opt.limit){ opt.limit = (tmp <= (opt.pack || (1000 * 100)))? tmp : 1; } + //console.log("RAD get:", key, opt); //var start = (+new Date); // console.log("GET!", id, JSON.stringify(key)); rad(key||'', function(err, data, o){ + //console.log("RAD gat:", err, data, o); if(data){ if(typeof data !== 'string'){ if(opt.atom){ diff --git a/test/rad/rad.js b/test/rad/rad.js index e2f597c7..39a10cdf 100644 --- a/test/rad/rad.js +++ b/test/rad/rad.js @@ -73,6 +73,42 @@ var names = ["Adalard","Adora","Aia","Albertina","Alfie","Allyn","Amabil","Ammam expect(Gun.obj.empty(all)).to.be.ok(); done(); }); + + it('radix read start end', function(done){ + var all = {}, start = 'Warring'.toLowerCase(), end = 'Zamir'.toLowerCase(); + names.forEach(function(v,i){ + v = v.toLowerCase(); + if(v < start){ return } + if(end < v){ return } + all[v] = v; + //rad(v, i) + }); + expect(Gun.obj.empty(all)).to.not.be.ok(); + Radix.map(radix, function(v,k, a,b){ + //if(!all[k]){ throw "out of range!" } + delete all[k]; + }, {start: start, end: end}); + expect(Gun.obj.empty(all)).to.be.ok(); + done(); + }); + + it('radix read start- end+', function(done){ + var all = {}, start = 'Warrinf'.toLowerCase(), end = 'Zamis'.toLowerCase(); + names.forEach(function(v,i){ + v = v.toLowerCase(); + if(v < start){ return } + if(end < v){ return } + all[v] = v; + //rad(v, i) + }); + expect(Gun.obj.empty(all)).to.not.be.ok(); + Radix.map(radix, function(v,k, a,b){ + //if(!all[k]){ throw "out of range!" } + delete all[k]; + }, {start: start, end: end}); + expect(Gun.obj.empty(all)).to.be.ok(); + done(); + }); }); describe('Radisk', function(){ @@ -102,6 +138,27 @@ var names = ["Adalard","Adora","Aia","Albertina","Alfie","Allyn","Amabil","Ammam }) }); + it('read contacts start', function(done){ + var opt = {}; + opt.start = 'Warring'.toLowerCase(); + opt.end = 'Zamir'.toLowerCase(); + var all = {}, find = ''; + names.forEach(function(v){ + v = v.toLowerCase(); + if(v < opt.start){ return } + if(opt.end < v){ return } + if(v.indexOf(find) == 0){ all[v] = true } + }); + rad(find, function(err, data){ + Radix.map(data, function(v,k){ + //console.log(find+k, v); + delete all[find+k]; + }); + if(!Gun.obj.empty(all)){ return } + done(); + }, opt); + }); + it('read contacts', function(done){ var all = {}, find = 'a'; names.forEach(function(v){