hyperbee2 0.0.1 → 1.0.0
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 +6 -6
- package/lib/context.js +17 -11
- package/lib/write.js +16 -23
- package/package.json +1 -1
- package/spec/hyperschema/index.js +49 -14
- package/spec/hyperschema/schema.json +30 -1
package/index.js
CHANGED
|
@@ -12,7 +12,7 @@ class Hyperbee {
|
|
|
12
12
|
const {
|
|
13
13
|
key = null,
|
|
14
14
|
core = key ? store.get(key) : store.get({ key, name: 'bee' }),
|
|
15
|
-
context = new CoreContext(store, core),
|
|
15
|
+
context = new CoreContext(store, core, core),
|
|
16
16
|
maxCacheSize = 4096,
|
|
17
17
|
cache = new NodeCache(maxCacheSize),
|
|
18
18
|
root = null,
|
|
@@ -64,9 +64,9 @@ class Hyperbee {
|
|
|
64
64
|
return this.store.replicate(...opts)
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
_makeView(root, writable, unbatch) {
|
|
67
|
+
_makeView(context, root, writable, unbatch) {
|
|
68
68
|
return new Hyperbee(this.store, {
|
|
69
|
-
context
|
|
69
|
+
context,
|
|
70
70
|
cache: this.cache,
|
|
71
71
|
root,
|
|
72
72
|
view: true,
|
|
@@ -78,15 +78,15 @@ class Hyperbee {
|
|
|
78
78
|
checkout({ length = this.core.length, key = null, writable = false } = {}) {
|
|
79
79
|
const context = key ? this.context.getContextByKey(key) : this.context
|
|
80
80
|
const root = length === 0 ? EMPTY : new TreeNodePointer(context, 0, length - 1, 0, false, null)
|
|
81
|
-
return this._makeView(root, writable, 0)
|
|
81
|
+
return this._makeView(context, root, writable, 0)
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
snapshot() {
|
|
85
|
-
return this._makeView(this.root, false, 0)
|
|
85
|
+
return this._makeView(this.context, this.root, false, 0)
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
undo(n) {
|
|
89
|
-
return this._makeView(this.root, true, n)
|
|
89
|
+
return this._makeView(this.context, this.root, true, n)
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
write(opts) {
|
package/lib/context.js
CHANGED
|
@@ -2,8 +2,9 @@ const b4a = require('b4a')
|
|
|
2
2
|
const { decodeBlock } = require('./encoding.js')
|
|
3
3
|
|
|
4
4
|
class CoreContext {
|
|
5
|
-
constructor(store, core, other = new Map()) {
|
|
5
|
+
constructor(store, local, core, other = new Map()) {
|
|
6
6
|
this.store = store
|
|
7
|
+
this.local = local
|
|
7
8
|
this.core = core
|
|
8
9
|
this.other = other
|
|
9
10
|
this.length = 0
|
|
@@ -48,14 +49,14 @@ class CoreContext {
|
|
|
48
49
|
|
|
49
50
|
// TODO: prop use a map...
|
|
50
51
|
for (let i = 0; i < this.cores.length; i++) {
|
|
51
|
-
const k = this.cores[i]
|
|
52
|
+
const k = this.cores[i].key
|
|
52
53
|
if (b4a.equals(k, key)) {
|
|
53
54
|
return i + 1
|
|
54
55
|
}
|
|
55
56
|
}
|
|
56
57
|
|
|
57
58
|
this.changed = true
|
|
58
|
-
this.cores.push(key)
|
|
59
|
+
this.cores.push({ key, fork: 0, length: 0, treeHash: null })
|
|
59
60
|
return this.cores.length
|
|
60
61
|
}
|
|
61
62
|
|
|
@@ -65,7 +66,7 @@ class CoreContext {
|
|
|
65
66
|
if (b4a.equals(key, this.core.key)) return 0
|
|
66
67
|
|
|
67
68
|
for (let i = 0; i < this.cores.length; i++) {
|
|
68
|
-
const k = this.cores[i]
|
|
69
|
+
const k = this.cores[i].key
|
|
69
70
|
if (b4a.equals(k, key)) {
|
|
70
71
|
return i + 1
|
|
71
72
|
}
|
|
@@ -74,22 +75,23 @@ class CoreContext {
|
|
|
74
75
|
await this.update(activeRequests)
|
|
75
76
|
|
|
76
77
|
for (let i = 0; i < this.cores.length; i++) {
|
|
77
|
-
const k = this.cores[i]
|
|
78
|
+
const k = this.cores[i].key
|
|
78
79
|
if (b4a.equals(k, key)) {
|
|
79
80
|
return i + 1
|
|
80
81
|
}
|
|
81
82
|
}
|
|
82
83
|
|
|
83
84
|
this.changed = true
|
|
84
|
-
this.cores.push(key)
|
|
85
|
+
this.cores.push({ key, fork: 0, length: 0, treeHash: null })
|
|
85
86
|
return this.cores.length
|
|
86
87
|
}
|
|
87
88
|
|
|
88
89
|
getCore(index) {
|
|
89
90
|
if (index === 0) return this.core
|
|
90
91
|
if (index > this.cores.length) throw new Error('Bad core index: ' + index)
|
|
91
|
-
if (this.opened[index - 1] === null)
|
|
92
|
-
this.opened[index - 1] = this.store.get(this.cores[index - 1])
|
|
92
|
+
if (this.opened[index - 1] === null) {
|
|
93
|
+
this.opened[index - 1] = this.store.get(this.cores[index - 1].key)
|
|
94
|
+
}
|
|
93
95
|
return this.opened[index - 1]
|
|
94
96
|
}
|
|
95
97
|
|
|
@@ -101,13 +103,17 @@ class CoreContext {
|
|
|
101
103
|
return block
|
|
102
104
|
}
|
|
103
105
|
|
|
106
|
+
getLocalContext() {
|
|
107
|
+
return this.getContextByKey(this.local.key)
|
|
108
|
+
}
|
|
109
|
+
|
|
104
110
|
getContextByKey(key) {
|
|
105
111
|
if (b4a.equals(key, this.core.key)) return this
|
|
106
112
|
|
|
107
113
|
const hex = b4a.toString(key, 'hex')
|
|
108
114
|
if (this.other.has(hex)) return this.other.get(hex)
|
|
109
115
|
|
|
110
|
-
const ctx = new CoreContext(this.store, this.store.get(key))
|
|
116
|
+
const ctx = new CoreContext(this.store, this.local, this.store.get(key))
|
|
111
117
|
this.other.set(hex, ctx)
|
|
112
118
|
return ctx
|
|
113
119
|
}
|
|
@@ -117,11 +123,11 @@ class CoreContext {
|
|
|
117
123
|
if (core > this.cores.length) await this.update(activeRequests)
|
|
118
124
|
if (core > this.cores.length) throw new Error('Bad core index: ' + core)
|
|
119
125
|
|
|
120
|
-
const hex = b4a.toString(this.cores[core - 1], 'hex')
|
|
126
|
+
const hex = b4a.toString(this.cores[core - 1].key, 'hex')
|
|
121
127
|
if (this.other.has(hex)) return this.other.get(hex)
|
|
122
128
|
|
|
123
129
|
const hc = this.getCore(core)
|
|
124
|
-
const ctx = new CoreContext(this.store, hc)
|
|
130
|
+
const ctx = new CoreContext(this.store, this.local, hc)
|
|
125
131
|
this.other.set(hex, ctx)
|
|
126
132
|
return ctx
|
|
127
133
|
}
|
package/lib/write.js
CHANGED
|
@@ -288,8 +288,9 @@ module.exports = class WriteBatch {
|
|
|
288
288
|
const update = { node: [], keys: [] }
|
|
289
289
|
const batch = [update]
|
|
290
290
|
const stack = [{ update, node: this.root }]
|
|
291
|
+
const context = this.tree.context.getLocalContext()
|
|
291
292
|
|
|
292
|
-
await
|
|
293
|
+
await context.update(this.tree.activeRequests)
|
|
293
294
|
|
|
294
295
|
while (stack.length > 0) {
|
|
295
296
|
const { update, node } = stack.pop()
|
|
@@ -301,12 +302,8 @@ module.exports = class WriteBatch {
|
|
|
301
302
|
const k = node.value.keys[i]
|
|
302
303
|
|
|
303
304
|
if (!k.changed) {
|
|
304
|
-
k.core = await this.tree.
|
|
305
|
-
|
|
306
|
-
k.core,
|
|
307
|
-
this.tree.activeRequests
|
|
308
|
-
)
|
|
309
|
-
k.context = this.tree.context
|
|
305
|
+
k.core = await context.getCoreOffset(k.context, k.core, this.tree.activeRequests)
|
|
306
|
+
k.context = context
|
|
310
307
|
continue
|
|
311
308
|
}
|
|
312
309
|
|
|
@@ -320,12 +317,8 @@ module.exports = class WriteBatch {
|
|
|
320
317
|
const n = node.value.children[i]
|
|
321
318
|
|
|
322
319
|
if (!n.changed) {
|
|
323
|
-
n.core = await this.tree.
|
|
324
|
-
|
|
325
|
-
n.core,
|
|
326
|
-
this.tree.activeRequests
|
|
327
|
-
)
|
|
328
|
-
n.context = this.tree.context
|
|
320
|
+
n.core = await context.getCoreOffset(n.context, n.core, this.tree.activeRequests)
|
|
321
|
+
n.context = context
|
|
329
322
|
continue
|
|
330
323
|
}
|
|
331
324
|
|
|
@@ -340,7 +333,7 @@ module.exports = class WriteBatch {
|
|
|
340
333
|
}
|
|
341
334
|
}
|
|
342
335
|
|
|
343
|
-
const length =
|
|
336
|
+
const length = context.core.length
|
|
344
337
|
const blocks = new Array(batch.length)
|
|
345
338
|
|
|
346
339
|
for (let i = 0; i < batch.length; i++) {
|
|
@@ -361,7 +354,7 @@ module.exports = class WriteBatch {
|
|
|
361
354
|
if (block.data === null) block.data = []
|
|
362
355
|
|
|
363
356
|
k.core = 0
|
|
364
|
-
k.context =
|
|
357
|
+
k.context = context
|
|
365
358
|
k.seq = seq
|
|
366
359
|
k.offset = block.data.length
|
|
367
360
|
block.data.push(k)
|
|
@@ -371,7 +364,7 @@ module.exports = class WriteBatch {
|
|
|
371
364
|
if (block.tree === null) block.tree = []
|
|
372
365
|
|
|
373
366
|
n.core = 0
|
|
374
|
-
n.context =
|
|
367
|
+
n.context = context
|
|
375
368
|
n.seq = seq
|
|
376
369
|
n.offset = block.tree.length
|
|
377
370
|
block.tree.push(n.value)
|
|
@@ -384,20 +377,20 @@ module.exports = class WriteBatch {
|
|
|
384
377
|
|
|
385
378
|
if (blocks.length > 0 && this.length > 0) {
|
|
386
379
|
const core = this.key
|
|
387
|
-
? await
|
|
380
|
+
? await context.getCoreOffsetByKey(this.key, this.tree.activeRequests)
|
|
388
381
|
: 0
|
|
389
382
|
blocks[blocks.length - 1].previous = { core, seq: this.length - 1 }
|
|
390
383
|
}
|
|
391
384
|
|
|
392
385
|
// TODO: make this transaction safe
|
|
393
|
-
if (
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
blocks[blocks.length - 1].cores =
|
|
386
|
+
if (context.changed) {
|
|
387
|
+
context.changed = false
|
|
388
|
+
context.checkpoint = context.core.length + blocks.length
|
|
389
|
+
blocks[blocks.length - 1].cores = context.cores
|
|
397
390
|
}
|
|
398
391
|
|
|
399
392
|
for (let i = 0; i < blocks.length; i++) {
|
|
400
|
-
blocks[i].checkpoint =
|
|
393
|
+
blocks[i].checkpoint = context.checkpoint
|
|
401
394
|
buffers[i] = c.encode(Block, blocks[i])
|
|
402
395
|
}
|
|
403
396
|
|
|
@@ -405,7 +398,7 @@ module.exports = class WriteBatch {
|
|
|
405
398
|
throw new Error('Write batch is closed')
|
|
406
399
|
}
|
|
407
400
|
|
|
408
|
-
await
|
|
401
|
+
await context.core.append(buffers)
|
|
409
402
|
|
|
410
403
|
for (let i = 0; i < batch.length; i++) {
|
|
411
404
|
const update = batch[i]
|
package/package.json
CHANGED
|
@@ -125,15 +125,48 @@ const encoding4 = {
|
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
+
// @bee/core
|
|
129
|
+
const encoding5 = {
|
|
130
|
+
preencode(state, m) {
|
|
131
|
+
c.fixed32.preencode(state, m.key)
|
|
132
|
+
state.end++ // max flag is 4 so always one byte
|
|
133
|
+
|
|
134
|
+
if (m.fork) c.uint.preencode(state, m.fork)
|
|
135
|
+
if (m.length) c.uint.preencode(state, m.length)
|
|
136
|
+
if (m.treeHash) c.fixed32.preencode(state, m.treeHash)
|
|
137
|
+
},
|
|
138
|
+
encode(state, m) {
|
|
139
|
+
const flags = (m.fork ? 1 : 0) | (m.length ? 2 : 0) | (m.treeHash ? 4 : 0)
|
|
140
|
+
|
|
141
|
+
c.fixed32.encode(state, m.key)
|
|
142
|
+
c.uint.encode(state, flags)
|
|
143
|
+
|
|
144
|
+
if (m.fork) c.uint.encode(state, m.fork)
|
|
145
|
+
if (m.length) c.uint.encode(state, m.length)
|
|
146
|
+
if (m.treeHash) c.fixed32.encode(state, m.treeHash)
|
|
147
|
+
},
|
|
148
|
+
decode(state) {
|
|
149
|
+
const r0 = c.fixed32.decode(state)
|
|
150
|
+
const flags = c.uint.decode(state)
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
key: r0,
|
|
154
|
+
fork: (flags & 1) !== 0 ? c.uint.decode(state) : 0,
|
|
155
|
+
length: (flags & 2) !== 0 ? c.uint.decode(state) : 0,
|
|
156
|
+
treeHash: (flags & 4) !== 0 ? c.fixed32.decode(state) : null
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
128
161
|
// @bee/block.tree
|
|
129
|
-
const
|
|
162
|
+
const encoding6_4 = c.array(encoding3)
|
|
130
163
|
// @bee/block.data
|
|
131
|
-
const
|
|
164
|
+
const encoding6_5 = c.array(encoding4)
|
|
132
165
|
// @bee/block.cores
|
|
133
|
-
const
|
|
166
|
+
const encoding6_6 = c.array(encoding5)
|
|
134
167
|
|
|
135
168
|
// @bee/block
|
|
136
|
-
const
|
|
169
|
+
const encoding6 = {
|
|
137
170
|
preencode(state, m) {
|
|
138
171
|
c.uint.preencode(state, m.type)
|
|
139
172
|
c.uint.preencode(state, m.checkpoint)
|
|
@@ -141,9 +174,9 @@ const encoding5 = {
|
|
|
141
174
|
state.end++ // max flag is 8 so always one byte
|
|
142
175
|
|
|
143
176
|
if (m.previous) encoding1.preencode(state, m.previous)
|
|
144
|
-
if (m.tree)
|
|
145
|
-
if (m.data)
|
|
146
|
-
if (m.cores)
|
|
177
|
+
if (m.tree) encoding6_4.preencode(state, m.tree)
|
|
178
|
+
if (m.data) encoding6_5.preencode(state, m.data)
|
|
179
|
+
if (m.cores) encoding6_6.preencode(state, m.cores)
|
|
147
180
|
},
|
|
148
181
|
encode(state, m) {
|
|
149
182
|
const flags = (m.previous ? 1 : 0) | (m.tree ? 2 : 0) | (m.data ? 4 : 0) | (m.cores ? 8 : 0)
|
|
@@ -154,9 +187,9 @@ const encoding5 = {
|
|
|
154
187
|
c.uint.encode(state, flags)
|
|
155
188
|
|
|
156
189
|
if (m.previous) encoding1.encode(state, m.previous)
|
|
157
|
-
if (m.tree)
|
|
158
|
-
if (m.data)
|
|
159
|
-
if (m.cores)
|
|
190
|
+
if (m.tree) encoding6_4.encode(state, m.tree)
|
|
191
|
+
if (m.data) encoding6_5.encode(state, m.data)
|
|
192
|
+
if (m.cores) encoding6_6.encode(state, m.cores)
|
|
160
193
|
},
|
|
161
194
|
decode(state) {
|
|
162
195
|
const r0 = c.uint.decode(state)
|
|
@@ -169,9 +202,9 @@ const encoding5 = {
|
|
|
169
202
|
checkpoint: r1,
|
|
170
203
|
batch: r2,
|
|
171
204
|
previous: (flags & 1) !== 0 ? encoding1.decode(state) : null,
|
|
172
|
-
tree: (flags & 2) !== 0 ?
|
|
173
|
-
data: (flags & 4) !== 0 ?
|
|
174
|
-
cores: (flags & 8) !== 0 ?
|
|
205
|
+
tree: (flags & 2) !== 0 ? encoding6_4.decode(state) : null,
|
|
206
|
+
data: (flags & 4) !== 0 ? encoding6_5.decode(state) : null,
|
|
207
|
+
cores: (flags & 8) !== 0 ? encoding6_6.decode(state) : null
|
|
175
208
|
}
|
|
176
209
|
}
|
|
177
210
|
}
|
|
@@ -209,8 +242,10 @@ function getEncoding(name) {
|
|
|
209
242
|
return encoding3
|
|
210
243
|
case '@bee/data':
|
|
211
244
|
return encoding4
|
|
212
|
-
case '@bee/
|
|
245
|
+
case '@bee/core':
|
|
213
246
|
return encoding5
|
|
247
|
+
case '@bee/block':
|
|
248
|
+
return encoding6
|
|
214
249
|
default:
|
|
215
250
|
throw new Error('Encoder not found ' + name)
|
|
216
251
|
}
|
|
@@ -109,6 +109,35 @@
|
|
|
109
109
|
}
|
|
110
110
|
]
|
|
111
111
|
},
|
|
112
|
+
{
|
|
113
|
+
"name": "core",
|
|
114
|
+
"namespace": "bee",
|
|
115
|
+
"compact": true,
|
|
116
|
+
"flagsPosition": 1,
|
|
117
|
+
"fields": [
|
|
118
|
+
{
|
|
119
|
+
"name": "key",
|
|
120
|
+
"required": true,
|
|
121
|
+
"type": "fixed32",
|
|
122
|
+
"version": 1
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"name": "fork",
|
|
126
|
+
"type": "uint",
|
|
127
|
+
"version": 1
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"name": "length",
|
|
131
|
+
"type": "uint",
|
|
132
|
+
"version": 1
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"name": "treeHash",
|
|
136
|
+
"type": "fixed32",
|
|
137
|
+
"version": 1
|
|
138
|
+
}
|
|
139
|
+
]
|
|
140
|
+
},
|
|
112
141
|
{
|
|
113
142
|
"name": "block",
|
|
114
143
|
"namespace": "bee",
|
|
@@ -153,7 +182,7 @@
|
|
|
153
182
|
{
|
|
154
183
|
"name": "cores",
|
|
155
184
|
"array": true,
|
|
156
|
-
"type": "
|
|
185
|
+
"type": "@bee/core",
|
|
157
186
|
"version": 1
|
|
158
187
|
}
|
|
159
188
|
]
|