From 9c3cbe7571d02890eff2736519a0981235d92a05 Mon Sep 17 00:00:00 2001 From: Mathias Buus Date: Wed, 8 Nov 2023 23:31:41 +0100 Subject: [PATCH] fix some bugs --- lib/bitfield.js | 2 +- lib/remote-bitfield.js | 10 +++++++--- lib/replicator.js | 34 ++++++++++++++++++++++------------ 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/lib/bitfield.js b/lib/bitfield.js index 4f408507..f16627b7 100644 --- a/lib/bitfield.js +++ b/lib/bitfield.js @@ -43,7 +43,7 @@ class BitfieldPage { let i = Math.floor(start / 128) const n = i + Math.ceil(length / 128) - while (i < n) this.tree.update(this.offset * 8 + i++ * 128) + while (i <= n) this.tree.update(this.offset * 8 + i++ * 128) } findFirst (val, position) { diff --git a/lib/remote-bitfield.js b/lib/remote-bitfield.js index 0386f4e8..b90a8191 100644 --- a/lib/remote-bitfield.js +++ b/lib/remote-bitfield.js @@ -38,7 +38,7 @@ class RemoteBitfieldPage { let i = Math.floor(start / 128) const n = i + Math.ceil(length / 128) - while (i < n) this.tree.update(this.offset * 8 + i++ * 128) + while (i <= n) this.tree.update(this.offset * 8 + i++ * 128) } findFirst (val, position) { @@ -65,6 +65,7 @@ class RemoteBitfieldSegment { this.offset = index * BYTES_PER_SEGMENT this.tree = quickbit.Index.from([], BYTES_PER_SEGMENT) this.pages = new Array(PAGES_PER_SEGMENT) + this.pagesLength = 0 } get chunks () { @@ -76,7 +77,10 @@ class RemoteBitfieldSegment { } add (page) { - this.pages[page.index - this.index * PAGES_PER_SEGMENT] = page + const pageIndex = page.index - this.index * PAGES_PER_SEGMENT + if (pageIndex >= this.pagesLength) this.pagesLength = pageIndex + 1 + + this.pages[pageIndex] = page const chunk = { field: page.bitfield, offset: page.offset } @@ -98,7 +102,7 @@ class RemoteBitfieldSegment { if (i >= PAGES_PER_SEGMENT) return -1 - while (i < this.pages.length) { + while (i < this.pagesLength) { const p = this.pages[i] let index = -1 diff --git a/lib/replicator.js b/lib/replicator.js index 06201306..4f76c54f 100644 --- a/lib/replicator.js +++ b/lib/replicator.js @@ -743,20 +743,23 @@ class Peer { _clearLocalRange (start, length) { if (length === 1) { - this.missingBlocks.set(start, false) + this.missingBlocks.set(start, this.remoteBitfield.get(start) && !this.core.bitfield.get(start)) return } const contig = Math.min(this.core.tree.length, this.core.header.hints.contiguousLength) - if (start < contig) { + if (start + length < contig) { const delta = contig - start - this.missingBlocks.setRange(start, delta) - start = contig - length -= delta + this.missingBlocks.setRange(start, delta, false) + return } - if ((start & 31) > 0) start -= (start & 31) + const rem = start & 32767 + if (rem > 0) { + start -= rem + length += rem + } const end = start + Math.min(length, this.core.tree.length) while (start < end) { @@ -772,11 +775,17 @@ class Peer { _unclearLocalRange (start, length) { if (length === 1) { - this.missingBlocks.set(start, this.remoteBitfield.get(start)) + this.missingBlocks.set(start, this.remoteBitfield.get(start) && !this.core.bitfield.get(start)) return } - if ((start & 31) > 0) start -= (start & 31) + const rem = start & 2097151 + if (rem > 0) { + start -= rem + length += rem + } + + const fixedStart = start const end = start + Math.min(length, this.remoteLength) while (start < end) { @@ -788,14 +797,14 @@ class Peer { start += 2097152 } - this._clearLocalRange(start, length) + this._clearLocalRange(fixedStart, length) } onrange ({ drop, start, length }) { const has = drop === false if (length === 1) { - this.remoteBitfield.setRange(start, length, has) + this.remoteBitfield.set(start, has) this.missingBlocks.set(start, has && !this.core.bitfield.get(start)) } else { const rangeStart = this.remoteBitfield.findFirst(!has, start) @@ -1027,12 +1036,14 @@ class Peer { if (r.blocks) { let min = -1 let max = -1 + for (let i = r.start; i < r.end; i++) { const index = r.blocks[i] if (min === -1 || index < min) min = index if (max === -1 || index > max) max = index if (this.missingBlocks.get(index) === true && this._requestRangeBlock(index, length)) return true } + if (min > -1) this._maybeWant(min, max - min) return false } @@ -1047,7 +1058,6 @@ class Peer { while (true) { i = this.missingBlocks.findFirst(true, i) - if (i === -1 || i >= end) break if (this._requestRangeBlock(i, length)) return true @@ -1061,7 +1071,7 @@ class Peer { if (i === -1 || i >= off) break - if (this.core.bitfield.get(i) === false && this._hasTreeParent(i) && this._requestRangeBlock(i, length)) return true + if (this._requestRangeBlock(i, length)) return true i++ }