@@ -9,9 +9,8 @@ const { BAD_ARGUMENT, STORAGE_EMPTY, STORAGE_CONFLICT, INVALID_SIGNATURE } = req
9
9
const m = require ( './messages' )
10
10
11
11
module . exports = class Core {
12
- constructor ( header , crypto , oplog , tree , blocks , bitfield , auth , legacy , onupdate , oncontigupdate ) {
12
+ constructor ( header , crypto , oplog , tree , blocks , bitfield , auth , legacy , onupdate ) {
13
13
this . onupdate = onupdate
14
- this . oncontigupdate = oncontigupdate
15
14
this . header = header
16
15
this . crypto = crypto
17
16
this . oplog = oplog
@@ -27,8 +26,6 @@ module.exports = class Core {
27
26
this . _verifiesFlushed = null
28
27
this . _mutex = new Mutex ( )
29
28
this . _legacy = legacy
30
-
31
- this . _updateContiguousLength ( header . contiguousLength )
32
29
}
33
30
34
31
static async open ( storage , opts = { } ) {
@@ -134,6 +131,11 @@ module.exports = class Core {
134
131
await bitfield . clear ( )
135
132
}
136
133
134
+ // compat from earlier version that do not store contig length
135
+ if ( header . contiguousLength === 0 ) {
136
+ while ( bitfield . get ( header . contiguousLength ) ) header . contiguousLength ++
137
+ }
138
+
137
139
const auth = opts . auth || this . createAuth ( crypto , header . signer )
138
140
139
141
for ( const e of entries ) {
@@ -149,6 +151,7 @@ module.exports = class Core {
149
151
150
152
if ( e . bitfield ) {
151
153
bitfield . setRange ( e . bitfield . start , e . bitfield . length , ! e . bitfield . drop )
154
+ updateContig ( header , e . bitfield , bitfield )
152
155
}
153
156
154
157
if ( e . treeUpgrade ) {
@@ -165,7 +168,7 @@ module.exports = class Core {
165
168
}
166
169
}
167
170
168
- return new this ( header , crypto , oplog , tree , blocks , bitfield , auth , ! ! opts . legacy , opts . onupdate || noop , opts . oncontigupdate || noop )
171
+ return new this ( header , crypto , oplog , tree , blocks , bitfield , auth , ! ! opts . legacy , opts . onupdate || noop )
169
172
}
170
173
171
174
_shouldFlush ( ) {
@@ -196,17 +199,6 @@ module.exports = class Core {
196
199
await this . blocks . put ( index , value , byteOffset )
197
200
}
198
201
199
- _updateContiguousLength ( index , length = 0 ) {
200
- if ( index === this . header . contiguousLength ) {
201
- let i = this . header . contiguousLength + length
202
-
203
- while ( this . bitfield . get ( i ) ) i ++
204
-
205
- this . header . contiguousLength = i
206
- this . oncontigupdate ( )
207
- }
208
- }
209
-
210
202
async userData ( key , value ) {
211
203
// TODO: each oplog append can set user data, so we should have a way
212
204
// to just hitch a ride on one of the other ongoing appends?
@@ -286,12 +278,12 @@ module.exports = class Core {
286
278
this . bitfield . setRange ( batch . ancestors , batch . length - batch . ancestors , true )
287
279
batch . commit ( )
288
280
289
- this . header . contiguousLength = batch . length
290
- this . oncontigupdate ( )
291
281
this . header . tree . length = batch . length
292
282
this . header . tree . rootHash = hash
293
283
this . header . tree . signature = batch . signature
294
- this . onupdate ( 0b01 , entry . bitfield , null , null )
284
+
285
+ const status = 0b0001 | updateContig ( this . header , entry . bitfield , this . bitfield )
286
+ this . onupdate ( status , entry . bitfield , null , null )
295
287
296
288
if ( this . _shouldFlush ( ) ) await this . _flushOplog ( )
297
289
@@ -329,9 +321,11 @@ module.exports = class Core {
329
321
330
322
await this . oplog . append ( [ entry ] , false )
331
323
324
+ let status = 0b0001
325
+
332
326
if ( bitfield ) {
333
327
this . bitfield . set ( bitfield . start , true )
334
- this . _updateContiguousLength ( bitfield . start , bitfield . length )
328
+ status |= updateContig ( this . header , bitfield , this . bitfield )
335
329
}
336
330
337
331
batch . commit ( )
@@ -340,7 +334,8 @@ module.exports = class Core {
340
334
this . header . tree . length = batch . length
341
335
this . header . tree . rootHash = batch . rootHash
342
336
this . header . tree . signature = batch . signature
343
- this . onupdate ( 0b01 , bitfield , value , from )
337
+
338
+ this . onupdate ( status , bitfield , value , from )
344
339
345
340
if ( this . _shouldFlush ( ) ) await this . _flushOplog ( )
346
341
} finally {
@@ -387,14 +382,16 @@ module.exports = class Core {
387
382
continue
388
383
}
389
384
385
+ let status = 0
386
+
390
387
if ( bitfield ) {
391
388
this . bitfield . set ( bitfield . start , true )
392
- this . _updateContiguousLength ( bitfield . start , bitfield . length )
389
+ status = updateContig ( this . header , bitfield , this . bitfield )
393
390
}
394
391
395
392
batch . commit ( )
396
393
397
- this . onupdate ( 0 , bitfield , value , from )
394
+ this . onupdate ( status , bitfield , value , from )
398
395
}
399
396
400
397
if ( this . _shouldFlush ( ) ) await this . _flushOplog ( )
@@ -472,15 +469,15 @@ module.exports = class Core {
472
469
addReorgHint ( this . header . hints . reorgs , this . tree , batch )
473
470
batch . commit ( )
474
471
475
- const appended = batch . length > batch . ancestors
472
+ const contigStatus = updateContig ( this . header , entry . bitfield , this . bitfield )
473
+ const status = ( ( batch . length > batch . ancestors ) ? 0b0011 : 0b0010 ) | contigStatus
476
474
477
- this . header . contiguousLength = Math . min ( batch . ancestors , this . header . contiguousLength )
478
- this . oncontigupdate ( )
479
475
this . header . tree . fork = batch . fork
480
476
this . header . tree . length = batch . length
481
477
this . header . tree . rootHash = batch . hash ( )
482
478
this . header . tree . signature = batch . signature
483
- this . onupdate ( appended ? 0b11 : 0b10 , entry . bitfield , null , from )
479
+
480
+ this . onupdate ( status , entry . bitfield , null , from )
484
481
485
482
// TODO: there is a bug in the merkle tree atm where it cannot handle unflushed
486
483
// truncates if we append or download anything after the truncation point later on
@@ -501,6 +498,36 @@ module.exports = class Core {
501
498
}
502
499
}
503
500
501
+ function updateContig ( header , upd , bitfield ) {
502
+ const end = upd . start + upd . length
503
+
504
+ let c = header . contiguousLength
505
+
506
+ if ( upd . drop ) {
507
+ // If we dropped a block in the current contig range, "downgrade" it
508
+ if ( c <= end && c > upd . start ) {
509
+ c = upd . start
510
+ }
511
+ } else {
512
+ if ( c <= end && c >= upd . start ) {
513
+ c = end
514
+ while ( bitfield . get ( c ) ) c ++
515
+ }
516
+ }
517
+
518
+ if ( c === header . contiguousLength ) {
519
+ return 0b0000
520
+ }
521
+
522
+ if ( c > header . contiguousLength ) {
523
+ header . contiguousLength = c
524
+ return 0b0100
525
+ }
526
+
527
+ header . contiguousLength = c
528
+ return 0b1000
529
+ }
530
+
504
531
function addReorgHint ( list , tree , batch ) {
505
532
if ( tree . length === 0 || tree . fork === batch . fork ) return
506
533
0 commit comments