From 8efa812fd2a0d964dc8389cae07de640dff0ca6f Mon Sep 17 00:00:00 2001 From: Carson Farmer Date: Fri, 20 Dec 2019 00:36:43 -0800 Subject: [PATCH] perf: optimize prefix search (#25) * feat: optimise prefix search Signed-off-by: Carson Farmer * style: fix linter issue Signed-off-by: Carson Farmer * chore: remove avoid reaching into internal db Signed-off-by: Carson Farmer --- src/index.js | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/index.js b/src/index.js index 70a397f..a3760f7 100644 --- a/src/index.js +++ b/src/index.js @@ -105,12 +105,23 @@ class LevelDatastore { values = !q.keysOnly } + const opts = { + keys: true, + values: values, + keyAsBuffer: true + } + + // Let the db do the prefix matching + if (q.prefix != null) { + const prefix = q.prefix.toString() + // Match keys greater than or equal to `prefix` and + opts.gte = prefix + // less than `prefix` + \xFF (hex escape sequence) + opts.lt = prefix + '\xFF' + } + let it = levelIteratorToIterator( - this.db.db.iterator({ - keys: true, - values: values, - keyAsBuffer: true - }) + this.db.iterator(opts) ) it = map(it, ({ key, value }) => { @@ -121,10 +132,6 @@ class LevelDatastore { return res }) - if (q.prefix != null) { - it = filter(it, e => e.key.toString().startsWith(q.prefix)) - } - if (Array.isArray(q.filters)) { it = q.filters.reduce((it, f) => filter(it, f), it) }