working on persistent indexes...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2022-11-06 22:38:34 +03:00
parent 8313a40fe6
commit c58a117cb3
3 changed files with 65 additions and 52 deletions

View File

@ -244,7 +244,9 @@ function(name, generate, options={}){
// action: clear/reset... // action: clear/reset...
if(action == 'clear' if(action == 'clear'
|| action == 'reset'){ || action == 'reset'){
delete this[cache] } delete this[cache]
'reset' in options
&& options['reset'].call(this, null, name) }
if(action == 'clear'){ if(action == 'clear'){
return } return }
@ -261,15 +263,16 @@ function(name, generate, options={}){
var cur = cache in this ? var cur = cache in this ?
this[cache] this[cache]
: meth.call(this, 'reset') : meth.call(this, 'reset')
var res = _await(this, this[cache] = var res = _await(this,
// NOTE: this[action_meth] will fully shadow options[action]... this[cache] =
action_meth in this ? // NOTE: this[action_meth] will fully shadow options[action]...
this[action_meth](cur, ...args) action_meth in this ?
: (action in options this[action_meth](cur, ...args)
&& typeof(options[action]) == 'function') ? : (action in options
//options[action].call(this, cur, ...args) && typeof(options[action]) == 'function') ?
options[action].call(this, cur, name, ...args) //options[action].call(this, cur, ...args)
: cur) options[action].call(this, cur, name, ...args)
: cur)
res !== cur res !== cur
&& _stamp(this, res) && _stamp(this, res)
return res } return res }

View File

@ -256,6 +256,10 @@ module.BaseStore = {
index = update.call(this, index, name, path, await this.get(path)) } index = update.call(this, index, name, path, await this.get(path)) }
return index }, { return index }, {
update: async function(data, name, path, update){ update: async function(data, name, path, update){
// do not index cache...
if(this.__cache_path__
&& !path.startsWith(this.__cache_path__)){
return data }
var {tags, paths} = await data var {tags, paths} = await data
// remove obsolete tags... // remove obsolete tags...
this.__tags.options.remove.call(this, data, name, path) this.__tags.options.remove.call(this, data, name, path)
@ -305,7 +309,7 @@ module.BaseStore = {
// load index... // load index...
if(this.__cache_path__ if(this.__cache_path__
&& await this.exists(path)){ && await this.exists(path)){
return this.__search.options.load() return this.__search.options.load.call(this, null, 'search')
// generate... // generate...
} else { } else {
var index = new flexsearch.Index( var index = new flexsearch.Index(
@ -315,23 +319,11 @@ module.BaseStore = {
for(var path of (await this.paths)){ for(var path of (await this.paths)){
update.call(this, index, name, path, await this.get(path)) } } update.call(this, index, name, path, await this.get(path)) } }
return index }, { return index }, {
/* XXX problematic...
__save_changes: async function(name, action, path, ...args){
//if(this.__cache_path__
// && this.exists(this.__cache_path__ +'/'+ name)){
if(this.__cache_path__){
// do not save changes to changes ;)
if(path.startsWith(this.__cache_path__)){
return }
var p = [this.__cache_path__, name, 'changes'].join('/')
var {changes} = await this.get(p) ?? {}
changes = changes ?? []
changes.push([Date.now(), action, path, ...args])
// XXX this needs not to trigger handlers...
return this.__update(p, {changes}) } },
//*/
// XXX do a save???
update: async function(data, name, path, update){ update: async function(data, name, path, update){
// do not index cache...
if(this.__cache_path__
&& path.startsWith(this.__cache_path__)){
return data }
var {text, tags} = update var {text, tags} = update
text = [ text = [
path, path,
@ -347,51 +339,69 @@ module.BaseStore = {
// handle changes... // handle changes...
//this.__search.options.__save_changes.call(this, name, 'update', path, update) //this.__search.options.__save_changes.call(this, name, 'update', path, update)
return data }, return data },
// XXX do a save???
remove: async function(data, name, path){ remove: async function(data, name, path){
;(await data).remove(path) data = await data
data
&& data.remove(path)
// handle changes... // handle changes...
//this.__search.options.__save_changes.call(this, name, 'remove', path) //this.__search.options.__save_changes.call(this, name, 'remove', path)
return data }, return data },
// XXX EXPERIMENTAL... // XXX EXPERIMENTAL...
// XXX for this to work need to figure out how to save a page
// without triggering an index update...
// ...and do it fast!!
__save_changes: async function(name, action, path, ...args){
if(this.__cache_path__
&& !path.startsWith(this.__cache_path__)){
var p = [this.__cache_path__, name, 'changes'].join('/')
// XXX can we get/update in one op???
var {changes} = await this.get(p) ?? {}
changes = changes ?? []
changes.push([Date.now(), action, path, ...args])
// XXX this needs not to neither trigger handlers nor .index('update', ...)...
return this.__update(p, {changes}) } },
save: async function(data, name){ save: async function(data, name){
if(this.__cache_path__){ if(this.__cache_path__){
var that = this var that = this
var path = this.__cache_path__ +'/'+ name var path = this.__cache_path__ +'/'+ name
this.delete(path +'/changes') //this.delete(path +'/changes')
/*/ XXX HACK this thing runs async but does not return a promise... // XXX HACK this thing runs async but does not return a promise...
var index = {} // ...this is quote ugly but I can't figure out a way to
data.export(
function(key, value){
index[key] = value })
this.update(path, {index}) }
/*/
// XXX this is quote ugly but can't figure out a way to
// track when exporting is done... // track when exporting is done...
var index = {} var index = {}
data.export( data.export(
function(key, value){ function(key, value){
index[key] = value index[key] = value
return that.update(path, {index}) }) } return that.update(path, {index}) }) }
/*/
var index = {}
data.export(
function(key, value){
index[key] = value })
this.update(path, {index}) }
//*/ //*/
return data }, return data },
load: async function(data, name){ load: async function(data, name){
if(this.__cache_path__){ if(this.__cache_path__){
var path = this.__cache_path__ +'/'+ name var path = this.__cache_path__ +'/'+ name
var changes = path +'/changes' var changes = path +'/changes'
var {index} = var {index} = await this.get(path) ?? {}
await this.get(path) var data =
?? {index: {}} new flexsearch.Index(
var data = new flexsearch.Index( this.__search_options
this.__search_options ?? {})
?? {}) for(var [key, value] of Object.entries(index ?? {})){
for(var [key, value] of Object.entries(index)){ data.import(key, value) } }
data.import(key, value) } return data },
// XXX load changes... reset: function(_, name){
} this.__cache_path__
return data }, }), && this.delete(this.__cache_path__ +'/'+ name) },}),
search: function(){ search: function(...args){
return this.__search().search(...arguments) }, var s = this.__search()
return s instanceof Promise ?
s.then(function(s){
return s.search(...args)})
: s.search(...args) },
// //
@ -833,7 +843,6 @@ module.BaseStore = {
// one-by-one loader... // one-by-one loader...
} else { } else {
for(var [path, value] of Object.entries(input)){ for(var [path, value] of Object.entries(input)){
// XXX LOAD
this.update(path, value) } } this.update(path, value) } }
//this.__update(path, value) } } //this.__update(path, value) } }
return this }, return this },

View File

@ -25,6 +25,7 @@
* - * -
* *
* *
* XXX Q: can we get state and update in one go???
* XXX stored index cache: need to define the save/load strategy + stored * XXX stored index cache: need to define the save/load strategy + stored
* cache validation... * cache validation...
* XXX FEATURE: to avoid reinventing the wheel, serialize stuff as pages... * XXX FEATURE: to avoid reinventing the wheel, serialize stuff as pages...