@@ -3,7 +3,7 @@ import { persist } from '../utils/persist.js'
33import { encode , PBLink , prepare } from '@ipld/dag-pb'
44import parallelBatch from 'it-parallel-batch'
55import * as rawCodec from 'multiformats/codecs/raw'
6- import type { BufferImporter , File , InProgressImportResult , Blockstore } from '../index.js'
6+ import type { BufferImporter , File , InProgressImportResult , Blockstore , SingleBlockImportResult } from '../index.js'
77import type { FileLayout , Reducer } from '../layout/index.js'
88import type { Version } from 'multiformats/cid'
99import type { ProgressOptions } from 'progress-events'
@@ -15,24 +15,37 @@ interface BuildFileBatchOptions {
1515
1616async function * buildFileBatch ( file : File , blockstore : Blockstore , options : BuildFileBatchOptions ) : AsyncGenerator < InProgressImportResult > {
1717 let count = - 1
18- let previous : InProgressImportResult | undefined
18+ let previous : SingleBlockImportResult | undefined
1919
2020 for await ( const entry of parallelBatch ( options . bufferImporter ( file , blockstore ) , options . blockWriteConcurrency ) ) {
2121 count ++
2222
2323 if ( count === 0 ) {
24- previous = entry
24+ // cache the first entry if case there aren't any more
25+ previous = {
26+ ...entry ,
27+ single : true
28+ }
29+
2530 continue
2631 } else if ( count === 1 && ( previous != null ) ) {
27- yield previous
32+ // we have the second block of a multiple block import so yield the first
33+ yield {
34+ ...previous ,
35+ block : undefined ,
36+ single : undefined
37+ }
2838 previous = undefined
2939 }
3040
31- yield entry
41+ // yield the second or later block of a multiple block import
42+ yield {
43+ ...entry ,
44+ block : undefined
45+ }
3246 }
3347
3448 if ( previous != null ) {
35- previous . single = true
3649 yield previous
3750 }
3851}
@@ -43,49 +56,32 @@ interface ReduceOptions extends ProgressOptions {
4356 signal ?: AbortSignal
4457}
4558
59+ function isSingleBlockImport ( result : any ) : result is SingleBlockImportResult {
60+ return result . single === true
61+ }
62+
4663const reduce = ( file : File , blockstore : Blockstore , options : ReduceOptions ) : Reducer => {
4764 const reducer : Reducer = async function ( leaves ) {
48- if ( leaves . length === 1 && leaves [ 0 ] ?. single === true && options . reduceSingleLeafToSelf ) {
65+ if ( leaves . length === 1 && isSingleBlockImport ( leaves [ 0 ] ) && options . reduceSingleLeafToSelf ) {
4966 const leaf = leaves [ 0 ]
5067
51- if ( file . mtime !== undefined || file . mode !== undefined ) {
68+ if ( isSingleBlockImport ( leaf ) && ( file . mtime !== undefined || file . mode !== undefined ) ) {
5269 // only one leaf node which is a raw leaf - we have metadata so convert it into a
5370 // UnixFS entry otherwise we'll have nowhere to store the metadata
54- let buffer = await blockstore . get ( leaf . cid , options )
55-
5671 leaf . unixfs = new UnixFS ( {
5772 type : 'file' ,
5873 mtime : file . mtime ,
5974 mode : file . mode ,
60- data : buffer
75+ data : leaf . block
6176 } )
6277
63- buffer = encode ( prepare ( { Data : leaf . unixfs . marshal ( ) } ) )
64-
65- // // TODO vmx 2021-03-26: This is what the original code does, it checks
66- // // the multihash of the original leaf node and uses then the same
67- // // hasher. i wonder if that's really needed or if we could just use
68- // // the hasher from `options.hasher` instead.
69- // const multihash = mh.decode(leaf.cid.multihash.bytes)
70- // let hasher
71- // switch multihash {
72- // case sha256.code {
73- // hasher = sha256
74- // break;
75- // }
76- // //case identity.code {
77- // // hasher = identity
78- // // break;
79- // // }
80- // default: {
81- // throw new Error(`Unsupported hasher "${multihash}"`)
82- // }
83- // }
84- leaf . cid = await persist ( buffer , blockstore , {
78+ leaf . block = encode ( prepare ( { Data : leaf . unixfs . marshal ( ) } ) )
79+
80+ leaf . cid = await persist ( leaf . block , blockstore , {
8581 ...options ,
8682 cidVersion : options . cidVersion
8783 } )
88- leaf . size = BigInt ( buffer . length )
84+ leaf . size = BigInt ( leaf . block . length )
8985 }
9086
9187 return {
@@ -147,15 +143,16 @@ const reduce = (file: File, blockstore: Blockstore, options: ReduceOptions): Red
147143 Data : f . marshal ( ) ,
148144 Links : links
149145 }
150- const buffer = encode ( prepare ( node ) )
151- const cid = await persist ( buffer , blockstore , options )
146+ const block = encode ( prepare ( node ) )
147+ const cid = await persist ( block , blockstore , options )
152148
153149 return {
154150 cid,
155151 path : file . path ,
156152 unixfs : f ,
157- size : BigInt ( buffer . length + node . Links . reduce ( ( acc , curr ) => acc + ( curr . Tsize ?? 0 ) , 0 ) ) ,
158- originalPath : file . originalPath
153+ size : BigInt ( block . length + node . Links . reduce ( ( acc , curr ) => acc + ( curr . Tsize ?? 0 ) , 0 ) ) ,
154+ originalPath : file . originalPath ,
155+ block
159156 }
160157 }
161158
0 commit comments