mirror of
https://github.com/flynx/pWiki.git
synced 2025-10-29 18:10:09 +00:00
moved to new index -- +50% performance boost, still not done.
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
fc36053293
commit
40f10250f5
@ -16,39 +16,6 @@ var index = require('../index')
|
|||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
//
|
|
||||||
// cached(<name>, <update>[, ...<args>])
|
|
||||||
// cached(<name>, <get>, <update>[, ...<args>])
|
|
||||||
// -> <func>
|
|
||||||
//
|
|
||||||
// NOTE: in the first case (no <get>) the first <args> item can not be
|
|
||||||
// a function...
|
|
||||||
//
|
|
||||||
// XXX better introspection???
|
|
||||||
var cached =
|
|
||||||
module.cached =
|
|
||||||
function(name, get, update, ...args){
|
|
||||||
name = `__${name}_cache`
|
|
||||||
if(typeof(update) != 'function'){
|
|
||||||
args.unshift(update)
|
|
||||||
update = get
|
|
||||||
get = null }
|
|
||||||
return update instanceof types.AsyncFunction ?
|
|
||||||
async function(){
|
|
||||||
var cache = this[name] =
|
|
||||||
this[name]
|
|
||||||
?? await update.call(this)
|
|
||||||
return get ?
|
|
||||||
get.call(this, cache, ...arguments)
|
|
||||||
: cache }
|
|
||||||
: function(){
|
|
||||||
var cache = this[name] =
|
|
||||||
this[name]
|
|
||||||
?? update.call(this)
|
|
||||||
return get ?
|
|
||||||
get.call(this, cache, ...arguments)
|
|
||||||
: cache } }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
@ -76,9 +43,9 @@ function(name, get, update, ...args){
|
|||||||
// When overloading it is needed to to call the super method to
|
// When overloading it is needed to to call the super method to
|
||||||
// retain base functionality.
|
// retain base functionality.
|
||||||
// All overloading here is optional.
|
// All overloading here is optional.
|
||||||
// .paths()
|
// .paths
|
||||||
// -> <path-list>
|
// -> <path-list>
|
||||||
// .names()
|
// .names
|
||||||
// -> <name-index>
|
// -> <name-index>
|
||||||
//
|
//
|
||||||
// .exists(<path>)
|
// .exists(<path>)
|
||||||
@ -160,23 +127,23 @@ module.BaseStore = {
|
|||||||
return index.index(this, ...arguments) },
|
return index.index(this, ...arguments) },
|
||||||
|
|
||||||
// XXX INDEX...
|
// XXX INDEX...
|
||||||
__xpaths__: async function(){
|
__paths__: async function(){
|
||||||
return Object.keys(this.data) },
|
return Object.keys(this.data) },
|
||||||
// XXX unique???
|
// XXX unique???
|
||||||
__xpaths_merge__: async function(data){
|
__paths_merge__: async function(data){
|
||||||
return (await data)
|
return (await data)
|
||||||
.concat((this.next
|
.concat((this.next
|
||||||
&& 'xpaths' in this.next) ?
|
&& 'paths' in this.next) ?
|
||||||
await this.next.xpaths
|
await this.next.paths
|
||||||
: []) },
|
: []) },
|
||||||
__xpaths_isvalid__: function(t){
|
__paths_isvalid__: function(t){
|
||||||
var changed =
|
var changed =
|
||||||
!!this.__xpaths_next_exists != !!this.next
|
!!this.__paths_next_exists != !!this.next
|
||||||
|| (!!this.next
|
|| (!!this.next
|
||||||
&& this.next.__xpaths_modified > t)
|
&& this.next.__paths_modified > t)
|
||||||
this.__xpaths_next_exists = !this.next
|
this.__paths_next_exists = !this.next
|
||||||
return changed },
|
return changed },
|
||||||
__xpaths: index.makeIndex('xpaths', {
|
__paths: index.makeIndex('paths', {
|
||||||
update: async function(data, path){
|
update: async function(data, path){
|
||||||
data = await data
|
data = await data
|
||||||
// XXX normalize???
|
// XXX normalize???
|
||||||
@ -191,14 +158,14 @@ module.BaseStore = {
|
|||||||
return data }, }),
|
return data }, }),
|
||||||
// XXX should this clone the data???
|
// XXX should this clone the data???
|
||||||
// XXX should we use 'lazy'???
|
// XXX should we use 'lazy'???
|
||||||
get xpaths(){
|
get paths(){
|
||||||
return this.__xpaths() },
|
return this.__paths() },
|
||||||
|
|
||||||
// NOTE: this is built from .paths so there is no need to define a
|
// NOTE: this is built from .paths so there is no need to define a
|
||||||
// way to merge...
|
// way to merge...
|
||||||
__xnames: index.makeIndex('xnames',
|
__names: index.makeIndex('names',
|
||||||
function(){
|
function(){
|
||||||
return this.xpaths
|
return this.paths
|
||||||
.iter()
|
.iter()
|
||||||
.reduce(function(res, path){
|
.reduce(function(res, path){
|
||||||
var n = pwpath.basename(path)
|
var n = pwpath.basename(path)
|
||||||
@ -226,76 +193,12 @@ module.BaseStore = {
|
|||||||
return data }, }),
|
return data }, }),
|
||||||
// XXX should this clone the data???
|
// XXX should this clone the data???
|
||||||
// XXX should we use 'lazy'???
|
// XXX should we use 'lazy'???
|
||||||
get xnames(){
|
get names(){
|
||||||
return this.__xnames() },
|
return this.__names() },
|
||||||
|
|
||||||
|
// XXX tags
|
||||||
|
// XXX search
|
||||||
|
|
||||||
// XXX might be a good idea to cache this...
|
|
||||||
__paths__: async function(){
|
|
||||||
return Object.keys(this.data) },
|
|
||||||
// local paths...
|
|
||||||
__paths: cached('paths', async function(){
|
|
||||||
return this.__paths__() }),
|
|
||||||
// NOTE: this produces an unsorted list...
|
|
||||||
// XXX should this also be cached???
|
|
||||||
paths: async function(local=false){
|
|
||||||
return this.__paths()
|
|
||||||
.iter()
|
|
||||||
.concat((!local && (this.next || {}).paths) ?
|
|
||||||
this.next.paths()
|
|
||||||
: []) },
|
|
||||||
|
|
||||||
// XXX BUG: after caching this will ignore the local argument....
|
|
||||||
names: cached('names', async function(local=false){
|
|
||||||
return this.paths(local)
|
|
||||||
.iter()
|
|
||||||
.reduce(function(res, path){
|
|
||||||
var n = pwpath.basename(path)
|
|
||||||
if(!n.includes('*')){
|
|
||||||
(res[n] = res[n] ?? []).push(path) }
|
|
||||||
return res }, {}) }),
|
|
||||||
|
|
||||||
// XXX sort paths based on search order into three groups:
|
|
||||||
// - non-system
|
|
||||||
// ...sorted by length?
|
|
||||||
// - system
|
|
||||||
// ...sort based on system search order?
|
|
||||||
__sort_names: function(){},
|
|
||||||
|
|
||||||
__cache_add: function(path){
|
|
||||||
if(this.__paths_cache){
|
|
||||||
this.__paths_cache.includes(path)
|
|
||||||
|| this.__paths_cache.push(path) }
|
|
||||||
if(this.__names_cache){
|
|
||||||
var name = pwpath.basename(path)
|
|
||||||
var names = (this.__names_cache[name] =
|
|
||||||
this.__names_cache[name]
|
|
||||||
?? [])
|
|
||||||
names.includes(path)
|
|
||||||
|| names.push(path) }
|
|
||||||
return this },
|
|
||||||
__cache_remove: function(path){
|
|
||||||
if(this.__paths_cache){
|
|
||||||
var paths = this.__paths_cache
|
|
||||||
paths.splice(
|
|
||||||
paths.indexOf(
|
|
||||||
paths.includes(path) ?
|
|
||||||
path
|
|
||||||
: path[0] == '/' ?
|
|
||||||
path.slice(1)
|
|
||||||
: '/'+path),
|
|
||||||
1) }
|
|
||||||
if(this.__names_cache){
|
|
||||||
var name = pwpath.basename(path)
|
|
||||||
var names = (this.__names_cache[name] =
|
|
||||||
this.__names_cache[name]
|
|
||||||
?? [])
|
|
||||||
var i = names.indexOf(path)
|
|
||||||
i >= 0
|
|
||||||
&& names.splice(i, 1)
|
|
||||||
if(names.length == 0){
|
|
||||||
delete this.__names_cache[name] } }
|
|
||||||
return this },
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// .exists(<path>)
|
// .exists(<path>)
|
||||||
@ -337,9 +240,7 @@ module.BaseStore = {
|
|||||||
var {path, args} = pwpath.splitArgs(path)
|
var {path, args} = pwpath.splitArgs(path)
|
||||||
args = pwpath.joinArgs('', args)
|
args = pwpath.joinArgs('', args)
|
||||||
// build list of existing page candidates...
|
// build list of existing page candidates...
|
||||||
//var names = await this.names()
|
var names = await this.names
|
||||||
// XXX INDEX
|
|
||||||
var names = await this.xnames
|
|
||||||
var pages = new Set(
|
var pages = new Set(
|
||||||
pwpath.names(path)
|
pwpath.names(path)
|
||||||
.map(function(name){
|
.map(function(name){
|
||||||
@ -408,7 +309,8 @@ module.BaseStore = {
|
|||||||
await this.paths()
|
await this.paths()
|
||||||
: await (this.names())[name])
|
: await (this.names())[name])
|
||||||
/*/
|
/*/
|
||||||
return [...(await this.paths())
|
//return [...(await this.paths())
|
||||||
|
return [...(await this.paths)
|
||||||
//*/
|
//*/
|
||||||
// NOTE: we are not using .filter(..) here as wee
|
// NOTE: we are not using .filter(..) here as wee
|
||||||
// need to keep parts of the path only and not
|
// need to keep parts of the path only and not
|
||||||
@ -593,8 +495,6 @@ module.BaseStore = {
|
|||||||
data,
|
data,
|
||||||
{mtime: Date.now()})
|
{mtime: Date.now()})
|
||||||
await this.__update__(path, data, mode)
|
await this.__update__(path, data, mode)
|
||||||
// XXX CACHED
|
|
||||||
this.__cache_add(path)
|
|
||||||
// XXX INDEX
|
// XXX INDEX
|
||||||
this.index('update', path)
|
this.index('update', path)
|
||||||
this.onUpdate(path)
|
this.onUpdate(path)
|
||||||
@ -609,8 +509,6 @@ module.BaseStore = {
|
|||||||
path = await this.exists(path)
|
path = await this.exists(path)
|
||||||
if(typeof(path) == 'string'){
|
if(typeof(path) == 'string'){
|
||||||
await this.__delete__(path)
|
await this.__delete__(path)
|
||||||
// XXX CACHED
|
|
||||||
this.__cache_remove(path)
|
|
||||||
// XXX INDEX
|
// XXX INDEX
|
||||||
this.index('remove', path)
|
this.index('remove', path)
|
||||||
this.onDelete(path) }
|
this.onDelete(path) }
|
||||||
@ -668,7 +566,8 @@ module.BaseStore = {
|
|||||||
// generic...
|
// generic...
|
||||||
} else {
|
} else {
|
||||||
var res = {}
|
var res = {}
|
||||||
for(var path of await this.paths()){
|
//for(var path of await this.paths()){
|
||||||
|
for(var path of await this.paths){
|
||||||
var page = await this.get(path)
|
var page = await this.get(path)
|
||||||
if(keep_funcs
|
if(keep_funcs
|
||||||
|| typeof(page) != 'function'){
|
|| typeof(page) != 'function'){
|
||||||
@ -763,46 +662,32 @@ module.MetaStore = {
|
|||||||
// their own stuff...
|
// their own stuff...
|
||||||
|
|
||||||
// XXX INDEX...
|
// XXX INDEX...
|
||||||
__xpaths_merge__: async function(data){
|
__paths_merge__: async function(data){
|
||||||
var that = this
|
var that = this
|
||||||
var stores = await Promise.iter(
|
var stores = await Promise.iter(
|
||||||
Object.entries(this.substores ?? {})
|
Object.entries(this.substores ?? {})
|
||||||
.map(function([path, store]){
|
.map(function([path, store]){
|
||||||
return store.xpaths
|
return store.paths
|
||||||
.iter()
|
.iter()
|
||||||
.map(function(s){
|
.map(function(s){
|
||||||
return pwpath.join(path, s) }) }))
|
return pwpath.join(path, s) }) }))
|
||||||
.flat()
|
.flat()
|
||||||
return object.parentCall(MetaStore.__xpaths_merge__, this, ...arguments)
|
return object.parentCall(MetaStore.__paths_merge__, this, ...arguments)
|
||||||
.iter()
|
.iter()
|
||||||
.concat(stores) },
|
.concat(stores) },
|
||||||
__xpaths_isvalid__: function(t){
|
__paths_isvalid__: function(t){
|
||||||
if(this.substores){
|
if(this.substores){
|
||||||
// match substore list...
|
// match substore list...
|
||||||
var cur = Object.keys(this.substores ?? {})
|
var cur = Object.keys(this.substores ?? {})
|
||||||
var prev = this.__xpaths_substores ?? cur ?? []
|
var prev = this.__paths_substores ?? cur ?? []
|
||||||
if(prev.length != cur.length
|
if(prev.length != cur.length
|
||||||
|| (new Set([...cur, ...prev])).size != cur.length){
|
|| (new Set([...cur, ...prev])).size != cur.length){
|
||||||
return false }
|
return false }
|
||||||
// check timestamps...
|
// check timestamps...
|
||||||
for(var {__xpaths_modified} of Object.values(this.substores ?? {})){
|
for(var {__paths_modified} of Object.values(this.substores ?? {})){
|
||||||
if(__xpaths_modified > t){
|
if(__paths_modified > t){
|
||||||
return false } } }
|
return false } } }
|
||||||
return object.parentCall(MetaStore.__xpaths_isvalid__, this, ...arguments) },
|
return object.parentCall(MetaStore.__paths_isvalid__, this, ...arguments) },
|
||||||
|
|
||||||
paths: async function(){
|
|
||||||
var that = this
|
|
||||||
var stores = await Promise.iter(
|
|
||||||
Object.entries(this.substores ?? {})
|
|
||||||
.map(function([path, store]){
|
|
||||||
return store.paths()
|
|
||||||
.iter()
|
|
||||||
.map(function(s){
|
|
||||||
return pwpath.join(path, s) }) }))
|
|
||||||
.flat()
|
|
||||||
return object.parentCall(MetaStore.paths, this, ...arguments)
|
|
||||||
.iter()
|
|
||||||
.concat(stores) },
|
|
||||||
|
|
||||||
exists: metaProxy('exists',
|
exists: metaProxy('exists',
|
||||||
//async function(path){
|
//async function(path){
|
||||||
@ -851,7 +736,7 @@ module.MetaStore = {
|
|||||||
// trim path...
|
// trim path...
|
||||||
path.slice(path.indexOf(p)+p.length),
|
path.slice(path.indexOf(p)+p.length),
|
||||||
...[...arguments].slice(1))
|
...[...arguments].slice(1))
|
||||||
this.__cache_add(path)
|
//this.__cache_add(path)
|
||||||
// XXX INDEX
|
// XXX INDEX
|
||||||
this.index('update', path)
|
this.index('update', path)
|
||||||
return this }
|
return this }
|
||||||
|
|||||||
@ -565,21 +565,6 @@ module.FileStoreRO = {
|
|||||||
.replace(/\$PWIKI/, this.__pwiki_path__) },
|
.replace(/\$PWIKI/, this.__pwiki_path__) },
|
||||||
|
|
||||||
// XXX INDEX...
|
// XXX INDEX...
|
||||||
__xpaths__: async function(){
|
|
||||||
var that = this
|
|
||||||
return new Promise(function(resolve, reject){
|
|
||||||
glob(pwpath.join(that.__path__, '**/*'))
|
|
||||||
.on('end', function(paths){
|
|
||||||
Promise.all(paths
|
|
||||||
.map(async function(path){
|
|
||||||
return await module.exists(path) ?
|
|
||||||
decode(path)
|
|
||||||
.slice(that.__path__.length)
|
|
||||||
: [] }))
|
|
||||||
.then(function(paths){
|
|
||||||
resolve(paths.flat()) }) }) }) },
|
|
||||||
// XXX do we remove the extension???
|
|
||||||
// XXX cache???
|
|
||||||
__paths__: async function(){
|
__paths__: async function(){
|
||||||
var that = this
|
var that = this
|
||||||
return new Promise(function(resolve, reject){
|
return new Promise(function(resolve, reject){
|
||||||
|
|||||||
@ -34,9 +34,6 @@ module.IndexedDBStore = {
|
|||||||
?? (this.__data = idb.createStore(this.__db__, this.__store__)) },
|
?? (this.__data = idb.createStore(this.__db__, this.__store__)) },
|
||||||
|
|
||||||
// XXX INDEX...
|
// XXX INDEX...
|
||||||
__xpaths__: function(){
|
|
||||||
return idb.keys(this.data) },
|
|
||||||
|
|
||||||
__paths__: function(){
|
__paths__: function(){
|
||||||
return idb.keys(this.data) },
|
return idb.keys(this.data) },
|
||||||
__exists__: function(path){
|
__exists__: function(path){
|
||||||
|
|||||||
@ -30,15 +30,6 @@ module.localStorageStore = {
|
|||||||
: undefined,
|
: undefined,
|
||||||
|
|
||||||
// XXX INDEX...
|
// XXX INDEX...
|
||||||
__xpaths__: function(){
|
|
||||||
var that = this
|
|
||||||
return Object.keys(this.data)
|
|
||||||
.map(function(k){
|
|
||||||
return k.startsWith(that.__prefix__) ?
|
|
||||||
k.slice((that.__prefix__ ?? '').length)
|
|
||||||
: [] })
|
|
||||||
.flat() },
|
|
||||||
|
|
||||||
__paths__: function(){
|
__paths__: function(){
|
||||||
var that = this
|
var that = this
|
||||||
return Object.keys(this.data)
|
return Object.keys(this.data)
|
||||||
|
|||||||
@ -35,14 +35,6 @@ module.PouchDBStore = {
|
|||||||
this.__data = value },
|
this.__data = value },
|
||||||
|
|
||||||
// XXX INDEX...
|
// XXX INDEX...
|
||||||
__xpaths__: async function(){
|
|
||||||
var that = this
|
|
||||||
// XXX not sure if this is a good idea...
|
|
||||||
return (await this.data.allDocs()).rows
|
|
||||||
.map(function(e){
|
|
||||||
return e.id.slice(that.__key_prefix__.length) }) },
|
|
||||||
|
|
||||||
// XXX cache???
|
|
||||||
__paths__: async function(){
|
__paths__: async function(){
|
||||||
var that = this
|
var that = this
|
||||||
// XXX not sure if this is a good idea...
|
// XXX not sure if this is a good idea...
|
||||||
|
|||||||
@ -21,9 +21,9 @@
|
|||||||
* ....i.e. in .update(..)/.delete(..) vs. .onUpdate(..)/.onDelete(..) ???
|
* ....i.e. in .update(..)/.delete(..) vs. .onUpdate(..)/.onDelete(..) ???
|
||||||
* XXX INDEX move to the new index...
|
* XXX INDEX move to the new index...
|
||||||
* - .names - DONE
|
* - .names - DONE
|
||||||
* - .paths -
|
* - .paths - DONE
|
||||||
* - events/methods -
|
* - handling - DONE
|
||||||
* - cleanup -
|
* - cleanup - DONE
|
||||||
* XXX INDEX DOC can index validation be async???
|
* XXX INDEX DOC can index validation be async???
|
||||||
* ...likely no
|
* ...likely no
|
||||||
* XXX INDEX add option to set default action (get/lazy/cached)
|
* XXX INDEX add option to set default action (get/lazy/cached)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user