diff --git a/lib/core.js b/lib/core.js index 91620f8d..67def666 100644 --- a/lib/core.js +++ b/lib/core.js @@ -413,7 +413,7 @@ module.exports = class Core { await state.flushWriteBatch(storage) - if (dependency) state.refreshDependencies(dependency) + if (dependency) state.storage.updateDependencies(dependency.length) } if (this.header.hints.contiguousLength === treeLength) { diff --git a/lib/session-state.js b/lib/session-state.js index 06caf9a5..b4adab87 100644 --- a/lib/session-state.js +++ b/lib/session-state.js @@ -129,24 +129,6 @@ module.exports = class SessionState { return dependency } - refreshDependencies (dependency) { - assert(!this.isDefault(), 'Default state should have no dependencies') - - const deps = this.storage.dependencies - - for (let i = deps.length - 1; i >= 0; i--) { - if (deps[i].data === dependency.data) { - const updated = deps.slice(0, i) - updated.push(dependency) - - this.storage.dependencies = updated - return - } - } - - throw new Error('Dependency not found') - } - _clearActiveBatch (err) { if (!this._activeBatch) return this._activeBatch.destroy() @@ -271,7 +253,7 @@ module.exports = class SessionState { await this.flushWriteBatch(storage) - if (dependency) this.refreshDependencies(dependency) + if (dependency) this.storage.updateDependencies(dependency.length) this.tree.onupdate(treeUpdate) this.ontruncate(tree, tree.length, batch.treeLength) @@ -292,7 +274,7 @@ module.exports = class SessionState { await this.flushWriteBatch(storage) - if (dependency) this.refreshDependencies(dependency) + if (dependency) this.storage.updateDependencies(dependency.length) this.tree.onupdate(treeUpdate) this.ontruncate(tree, batch.ancestors, batch.treeLength) @@ -341,7 +323,7 @@ module.exports = class SessionState { await this.flushWriteBatch(storage) - if (dependency) this.refreshDependencies(dependency) + if (dependency) this.storage.updateDependencies(dependency.length) if (this.isDefault()) { const length = end - start @@ -635,18 +617,11 @@ async function storeBitfieldRange (storage, writer, from, to, value) { } function updateDependency (state, length) { - const dependencies = state.storage.dependencies - if (!dependencies.length) return null // skip default state and overlays of default - - let target = dependencies[dependencies.length - 1] - - for (const dep of dependencies) { - if (dep.length < length) break - target = dep - } + const dependency = state.storage.findDependency(length) + if (dependency === null) return null // skip default state and overlays of default return { - data: target.data, + data: dependency.data, length } } diff --git a/test/snapshots.js b/test/snapshots.js index 12bf1003..05b239e8 100644 --- a/test/snapshots.js +++ b/test/snapshots.js @@ -147,3 +147,36 @@ test('snapshots are consistent', async function (t) { await snapshot.close() }) + +test('snapshot over named batch persists after truncate', async function (t) { + t.plan(8) + + const core = await create(t) + + await core.append('block #0.0') + await core.append('block #1.0') + await core.append('block #2.0') + + const session = core.session({ name: 'session' }) + const snapshot = session.snapshot({ valueEncoding: 'utf-8' }) + + t.is(snapshot.length, 3) + + t.is(await snapshot.get(1), 'block #1.0') + + await core.truncate(1) + await core.append('block #1.1') + + t.is(core.fork, 1, 'clone updated') + t.is(core.length, 2, 'core updated') + + // t.is(snapshot.fork, 0, 'snapshot remains') + t.is(snapshot.length, 3, 'snapshot remains') + + t.is(await snapshot.get(0), 'block #0.0') + t.is(await snapshot.get(1), 'block #1.0') + t.is(await snapshot.get(2), 'block #2.0') + + await core.close() + await snapshot.close() +})