From 9abebd767316fd948dbed4087e72016c9846bc90 Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Tue, 24 Jan 2023 15:51:26 -0800 Subject: [PATCH] rad fixed dup text, perf, read + tests. --- lib/book.js | 8 ++++---- lib/radisk3.js | 51 ++++++++++++++++++++++++++---------------------- test/rad/book.js | 23 ++++++++++++++-------- 3 files changed, 47 insertions(+), 35 deletions(-) diff --git a/lib/book.js b/lib/book.js index 68830b57..12936305 100644 --- a/lib/book.js +++ b/lib/book.js @@ -17,7 +17,7 @@ var sT = setTimeout, B = sT.Book || (sT.Book = function(text){ return b.set(word, is); }; // TODO: if from text, preserve the separator symbol. - b.list = [{from: text, size: (text||'').length, substring: sub, toString: to, book: b}]; + b.list = [{from: text, size: (text||'').length, substring: sub, toString: to, book: b, get: b}]; b.page = page; b.set = set; b.get = get; @@ -27,7 +27,7 @@ var sT = setTimeout, B = sT.Book || (sT.Book = function(text){ function page(word){ var b = this, l = b.list, i = spot(B.encode(word), l), p = l[i]; - if('string' == typeof p){ l[i] = p = {size: -1, first: p, substring: sub, toString: to, book: b} } // TODO: test, how do we arrive at this condition again? + if('string' == typeof p){ l[i] = p = {size: -1, first: p, substring: sub, toString: to, book: b, get: b} } // TODO: test, how do we arrive at this condition again? return p; // TODO: BUG! What if we get the page, it turns out to be too big & split, we must then RE get the page! } @@ -89,7 +89,7 @@ function split(p, b){ //console.time(); var L = p.list = p.list.sort(), l = L.length, i = l/2 >> 0, j = i, half = L[j], tmp; //console.timeEnd(); - var next = {list: [], first: B.encode(half.substring()), size: 0, substring: sub, toString: to, book: b}, nl = next.list; + var next = {list: [], first: B.encode(half.substring()), size: 0, substring: sub, toString: to, book: b, get: b}, nl = next.list; nl.toString = join; //console.time(); while(tmp = L[i++]){ @@ -121,7 +121,7 @@ function join(){ return this.join('|') } function text(p){ if(!p.list){ return (p.from||'')+'' } if(!p.from){ return '|'+((p.list && (p.list = p.list.sort()).join('|'))||'')+'|' } - return '|'+from(p).concat(p.list).sort().join('|')+'|'; + return '|'+/*from(p).concat(p.list)*/p.list.sort().join('|')+'|'; // commenting out this sub-portion of code fixed a more basic test, but will probably cause a bug with a FROM + MEMORY. } B.encode = function(d, _){ _ = _ || "'"; diff --git a/lib/radisk3.js b/lib/radisk3.js index d4337746..c0045fa3 100644 --- a/lib/radisk3.js +++ b/lib/radisk3.js @@ -1,17 +1,17 @@ -;(function () { // RAD +;(function(){ // RAD console.log("Warning: Experimental rewrite of RAD to use Book. It is not API compatible with RAD yet and is very alpha."); - var sT = setTimeout, Book = sT.Book, RAD = sT.RAD || (sT.RAD = function (opt) { + var sT = setTimeout, Book = sT.Book, RAD = sT.RAD || (sT.RAD = function(opt){ opt = opt || {}; opt.file = String(opt.file || 'radata'); var log = opt.log || nope; var has = (sT.RAD.has || (sT.RAD.has = {}))[opt.file]; if (has) { return has } - var r = function rad(word, is, reply) { - if (!b) { start(word, is, reply); return r } - if (is === undefined || 'function' == typeof is) { // THIS IS A READ: + var r = function rad(word, is, reply){ + if(!b){ start(word, is, reply); return r } + if(is === undefined || 'function' == typeof is){ // THIS IS A READ: var page = b.page(word); - if (page.from) { + if(page.from){ return is(null, page); } read(word, is, page); // get from disk @@ -26,50 +26,53 @@ }, /** @param b the book */ b; - async function read(word, reply, page) { + async function read(word, reply, page){ var p = page;//b.page(word); reply = reply.call ? reply : () => { }; log(`read() ${word.slice(0, 40)}`); - get(p, function (err, disk) { - if (err) { log("ERR! in read() get() cb", err); reply(err); return } + get(p, function(err, disk){ + if(err){ log("ERR! in read() get() cb", err); reply(err); return } p.from = disk || p.from; reply(null, p, b); }) } - async function write(word, reply) { - log('write() word', word); + async function write(word, reply){ + //log('write() word', word); var p = b.page(word), tmp; - if (tmp = p.saving) { reply && tmp.push(reply); return } p.saving = [reply]; + if(tmp = p.saving){ reply && tmp.push(reply); return } p.saving = [reply]; var S = +new Date; log(" writing", p.substring(), 'since last', S - p.saved, RAD.c, 'records', env.count++, 'mid-swap.'); - get(p, function (err, disk) { - if (err) { log("ERR! in write() get() cb ", err); return } - log(' get() - p.saving ', (p.saving || []).length); - if (p.from && disk) { - log(" get() merge: p.from ", p.toString().slice(0, 40), " disk.length", disk?.length || 0); + get(p, function(err, disk){ + if(err){ log("ERR! in write() get() cb ", err); return } + //log(' get() - p.saving ', (p.saving || []).length); + if(p.from && disk){ + //log(" get() merge: p.from ", p.toString().slice(0, 40), " disk.length", disk?.length || 0); } p.from = disk || p.from; // TODO: NEED TO MERGE! AND HANDLE ERR! + // var save = '' + p; if(!p.from){ p.from = save } // p.list = p.text = p.from = 0; // p.first = p.first.word || p.first; tmp = p.saving; p.saving = []; - put(p, '' + p, function (err, ok) { + put(p, p.from = '' + p, function(err, ok){ env.count--; p.saved = +new Date; log(" ...wrote %d bytes in %dms", ('' + p).length, (p.saved = +new Date) - S); - if (!p.saving.length) { p.saving = 0; reply?.call && reply(err, ok); return; } p.saving = 0; // what? + if(!p.saving.length){ p.saving = 0; reply?.call && reply(err, ok); return; } p.saving = 0; // what? // log({ tmp }); write(word, reply); }); }) } - function put(file, data, cb) { + function put(file, data, cb){ file.first && (file = Book.slot(file.first)[0]); put[file = fname(file)] = { data: data }; - RAD.put(file, data, function (err, ok) { + RAD.put(file, data, function(err, ok){ delete put[file]; cb && cb(err, ok); }); }; function get(file, cb) { var tmp; + if(!file){ return } // TODO: HANDLE ERROR!! + if(file.from){ cb(null, file.from); return } // IS THIS LINE SAFE? ADD TESTS! file.first && (file = Book.slot(file.first)[0]); if (tmp = put[file = fname(file)]) { cb(u, tmp.data); return } if (tmp = get[file]) { tmp.push(cb); return } get[file] = [cb]; @@ -172,11 +175,13 @@ if (!lS) { return } var sT = setTimeout, RAD = sT.RAD; - RAD.put = function (file, data, cb) { + RAD.put = function(file, data, cb){ + //setTimeout(function(){ lS[file] = data; cb(null, 1); + //},9); } - RAD.get = function (file, cb) { + RAD.get = function(file, cb){ cb(null, lS[file]); } }()); diff --git a/test/rad/book.js b/test/rad/book.js index 939d91dd..d65290a7 100644 --- a/test/rad/book.js +++ b/test/rad/book.js @@ -5,7 +5,7 @@ var Gun; if(typeof global !== 'undefined'){ env = global } if(typeof window !== 'undefined'){ env = window } root = env.window? env.window : global; - //try{ env.window && root.localStorage && root.localStorage.clear() }catch(e){} + try{ env.window && root.localStorage && root.localStorage.clear() }catch(e){} //try{ indexedDB.deleteDatabase('radatatest') }catch(e){} if(root.Gun){ root.Gun = root.Gun; @@ -73,9 +73,8 @@ var names = ["Adalard","Adora","Aia","Albertina","Alfie","Allyn","Amabil","Ammam it('read', function(done){ rad('hello', function(err, page){ - var val = page.book('hello'); + var val = page.get('hello'); expect(val).to.be('world'); - console.log('read:', val); done(); }) }); @@ -96,15 +95,23 @@ var names = ["Adalard","Adora","Aia","Albertina","Alfie","Allyn","Amabil","Ammam var prim = ['alice', 'bob']; root.rad = rad; - describe('can write & read all primitives', done => { prim.forEach(function(type){ + describe('can in-memory write & read all primitives', done => { prim.forEach(function(type){ + var b = setTimeout.Book(); + it('save '+type, done => { setTimeout(function(){ + b('type-'+type, type); + var val = b('type-'+type); + expect(val).to.be(type); + done(); + },1); }); + });}); + + describe('can disk write & read all primitives', done => { prim.forEach(function(type){ var r = rad; it('save '+type, done => { setTimeout(function(){ - console.log("how many times is this called?", type); r('type-'+type, type, function(err, ok){ expect(err).to.not.be.ok(); r('type-'+type, function(err, page){ - var val = page.book('type-'+type); - console.log("we loaded", page, val); + var val = page.get('type-'+type); expect(val).to.be(type); done(); }); @@ -115,7 +122,7 @@ var names = ["Adalard","Adora","Aia","Albertina","Alfie","Allyn","Amabil","Ammam }); var ntmp = names; - describe.skip('RAD + GUN', function(){ + describe.skip('RAD + GUN', function(){ return; this.timeout(1000 * 9); var ochunk = 1000; Gun.on('opt', function(root){