@@ -7,6 +7,7 @@ const m = require('./messages')
7
7
const caps = require ( './caps' )
8
8
9
9
const DEFAULT_MAX_INFLIGHT = 32
10
+ const DEFAULT_SEGMENT_SIZE = 128 * 1024 // 128 KiB
10
11
11
12
class Attachable {
12
13
constructor ( ) {
@@ -286,6 +287,9 @@ class Peer {
286
287
this . remoteDownloading = true
287
288
this . remoteSynced = false
288
289
290
+ this . segmentsWanted = new Set ( )
291
+ this . broadcastedNonSparse = false
292
+
289
293
this . lengthAcked = 0
290
294
291
295
this . extensions = new Map ( )
@@ -356,13 +360,13 @@ class Peer {
356
360
357
361
this . sendSync ( )
358
362
359
- const p = pages ( this . core )
363
+ const contig = this . core . header . contiguousLength
364
+ if ( contig > 0 ) {
365
+ this . broadcastRange ( 0 , contig , false )
360
366
361
- for ( let index = 0 ; index < p . length ; index ++ ) {
362
- this . wireBitfield . send ( {
363
- start : index * this . core . bitfield . pageSize ,
364
- bitfield : p [ index ]
365
- } )
367
+ if ( contig === this . core . tree . length ) {
368
+ this . broadcastedNonSparse = true
369
+ }
366
370
}
367
371
368
372
this . replicator . _ifAvailable --
@@ -552,8 +556,8 @@ class Peer {
552
556
this . replicator . _onnodata ( this , req )
553
557
}
554
558
555
- onwant ( ) {
556
- // TODO
559
+ onwant ( { start , length } ) {
560
+ this . replicator . _onwant ( this , start , length )
557
561
}
558
562
559
563
onunwant ( ) {
@@ -672,6 +676,7 @@ class Peer {
672
676
return true
673
677
}
674
678
679
+ this . _maybeWant ( s . seeker . start , len )
675
680
return false
676
681
}
677
682
@@ -683,7 +688,10 @@ class Peer {
683
688
_requestBlock ( b ) {
684
689
const { length, fork } = this . core . tree
685
690
686
- if ( this . remoteBitfield . get ( b . index ) === false || fork !== this . remoteFork ) return false
691
+ if ( this . remoteBitfield . get ( b . index ) === false || fork !== this . remoteFork ) {
692
+ this . _maybeWant ( b . index )
693
+ return false
694
+ }
687
695
688
696
const req = this . _makeRequest ( b . index >= length )
689
697
if ( req === null ) return false
@@ -741,6 +749,7 @@ class Peer {
741
749
return true
742
750
}
743
751
752
+ this . _maybeWant ( r . start , len )
744
753
return false
745
754
}
746
755
@@ -778,9 +787,25 @@ class Peer {
778
787
return true
779
788
}
780
789
790
+ this . _maybeWant ( f . batch . want . start , len )
781
791
return false
782
792
}
783
793
794
+ _maybeWant ( start , length = 1 ) {
795
+ let i = Math . floor ( start / DEFAULT_SEGMENT_SIZE )
796
+ const n = Math . ceil ( ( start + length ) / DEFAULT_SEGMENT_SIZE )
797
+
798
+ for ( ; i < n ; i ++ ) {
799
+ if ( this . segmentsWanted . has ( i ) ) continue
800
+ this . segmentsWanted . add ( i )
801
+
802
+ this . wireWant . send ( {
803
+ start : i * DEFAULT_SEGMENT_SIZE ,
804
+ length : DEFAULT_SEGMENT_SIZE
805
+ } )
806
+ }
807
+ }
808
+
784
809
async _send ( req ) {
785
810
const fork = this . core . tree . fork
786
811
@@ -1297,6 +1322,28 @@ module.exports = class Replicator {
1297
1322
else this . updatePeer ( peer )
1298
1323
}
1299
1324
1325
+ _onwant ( peer , start , length ) {
1326
+ length = Math . min ( length , this . core . tree . length - start )
1327
+
1328
+ peer . protomux . cork ( )
1329
+
1330
+ let i = Math . floor ( start / this . core . bitfield . pageSize )
1331
+ const n = Math . ceil ( ( start + length ) / this . core . bitfield . pageSize )
1332
+
1333
+ for ( ; i < n ; i ++ ) {
1334
+ const p = this . core . bitfield . pages . get ( i )
1335
+
1336
+ if ( p ) {
1337
+ peer . wireBitfield . send ( {
1338
+ start : i * this . core . bitfield . pageSize ,
1339
+ bitfield : p . bitfield
1340
+ } )
1341
+ }
1342
+ }
1343
+
1344
+ peer . protomux . uncork ( )
1345
+ }
1346
+
1300
1347
async _onreorgdata ( peer , req , data ) {
1301
1348
const f = this . _addReorg ( data . fork , peer )
1302
1349
@@ -1523,17 +1570,6 @@ module.exports = class Replicator {
1523
1570
}
1524
1571
}
1525
1572
1526
- function pages ( core ) {
1527
- const res = [ ]
1528
-
1529
- for ( let i = 0 ; i < core . tree . length ; i += core . bitfield . pageSize ) {
1530
- const p = core . bitfield . page ( i / core . bitfield . pageSize )
1531
- res . push ( p )
1532
- }
1533
-
1534
- return res
1535
- }
1536
-
1537
1573
function matchingRequest ( req , data ) {
1538
1574
if ( data . block !== null && ( req . block === null || req . block . index !== data . block . index ) ) return false
1539
1575
if ( data . hash !== null && ( req . hash === null || req . hash . index !== data . hash . index ) ) return false
0 commit comments