Skip to content

Commit c65e722

Browse files
dignifiedquiredaviddias
authored andcommitted
feat: more perf stuffs
1 parent dbe80cc commit c65e722

File tree

8 files changed

+130
-170
lines changed

8 files changed

+130
-170
lines changed

README.md

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -104,24 +104,24 @@ pull(
104104

105105
- `cids: CID|[]CID`
106106

107-
Cancel previously requested keys, forcefully. That means they are removed from the
108-
wantlist independent of how many other resources requested these keys. Callbacks
109-
attached to `getBlock` are errored with `Error('manual unwant: key')`.
107+
Cancel previously requested cids, forcefully. That means they are removed from the
108+
wantlist independent of how many other resources requested these cids. Callbacks
109+
attached to `getBlock` are errored with `Error('manual unwant: cid)`.
110110

111111
#### `cancelWants(cids)`
112112

113113
- `cid: CID|[]CID`
114114

115-
Cancel previously requested keys.
115+
Cancel previously requested cids.
116116

117117
#### `putStream()`
118118

119-
Returns a duplex `pull-stream` that emits an object `{key: Multihash}` for every written block when it was stored.
120-
Objects passed into here should be of the form `{data: Buffer, key: Multihash}`
119+
Returns a duplex `pull-stream` that emits an object `{cid: CID}` for every written block when it was stored.
120+
Objects passed into here should be of the form `{data: Buffer, cid: CID}`
121121

122122
#### `put(blockAndCid, callback)`
123123

124-
- `blockAndKey: {data: Buffer, cid: CID}`
124+
- `blockAndCid: {data: Buffer, cid: CID}`
125125
- `callback: Function`
126126

127127
Announce that the current node now has the block containing `data`. This will store it
@@ -152,9 +152,7 @@ src
152152
│   ├── decision
153153
│   │   ├── engine.js
154154
│   │   ├── index.js
155-
│   │   ├── ledger.js
156-
│   │   ├── peer-request-queue.js
157-
│   │   └── pq.js
155+
│   │   └── ledger.js
158156
│   ├── network # Handles peerSet and open new conns
159157
│   │   └── index.js
160158
│   └── want-manager # Keeps track of all blocks the peer wants (not the others which it is connected)

package.json

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,22 +44,22 @@
4444
"idb-pull-blob-store": "^0.5.1",
4545
"interface-pull-blob-store": "^0.6.0",
4646
"ipfs-repo": "^0.11.2",
47-
"libp2p-ipfs-nodejs": "^0.17.0",
47+
"libp2p-ipfs-nodejs": "^0.17.1",
4848
"lodash": "^4.17.2",
4949
"multiaddr": "^2.1.1",
5050
"ncp": "^2.0.0",
5151
"peer-book": "^0.3.0",
52-
"peer-id": "^0.8.0",
52+
"peer-id": "^0.8.1",
5353
"peer-info": "^0.8.1",
5454
"rimraf": "^2.5.4",
5555
"safe-buffer": "^5.0.1"
5656
},
5757
"dependencies": {
5858
"async": "^2.1.4",
5959
"cids": "^0.3.5",
60-
"debug": "^2.4.4",
60+
"debug": "^2.5.1",
6161
"heap": "^0.2.6",
62-
"ipfs-block": "^0.5.3",
62+
"ipfs-block": "^0.5.4",
6363
"lodash.debounce": "^4.0.8",
6464
"lodash.find": "^4.6.0",
6565
"lodash.groupby": "^4.6.0",
@@ -68,7 +68,6 @@
6868
"lodash.pullallwith": "^4.7.0",
6969
"lodash.uniqwith": "^4.5.0",
7070
"lodash.values": "^4.3.0",
71-
"multihashes": "^0.3.1",
7271
"protocol-buffers": "^3.2.1",
7372
"pull-defer": "^0.2.2",
7473
"pull-length-prefixed": "^1.2.0",

src/components/decision-engine/index.js

Lines changed: 29 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ const find = require('lodash.find')
1111
const values = require('lodash.values')
1212
const groupBy = require('lodash.groupby')
1313
const pullAllWith = require('lodash.pullallwith')
14-
const CID = require('cids')
1514

1615
const log = debug('bitswap:engine')
1716
log.error = debug('bitswap:engine:error')
@@ -124,18 +123,17 @@ class DecisionEngine {
124123
return
125124
}
126125
// Check all connected peers if they want the block we received
127-
for (let l of this.ledgerMap.values()) {
126+
this.ledgerMap.forEach((ledger) => {
128127
cids
129-
.map((k) => l.wantlistContains(k))
128+
.map((cid) => ledger.wantlistContains(cid))
130129
.filter(Boolean)
131-
.forEach((e) => {
132-
// this.peerRequestQueue.push(e, l.partner)
130+
.forEach((entry) => {
133131
this._tasks.push({
134-
entry: e,
135-
target: l.partner
132+
entry: entry,
133+
target: ledger.partner
136134
})
137135
})
138-
}
136+
})
139137
this._outbox()
140138
}
141139

@@ -152,30 +150,26 @@ class DecisionEngine {
152150
ledger.wantlist = new Wantlist()
153151
}
154152

155-
this._processBlocks(msg.blocks, ledger, (err) => {
156-
if (err) {
157-
log.error(`failed to process blocks: ${err.message}`)
158-
}
153+
this._processBlocks(msg.blocks, ledger)
159154

160-
if (msg.wantlist.size === 0) {
161-
return cb()
162-
}
155+
if (msg.wantlist.size === 0) {
156+
return cb()
157+
}
163158

164-
let cancels = []
165-
let wants = []
166-
for (let entry of msg.wantlist.values()) {
167-
if (entry.cancel) {
168-
ledger.cancelWant(entry.cid)
169-
cancels.push(entry)
170-
} else {
171-
ledger.wants(entry.cid, entry.priority)
172-
wants.push(entry)
173-
}
159+
let cancels = []
160+
let wants = []
161+
msg.wantlist.forEach((entry) => {
162+
if (entry.cancel) {
163+
ledger.cancelWant(entry.cid)
164+
cancels.push(entry)
165+
} else {
166+
ledger.wants(entry.cid, entry.priority)
167+
wants.push(entry)
174168
}
175-
176-
this._cancelWants(ledger, peerId, cancels)
177-
this._addWants(ledger, peerId, wants, cb)
178169
})
170+
171+
this._cancelWants(ledger, peerId, cancels)
172+
this._addWants(ledger, peerId, wants, cb)
179173
}
180174

181175
_cancelWants (ledger, peerId, entries) {
@@ -209,24 +203,14 @@ class DecisionEngine {
209203
}
210204

211205
_processBlocks (blocks, ledger, callback) {
212-
map(blocks.values(), (block, cb) => {
213-
block.key((err, key) => {
214-
if (err) {
215-
return cb(err)
216-
}
217-
log('got block (%s bytes)', block.data.length)
218-
ledger.receivedBytes(block.data.length)
219-
220-
cb(null, new CID(key))
221-
})
222-
}, (err, cids) => {
223-
if (err) {
224-
return callback(err)
225-
}
226-
227-
this.receivedBlocks(cids)
228-
callback()
206+
const cids = []
207+
blocks.forEach((b, cidStr) => {
208+
log('got block (%s bytes)', b.block.data.length)
209+
ledger.receivedBytes(b.block.data.length)
210+
cids.push(b.cid)
229211
})
212+
213+
this.receivedBlocks(cids)
230214
}
231215

232216
// Clear up all accounting things after message was sent

src/index.js

Lines changed: 62 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
'use strict'
22

3-
const series = require('async/series')
4-
const debug = require('debug')
5-
6-
const log = debug('bitswap')
7-
log.error = debug('bitswap:error')
3+
const waterfall = require('async/waterfall')
4+
const each = require('async/each')
85
const EventEmitter = require('events').EventEmitter
96
const pull = require('pull-stream')
107
const paramap = require('pull-paramap')
118
const defer = require('pull-defer/source')
12-
const CID = require('cids')
9+
const debug = require('debug')
1310

1411
const CONSTANTS = require('./constants')
1512
const WantManager = require('./components/want-manager')
1613
const Network = require('./components/network')
1714
const DecisionEngine = require('./components/decision-engine')
1815

16+
const log = debug('bitswap')
17+
log.error = debug('bitswap:error')
18+
1919
class Bitswap {
2020
constructor (libp2p, blockstore, peerBook) {
2121
this.libp2p = libp2p
@@ -46,83 +46,53 @@ class Bitswap {
4646
log('failed to receive message', incoming)
4747
}
4848

49-
const cidsAndBlocks = Array
50-
.from(incoming.blocks.entries())
51-
.map((entry) => {
52-
return { cid: new CID(entry[0]), block: entry[1] }
53-
})
54-
55-
if (cidsAndBlocks.length === 0) {
49+
if (incoming.blocks.size === 0) {
5650
return cb()
5751
}
5852

53+
const cidsAndBlocks = Array.from(incoming.blocks.values())
54+
5955
// quickly send out cancels, reduces chances of duplicate block receives
60-
pull(
61-
pull.values(cidsAndBlocks),
62-
pull.filter((cidAndBlock) => this.wm.wantlist.contains(cidAndBlock.cid)),
63-
pull.collect((err, cidsAndBlocks) => {
64-
if (err) {
65-
return log.error(err)
66-
}
67-
const cids = cidsAndBlocks.map((entry) => entry.cid)
56+
const toCancel = cidsAndBlocks
57+
.filter((b) => this.wm.wantlist.contains(b.cid))
58+
.map((b) => b.cid)
6859

69-
this.wm.cancelWants(cids)
70-
})
71-
)
60+
this.wm.cancelWants(toCancel)
7261

73-
pull(
74-
pull.values(cidsAndBlocks),
75-
paramap(this._handleReceivedBlock.bind(this, peerId), 10),
76-
pull.onEnd(cb)
62+
each(
63+
cidsAndBlocks,
64+
this._handleReceivedBlock.bind(this, peerId),
65+
cb
7766
)
7867
})
7968
}
8069

8170
_handleReceivedBlock (peerId, cidAndBlock, callback) {
82-
series([
83-
(cb) => this._updateReceiveCounters(cidAndBlock.block, (err) => {
84-
if (err) {
85-
// ignore, as these have been handled
86-
// in _updateReceiveCounters
71+
const cid = cidAndBlock.cid
72+
const block = cidAndBlock.block
73+
74+
waterfall([
75+
(cb) => this.blockstore.has(cid.multihash, cb),
76+
(exists, cb) => {
77+
this._updateReceiveCounters(block, exists)
78+
log('got block')
79+
80+
if (exists) {
8781
return cb()
8882
}
8983

90-
log('got block from %s', peerId.toB58String(), cidAndBlock.block.data.length)
91-
cb()
92-
}),
93-
(cb) => {
94-
this.put(cidAndBlock, (err) => {
95-
if (err) {
96-
log.error('receiveMessage put error: %s', err.message)
97-
}
98-
cb()
99-
})
84+
this._putBlockStore(cidAndBlock, cb)
10085
}
10186
], callback)
10287
}
10388

104-
_updateReceiveCounters (block, callback) {
89+
_updateReceiveCounters (block, exists) {
10590
this.blocksRecvd++
106-
block.key((err, key) => {
107-
if (err) {
108-
return callback(err)
109-
}
11091

111-
this.blockstore.has(key, (err, has) => {
112-
if (err) {
113-
log('blockstore.has error: %s', err.message)
114-
return callback(err)
115-
}
116-
117-
if (has) {
118-
this.dupBlocksRecvd ++
119-
this.dupDataRecvd += block.data.length
120-
return callback(new Error('Already have block'))
121-
}
122-
123-
callback()
124-
})
125-
})
92+
if (exists) {
93+
this.dupBlocksRecvd ++
94+
this.dupDataRecvd += block.data.length
95+
}
12696
}
12797

12898
// handle errors on the receiving channel
@@ -250,24 +220,35 @@ class Bitswap {
250220
})
251221
}),
252222
pull.filter((val) => !val[1]),
253-
pull.map((val) => {
254-
const block = val[0].block
255-
const cid = val[0].cid
256-
log('putting block')
257-
return pull(
258-
pull.values([{
259-
data: block.data,
260-
key: cid.multihash
261-
}]),
262-
this.blockstore.putStream(),
263-
pull.through(() => {
264-
log('put block')
265-
this.notifications.emit(`block:${cid.buffer.toString()}`, block)
266-
this.engine.receivedBlocks([cid])
267-
})
268-
)
269-
}),
270-
pull.flatten()
223+
pull.asyncMap((val, cb) => {
224+
this._putBlockStore(val[0], cb)
225+
})
226+
)
227+
}
228+
229+
_putBlockStore (blockAndCid, callback) {
230+
const block = blockAndCid.block
231+
const cid = blockAndCid.cid
232+
const cidStr = cid.buffer.toString()
233+
234+
log('putting block')
235+
236+
pull(
237+
pull.values([{
238+
data: block.data,
239+
key: cid.multihash
240+
}]),
241+
this.blockstore.putStream(),
242+
pull.collect((err, meta) => {
243+
if (err) {
244+
return callback(err)
245+
}
246+
247+
log('put block')
248+
this.notifications.emit(`block:${cidStr}`, block)
249+
this.engine.receivedBlocks([cid])
250+
callback(null, meta)
251+
})
271252
)
272253
}
273254

0 commit comments

Comments
 (0)