hypercore-storage 0.0.28 → 0.0.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -471,6 +471,18 @@ class HypercoreStorage {
471
471
  }
472
472
  }
473
473
 
474
+ async registerOverlay (head) {
475
+ const storage = new MemoryOverlay(this)
476
+ const batch = storage.createWriteBatch()
477
+
478
+ batch.setDataDependency({ data: this.dataPointer, length: head.length })
479
+ if (head.rootHash) batch.setCoreHead(head) // if no root hash its the empty core - no head yet
480
+
481
+ await batch.flush()
482
+
483
+ return storage
484
+ }
485
+
474
486
  createMemoryOverlay () {
475
487
  return new MemoryOverlay(this)
476
488
  }
@@ -115,6 +115,9 @@ class MemoryOverlay {
115
115
  this.bitfields = null
116
116
 
117
117
  this.snapshotted = false
118
+ this.snapshotShared = null
119
+ this.activeSnapshots = 0
120
+ this.copyOnWrite = false
118
121
  }
119
122
 
120
123
  async registerBatch (name, length, overwrite) {
@@ -122,29 +125,46 @@ class MemoryOverlay {
122
125
  }
123
126
 
124
127
  snapshot () {
128
+ if (this.snapshotShared !== null) return this.snapshotShared.snapshot()
129
+
130
+ this.activeSnapshots++
131
+ this.copyOnWrite = true
132
+
125
133
  const snap = new MemoryOverlay(this.storage.snapshot())
126
- snap.merge(this)
127
134
 
128
- if (this.userData !== null) snap.userData = new Map()
129
- if (this.blocks !== null) snap.blocks = new TipList()
130
- if (this.treeNodes !== null) snap.treeNodes = new Map()
131
- if (this.bitfields !== null) snap.bitfields = new TipList()
135
+ snap.snapshotted = true
136
+ snap.snapshotShared = this
132
137
 
133
- // clone state
134
- if (this.head !== null) snap.head = Object.assign(this.head)
135
- if (this.auth !== null) snap.auth = Object.assign(this.auth)
136
- if (this.localKeyPair !== null) snap.localKeyPair = Object.assign(this.localKeyPair)
137
- if (this.encryptionKey !== null) snap.encryptionKey = Object.assign(this.encryptionKey)
138
- if (this.dataDependency !== null) snap.dataDependency = Object.assign(this.dataDependency)
139
- if (this.dataInfo !== null) snap.dataInfo = Object.assign(this.dataInfo)
140
- if (this.userData !== null) snap.userData = mergeMap(snap.userData, this.userData)
141
- if (this.blocks !== null) snap.blocks = mergeTip(snap.blocks, this.blocks)
142
- if (this.treeNodes !== null) snap.treeNodes = mergeMap(snap.treeNodes, this.treeNodes)
143
- if (this.bitfields !== null) snap.bitfields = mergeTip(snap.bitfields, this.bitfields)
138
+ if (this.head !== null) snap.head = this.head
139
+ if (this.auth !== null) snap.auth = this.auth
140
+ if (this.localKeyPair !== null) snap.localKeyPair = this.localKeyPair
141
+ if (this.encryptionKey !== null) snap.encryptionKey = this.encryptionKey
142
+ if (this.dataDependency !== null) snap.dataDependency = this.dataDependency
143
+ if (this.dataInfo !== null) snap.dataInfo = this.dataInfo
144
+ if (this.userData !== null) snap.userData = this.userData
145
+ if (this.blocks !== null) snap.blocks = this.blocks
146
+ if (this.treeNodes !== null) snap.treeNodes = this.treeNodes
147
+ if (this.bitfields !== null) snap.bitfields = this.bitfields
144
148
 
145
149
  return snap
146
150
  }
147
151
 
152
+ _copy () {
153
+ this.copyOnWrite = false
154
+
155
+ // clone state
156
+ if (this.head !== null) this.head = Object.assign(this.head)
157
+ if (this.auth !== null) this.auth = Object.assign(this.auth)
158
+ if (this.localKeyPair !== null) this.localKeyPair = Object.assign(this.localKeyPair)
159
+ if (this.encryptionKey !== null) this.encryptionKey = Object.assign(this.encryptionKey)
160
+ if (this.dataDependency !== null) this.dataDependency = Object.assign(this.dataDependency)
161
+ if (this.dataInfo !== null) this.dataInfo = Object.assign(this.dataInfo)
162
+ if (this.userData !== null) this.userData = mergeMap(new Map(), this.userData)
163
+ if (this.blocks !== null) this.blocks = mergeTip(new TipList(), this.blocks)
164
+ if (this.treeNodes !== null) this.treeNodes = mergeMap(new Map(), this.treeNodes)
165
+ if (this.bitfields !== null) this.bitfields = mergeTip(new TipList(), this.bitfields)
166
+ }
167
+
148
168
  get dependencies () {
149
169
  return this.storage.dependencies
150
170
  }
@@ -159,6 +179,7 @@ class MemoryOverlay {
159
179
  }
160
180
 
161
181
  createWriteBatch () {
182
+ if (this.copyOnWrite) this._copy()
162
183
  return new MemoryOverlayWriteBatch(this)
163
184
  }
164
185
 
@@ -175,6 +196,7 @@ class MemoryOverlay {
175
196
  }
176
197
 
177
198
  createBitfieldPageStream (opts) {
199
+ if (this.bitfields === null) return createBitfieldPageStream(this.storage)
178
200
  return new OverlayStream(this.bitfields, this.storage, createBitfieldPageStream, opts)
179
201
  }
180
202
 
@@ -193,7 +215,12 @@ class MemoryOverlay {
193
215
  return (page && (!disk || index > disk.index)) ? { index, page } : disk
194
216
  }
195
217
 
196
- destroy () {}
218
+ destroy () {
219
+ if (this.snapshotted) this.storage.destroy()
220
+ if (this.snapshotShared === null) return
221
+ if (--this.snapshotShared.activeSnapshots === 0) this.snapshotShared.copyOnWrite = false
222
+ this.snapshotShared = null
223
+ }
197
224
 
198
225
  merge (overlay) {
199
226
  if (overlay.head !== null) this.head = overlay.head
package/lib/messages.js CHANGED
@@ -25,13 +25,13 @@ exports.KeyPair = {
25
25
 
26
26
  exports.StorageInfo = {
27
27
  preencode (state, m) {
28
- c.uint.preencode(state, m.version)
28
+ c.uint.preencode(state, 0) // version
29
29
  c.uint.preencode(state, 0) // flags, reserved
30
30
  c.uint.preencode(state, m.free)
31
31
  c.uint.preencode(state, m.total)
32
32
  },
33
33
  encode (state, m) {
34
- c.uint.encode(state, m.version)
34
+ c.uint.encode(state, 0) // version
35
35
  c.uint.encode(state, 0) // flags, reserved
36
36
  c.uint.encode(state, m.free)
37
37
  c.uint.encode(state, m.total)
package/lib/tip-list.js CHANGED
@@ -78,7 +78,7 @@ module.exports = class TipList {
78
78
  }
79
79
 
80
80
  merge (tip) {
81
- const invalidDeletion = tip.removed && tip.end() !== -1 && tip.end() < this.end()
81
+ const invalidDeletion = tip.removed > 0 && tip.end() !== -1 && tip.end() < this.end()
82
82
  const invalidTip = (tip.removed !== -1 && tip.end() < this.offset) || this.end() < tip.offset
83
83
 
84
84
  if (invalidTip || invalidDeletion) throw ASSERTION('Cannot merge tip list')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hypercore-storage",
3
- "version": "0.0.28",
3
+ "version": "0.0.30",
4
4
  "main": "index.js",
5
5
  "files": [
6
6
  "index.js",