@@ -9,9 +9,8 @@ const { BAD_ARGUMENT, STORAGE_EMPTY, STORAGE_CONFLICT, INVALID_SIGNATURE } = req
99const m = require ( './messages' )
1010
1111module . 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 ) {
1313 this . onupdate = onupdate
14- this . oncontigupdate = oncontigupdate
1514 this . header = header
1615 this . crypto = crypto
1716 this . oplog = oplog
@@ -27,8 +26,6 @@ module.exports = class Core {
2726 this . _verifiesFlushed = null
2827 this . _mutex = new Mutex ( )
2928 this . _legacy = legacy
30-
31- this . _updateContiguousLength ( header . contiguousLength )
3229 }
3330
3431 static async open ( storage , opts = { } ) {
@@ -134,6 +131,11 @@ module.exports = class Core {
134131 await bitfield . clear ( )
135132 }
136133
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+
137139 const auth = opts . auth || this . createAuth ( crypto , header . signer )
138140
139141 for ( const e of entries ) {
@@ -149,6 +151,7 @@ module.exports = class Core {
149151
150152 if ( e . bitfield ) {
151153 bitfield . setRange ( e . bitfield . start , e . bitfield . length , ! e . bitfield . drop )
154+ updateContig ( header , e . bitfield , bitfield )
152155 }
153156
154157 if ( e . treeUpgrade ) {
@@ -165,7 +168,7 @@ module.exports = class Core {
165168 }
166169 }
167170
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 )
169172 }
170173
171174 _shouldFlush ( ) {
@@ -196,17 +199,6 @@ module.exports = class Core {
196199 await this . blocks . put ( index , value , byteOffset )
197200 }
198201
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-
210202 async userData ( key , value ) {
211203 // TODO: each oplog append can set user data, so we should have a way
212204 // to just hitch a ride on one of the other ongoing appends?
@@ -286,12 +278,12 @@ module.exports = class Core {
286278 this . bitfield . setRange ( batch . ancestors , batch . length - batch . ancestors , true )
287279 batch . commit ( )
288280
289- this . header . contiguousLength = batch . length
290- this . oncontigupdate ( )
291281 this . header . tree . length = batch . length
292282 this . header . tree . rootHash = hash
293283 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 )
295287
296288 if ( this . _shouldFlush ( ) ) await this . _flushOplog ( )
297289
@@ -329,9 +321,11 @@ module.exports = class Core {
329321
330322 await this . oplog . append ( [ entry ] , false )
331323
324+ let status = 0b0001
325+
332326 if ( bitfield ) {
333327 this . bitfield . set ( bitfield . start , true )
334- this . _updateContiguousLength ( bitfield . start , bitfield . length )
328+ status |= updateContig ( this . header , bitfield , this . bitfield )
335329 }
336330
337331 batch . commit ( )
@@ -340,7 +334,8 @@ module.exports = class Core {
340334 this . header . tree . length = batch . length
341335 this . header . tree . rootHash = batch . rootHash
342336 this . header . tree . signature = batch . signature
343- this . onupdate ( 0b01 , bitfield , value , from )
337+
338+ this . onupdate ( status , bitfield , value , from )
344339
345340 if ( this . _shouldFlush ( ) ) await this . _flushOplog ( )
346341 } finally {
@@ -387,14 +382,16 @@ module.exports = class Core {
387382 continue
388383 }
389384
385+ let status = 0
386+
390387 if ( bitfield ) {
391388 this . bitfield . set ( bitfield . start , true )
392- this . _updateContiguousLength ( bitfield . start , bitfield . length )
389+ status = updateContig ( this . header , bitfield , this . bitfield )
393390 }
394391
395392 batch . commit ( )
396393
397- this . onupdate ( 0 , bitfield , value , from )
394+ this . onupdate ( status , bitfield , value , from )
398395 }
399396
400397 if ( this . _shouldFlush ( ) ) await this . _flushOplog ( )
@@ -472,15 +469,15 @@ module.exports = class Core {
472469 addReorgHint ( this . header . hints . reorgs , this . tree , batch )
473470 batch . commit ( )
474471
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
476474
477- this . header . contiguousLength = Math . min ( batch . ancestors , this . header . contiguousLength )
478- this . oncontigupdate ( )
479475 this . header . tree . fork = batch . fork
480476 this . header . tree . length = batch . length
481477 this . header . tree . rootHash = batch . hash ( )
482478 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 )
484481
485482 // TODO: there is a bug in the merkle tree atm where it cannot handle unflushed
486483 // truncates if we append or download anything after the truncation point later on
@@ -501,6 +498,36 @@ module.exports = class Core {
501498 }
502499}
503500
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+
504531function addReorgHint ( list , tree , batch ) {
505532 if ( tree . length === 0 || tree . fork === batch . fork ) return
506533
0 commit comments