Skip to content
This repository was archived by the owner on Aug 12, 2020. It is now read-only.

Commit 7450a65

Browse files
alanshawdaviddias
authored andcommitted
feat: Add onlyHash option (#183)
* option for only-hash * Adds tests for only-hash option --only-hash will chunk and hash input - but not write it to disk * removes console.logging * restores src/importer/flush-tree (which is not actually ever used or executed) * Removes .only on a test and changes the option name. Adds reference to 'onlyHash' in the read me * Fix the tests
1 parent ac6f722 commit 7450a65

14 files changed

+124
-24
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ The input's file paths and directory structure will be preserved in the [`dag-pb
139139
- `hamt` (object): the options for the HAMT sharded directory builder
140140
- bits (positive integer, defaults to `8`): the number of bits at each bucket of the HAMT
141141
- `progress` (function): a function that will be called with the byte length of chunks as a file is added to ipfs.
142+
- `onlyHash` (boolean, defaults to false): Only chunk and hash - do not write to disk
142143

143144
### Exporter
144145

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
},
8282
"contributors": [
8383
"Alan Shaw <[email protected]>",
84+
"Bernard Mordan <[email protected]>",
8485
"David Dias <[email protected]>",
8586
"Francisco Baio Dias <[email protected]>",
8687
"Friedel Ziegelmayer <[email protected]>",

src/builder/builder.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,12 @@ module.exports = function (createChunker, ipldResolver, createReducer, _options)
5757
// 2. write it to the dag store
5858

5959
const d = new UnixFS('directory')
60+
6061
waterfall([
6162
(cb) => DAGNode.create(d.marshal(), [], options.hashAlg, cb),
6263
(node, cb) => {
64+
if (options.onlyHash) return cb(null, node)
65+
6366
ipldResolver.put(node, {
6467
cid: new CID(node.multihash)
6568
}, (err) => cb(err, node))
@@ -106,6 +109,8 @@ module.exports = function (createChunker, ipldResolver, createReducer, _options)
106109
})
107110
}),
108111
pull.asyncMap((leaf, callback) => {
112+
if (options.onlyHash) return callback(null, leaf)
113+
109114
ipldResolver.put(leaf.DAGNode, {
110115
cid: new CID(leaf.DAGNode.multihash)
111116
}, (err) => callback(err, leaf)

src/builder/reduce.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ module.exports = function (file, ipldResolver, options) {
3434
waterfall([
3535
(cb) => DAGNode.create(f.marshal(), links, cb),
3636
(node, cb) => {
37+
if (options.onlyHash) return cb(null, node)
38+
3739
ipldResolver.put(node, {
3840
cid: new CID(node.multihash)
3941
}, (err) => cb(err, node))

src/importer/dir-flat.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@ const DAGNode = dagPB.DAGNode
1010
const Dir = require('./dir')
1111

1212
class DirFlat extends Dir {
13-
constructor (props) {
14-
super()
13+
constructor (props, _options) {
14+
super(props, _options)
1515
this._children = {}
16-
Object.assign(this, props)
1716
}
1817

1918
put (name, value, callback) {
@@ -57,10 +56,13 @@ class DirFlat extends Dir {
5756
})
5857

5958
const dir = new UnixFS('directory')
59+
6060
waterfall(
6161
[
6262
(callback) => DAGNode.create(dir.marshal(), links, callback),
6363
(node, callback) => {
64+
if (this._options.onlyHash) return callback(null, node)
65+
6466
ipldResolver.put(
6567
node,
6668
{
@@ -86,6 +88,6 @@ class DirFlat extends Dir {
8688

8789
module.exports = createDirFlat
8890

89-
function createDirFlat (props) {
90-
return new DirFlat(props)
91+
function createDirFlat (props, _options) {
92+
return new DirFlat(props, _options)
9193
}

src/importer/dir-sharded.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,9 @@ const defaultOptions = {
4141

4242
class DirSharded extends Dir {
4343
constructor (props, _options) {
44-
super()
4544
const options = Object.assign({}, defaultOptions, _options)
46-
this._options = options
45+
super(props, options)
4746
this._bucket = Bucket(options)
48-
Object.assign(this, props)
4947
}
5048

5149
put (name, value, callback) {
@@ -87,8 +85,8 @@ class DirSharded extends Dir {
8785

8886
module.exports = createDirSharded
8987

90-
function createDirSharded (props) {
91-
return new DirSharded(props)
88+
function createDirSharded (props, _options) {
89+
return new DirSharded(props, _options)
9290
}
9391

9492
function flush (options, bucket, path, ipldResolver, source, callback) {
@@ -148,6 +146,8 @@ function flush (options, bucket, path, ipldResolver, source, callback) {
148146
[
149147
(callback) => DAGNode.create(dir.marshal(), links, callback),
150148
(node, callback) => {
149+
if (options.onlyHash) return callback(null, node)
150+
151151
ipldResolver.put(
152152
node,
153153
{

src/importer/dir.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
'use strict'
22

33
module.exports = class Dir {
4+
constructor (props, _options) {
5+
this._options = _options || {}
6+
Object.assign(this, props)
7+
}
48
}

src/importer/flat-to-shard.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ const DirSharded = require('./dir-sharded')
55

66
module.exports = flatToShard
77

8-
function flatToShard (child, dir, threshold, callback) {
9-
maybeFlatToShardOne(dir, threshold, (err, newDir) => {
8+
function flatToShard (child, dir, threshold, options, callback) {
9+
maybeFlatToShardOne(dir, threshold, options, (err, newDir) => {
1010
if (err) {
1111
callback(err)
1212
return // early
@@ -27,7 +27,7 @@ function flatToShard (child, dir, threshold, callback) {
2727
},
2828
(callback) => {
2929
if (parent) {
30-
flatToShard(newDir, parent, threshold, callback)
30+
flatToShard(newDir, parent, threshold, options, callback)
3131
} else {
3232
callback(null, newDir)
3333
}
@@ -40,15 +40,15 @@ function flatToShard (child, dir, threshold, callback) {
4040
})
4141
}
4242

43-
function maybeFlatToShardOne (dir, threshold, callback) {
43+
function maybeFlatToShardOne (dir, threshold, options, callback) {
4444
if (dir.flat && dir.directChildrenCount() >= threshold) {
45-
definitelyShardOne(dir, callback)
45+
definitelyShardOne(dir, options, callback)
4646
} else {
4747
callback(null, dir)
4848
}
4949
}
5050

51-
function definitelyShardOne (oldDir, callback) {
51+
function definitelyShardOne (oldDir, options, callback) {
5252
const newDir = DirSharded({
5353
root: oldDir.root,
5454
dir: true,
@@ -57,7 +57,7 @@ function definitelyShardOne (oldDir, callback) {
5757
path: oldDir.path,
5858
dirty: oldDir.dirty,
5959
flat: false
60-
})
60+
}, options)
6161

6262
oldDir.eachChildSeries(
6363
(key, value, callback) => {

src/importer/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ module.exports = function (ipldResolver, _options) {
6464
return node
6565
}),
6666
treeBuilderStream
67-
)
67+
)
6868

6969
return {
7070
sink: entry.sink,

src/importer/tree-builder.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ module.exports = createTreeBuilder
1414

1515
const defaultOptions = {
1616
wrap: false,
17-
shardSplitThreshold: 1000
17+
shardSplitThreshold: 1000,
18+
onlyHash: false
1819
}
1920

2021
function createTreeBuilder (ipldResolver, _options) {
2122
const options = Object.assign({}, defaultOptions, _options)
2223

2324
const queue = createQueue(consumeQueue, 1)
24-
2525
// returned stream
2626
let stream = createStream()
2727

@@ -32,7 +32,7 @@ function createTreeBuilder (ipldResolver, _options) {
3232
dir: true,
3333
dirty: false,
3434
flat: true
35-
})
35+
}, options)
3636

3737
return {
3838
flush: flushRoot,
@@ -101,7 +101,6 @@ function createTreeBuilder (ipldResolver, _options) {
101101
currentPath += '/'
102102
}
103103
currentPath += pathElem
104-
105104
const last = (index === lastIndex)
106105
parent.dirty = true
107106
parent.multihash = null
@@ -110,7 +109,7 @@ function createTreeBuilder (ipldResolver, _options) {
110109
if (last) {
111110
waterfall([
112111
(callback) => parent.put(pathElem, elem, callback),
113-
(callback) => flatToShard(null, parent, options.shardSplitThreshold, callback),
112+
(callback) => flatToShard(null, parent, options.shardSplitThreshold, options, callback),
114113
(newRoot, callback) => {
115114
tree = newRoot
116115
callback()
@@ -131,7 +130,7 @@ function createTreeBuilder (ipldResolver, _options) {
131130
path: currentPath,
132131
dirty: true,
133132
flat: true
134-
})
133+
}, options)
135134
}
136135
const parentDir = parent
137136
parent = dir

test/browser.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,5 @@ describe('IPFS data importing tests on the Browser', function () {
5252
require('./test-hash-parity-with-go-ipfs')(repo)
5353
require('./test-nested-dir-import-export')(repo)
5454
require('./test-dirbuilder-sharding')(repo)
55+
require('./test-builder-only-hash')(repo)
5556
})

test/node.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,5 @@ describe('IPFS UnixFS Engine', () => {
5353
require('./test-nested-dir-import-export')(repo)
5454
require('./test-dirbuilder-sharding')(repo)
5555
require('./test-dag-api')
56+
require('./test-builder-only-hash')(repo)
5657
})

test/test-builder-only-hash.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/* eslint-env mocha */
2+
'use strict'
3+
4+
const chai = require('chai')
5+
chai.use(require('dirty-chai'))
6+
const expect = chai.expect
7+
const BlockService = require('ipfs-block-service')
8+
const pull = require('pull-stream')
9+
const IPLDResolver = require('ipld-resolver')
10+
const CID = require('cids')
11+
const createBuilder = require('../src/builder')
12+
const FixedSizeChunker = require('../src/chunker/fixed-size')
13+
14+
module.exports = (repo) => {
15+
describe('builder', () => {
16+
let ipldResolver
17+
18+
before(() => {
19+
const bs = new BlockService(repo)
20+
ipldResolver = new IPLDResolver(bs)
21+
})
22+
23+
it('will only chunk and hash if passed an "onlyHash" option', (done) => {
24+
const onCollected = (err, nodes) => {
25+
if (err) return done(err)
26+
27+
const node = nodes[0]
28+
expect(node).to.exist()
29+
30+
ipldResolver.get(new CID(node.multihash), (err, res) => {
31+
expect(err).to.exist()
32+
done()
33+
})
34+
}
35+
36+
const content = String(Math.random() + Date.now())
37+
const inputFile = {
38+
path: content + '.txt',
39+
content: Buffer.from(content)
40+
}
41+
42+
const options = {
43+
onlyHash: true
44+
}
45+
46+
pull(
47+
pull.values([inputFile]),
48+
createBuilder(FixedSizeChunker, ipldResolver, options),
49+
pull.collect(onCollected)
50+
)
51+
})
52+
})
53+
}

test/test-importer.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const sinon = require('sinon')
1111
const BlockService = require('ipfs-block-service')
1212
const pull = require('pull-stream')
1313
const mh = require('multihashes')
14+
const CID = require('cids')
1415
const IPLDResolver = require('ipld-resolver')
1516
const loadFixture = require('aegir/fixtures')
1617

@@ -419,6 +420,36 @@ module.exports = (repo) => {
419420
}
420421
})
421422

423+
it('will not write to disk if passed "onlyHash" option', (done) => {
424+
const content = String(Math.random() + Date.now())
425+
const inputFile = {
426+
path: content + '.txt',
427+
content: Buffer.from(content)
428+
}
429+
430+
const options = {
431+
onlyHash: true
432+
}
433+
434+
const onCollected = (err, files) => {
435+
if (err) return done(err)
436+
437+
const file = files[0]
438+
expect(file).to.exist()
439+
440+
ipldResolver.get(new CID(file.multihash), (err, res) => {
441+
expect(err).to.exist()
442+
done()
443+
})
444+
}
445+
446+
pull(
447+
pull.values([inputFile]),
448+
importer(ipldResolver, options),
449+
pull.collect(onCollected)
450+
)
451+
})
452+
422453
it('will call an optional progress function', (done) => {
423454
options.progress = sinon.spy()
424455

0 commit comments

Comments
 (0)