Implement explicit snapshots (#16) · Level/memory-level@f832018
@@ -4,7 +4,8 @@ const {
44 AbstractLevel,
55 AbstractIterator,
66 AbstractKeyIterator,
7- AbstractValueIterator
7+ AbstractValueIterator,
8+ AbstractSnapshot
89} = require('abstract-level')
9101011const ModuleError = require('module-error')
@@ -59,7 +60,7 @@ function lte (value) {
5960class MemoryIterator extends AbstractIterator {
6061constructor (db, options) {
6162super(db, options)
62-this[kInit](db[kTree], options)
63+this[kInit](db, options)
6364}
64656566async _next () {
@@ -103,7 +104,7 @@ class MemoryIterator extends AbstractIterator {
103104class MemoryKeyIterator extends AbstractKeyIterator {
104105constructor (db, options) {
105106super(db, options)
106-this[kInit](db[kTree], options)
107+this[kInit](db, options)
107108}
108109109110async _next () {
@@ -145,7 +146,7 @@ class MemoryKeyIterator extends AbstractKeyIterator {
145146class MemoryValueIterator extends AbstractValueIterator {
146147constructor (db, options) {
147148super(db, options)
148-this[kInit](db[kTree], options)
149+this[kInit](db, options)
149150}
150151151152async _next (options) {
@@ -187,7 +188,11 @@ class MemoryValueIterator extends AbstractValueIterator {
187188}
188189189190for (const Ctor of [MemoryIterator, MemoryKeyIterator, MemoryValueIterator]) {
190-Ctor.prototype[kInit] = function (tree, options) {
191+Ctor.prototype[kInit] = function (db, options) {
192+const tree = options.snapshot != null
193+ ? options.snapshot[kTree]
194+ : db[kTree]
195+191196this[kReverse] = options.reverse
192197this[kOptions] = options
193198@@ -281,6 +286,7 @@ class MemoryLevel extends AbstractLevel {
281286282287super({
283288seek: true,
289+explicitSnapshots: true,
284290permanence: false,
285291createIfMissing: false,
286292errorIfExists: false,
@@ -305,12 +311,20 @@ class MemoryLevel extends AbstractLevel {
305311}
306312307313async _get (key, options) {
314+const tree = options.snapshot != null
315+ ? options.snapshot[kTree]
316+ : this[kTree]
317+308318// Is undefined if not found
309-return this[kTree].get(key)
319+return tree.get(key)
310320}
311321312322async _getMany (keys, options) {
313-return keys.map(key => this[kTree].get(key))
323+const tree = options.snapshot != null
324+ ? options.snapshot[kTree]
325+ : this[kTree]
326+327+return keys.map(getFromThis, tree)
314328}
315329316330async _del (key, options) {
@@ -335,7 +349,7 @@ class MemoryLevel extends AbstractLevel {
335349}
336350337351async _clear (options) {
338-if (options.limit === -1 && !Object.keys(options).some(isRangeOption)) {
352+if (options.limit === -1 && !Object.keys(options).some(isRangeOption) && !options.snapshot) {
339353// Delete everything by creating a new empty tree.
340354this[kTree] = createRBT(compare)
341355return
@@ -374,6 +388,17 @@ class MemoryLevel extends AbstractLevel {
374388_values (options) {
375389return new MemoryValueIterator(this, options)
376390}
391+392+_snapshot (options) {
393+return new MemorySnapshot(this[kTree], options)
394+}
395+}
396+397+class MemorySnapshot extends AbstractSnapshot {
398+constructor (tree, options) {
399+super(options)
400+this[kTree] = tree
401+}
377402}
378403379404exports.MemoryLevel = MemoryLevel
@@ -391,6 +416,10 @@ if (typeof process !== 'undefined' && !process.browser && typeof global !== 'und
391416breathe = async function () {}
392417}
393418419+function getFromThis (key) {
420+return this.get(key)
421+}
422+394423function isRangeOption (k) {
395424return rangeOptions.has(k)
396425}