@@ -6,14 +6,13 @@ const crypto = require('crypto')
6
6
const fixOwner = require ( './util/fix-owner' )
7
7
const fs = require ( 'graceful-fs' )
8
8
const path = require ( 'path' )
9
- const pipe = require ( 'mississippi' ) . pipe
10
9
const Promise = require ( 'bluebird' )
11
- const split = require ( 'split' )
12
10
const through = require ( 'mississippi' ) . through
13
11
14
12
const indexV = require ( '../package.json' ) [ 'cache-version' ] . index
15
13
16
14
const appendFileAsync = Promise . promisify ( fs . appendFile )
15
+ const readFileAsync = Promise . promisify ( fs . readFile )
17
16
18
17
module . exports . insert = insert
19
18
function insert ( cache , key , digest , opts ) {
@@ -50,32 +49,20 @@ function insert (cache, key, digest, opts) {
50
49
module . exports . find = find
51
50
function find ( cache , key ) {
52
51
const bucket = bucketPath ( cache , key )
53
- const stream = fs . createReadStream ( bucket )
54
- let ret
55
- return Promise . fromNode ( cb => {
56
- pipe ( stream , split ( '\n' , null , { trailing : true } ) . on ( 'data' , function ( l ) {
57
- const pieces = l . split ( '\t' )
58
- if ( ! pieces [ 1 ] || pieces [ 1 ] . length !== parseInt ( pieces [ 0 ] , 10 ) ) {
59
- // Length is no good! Corruption ahoy!
60
- return
61
- }
62
- let obj
63
- try {
64
- obj = JSON . parse ( pieces [ 1 ] )
65
- } catch ( e ) {
66
- // Entry is corrupted!
67
- return
68
- }
69
- if ( obj && ( obj . key === key ) ) {
70
- ret = formatEntry ( cache , obj )
71
- }
72
- } ) , function ( err ) {
73
- if ( err && err . code === 'ENOENT' ) {
74
- cb ( null , null )
52
+ return bucketEntries ( cache , bucket ) . then ( entries => {
53
+ return entries . reduce ( ( latest , next ) => {
54
+ if ( next && next . key === key ) {
55
+ return formatEntry ( cache , next )
75
56
} else {
76
- cb ( err , ret )
57
+ return latest
77
58
}
78
- } )
59
+ } , null )
60
+ } ) . catch ( err => {
61
+ if ( err . code === 'ENOENT' ) {
62
+ return null
63
+ } else {
64
+ throw err
65
+ }
79
66
} )
80
67
}
81
68
@@ -102,38 +89,27 @@ function lsStream (cache) {
102
89
return cb ( err )
103
90
} else {
104
91
asyncMap ( files , function ( f , cb ) {
105
- fs . readFile ( path . join ( indexDir , bucket , f ) , 'utf8' , function ( err , data ) {
106
- if ( err ) { return cb ( err ) }
107
- const entries = { }
108
- data . split ( '\n' ) . slice ( 1 ) . forEach ( function ( entry ) {
109
- const pieces = entry . split ( '\t' )
110
- if ( pieces [ 1 ] . length !== parseInt ( pieces [ 0 ] , 10 ) ) {
111
- // Length is no good! Corruption ahoy!
112
- return
113
- }
114
- let parsed
115
- try {
116
- parsed = JSON . parse ( pieces [ 1 ] )
117
- } catch ( e ) {
118
- }
119
- // NOTE - it's possible for an entry to be
120
- // incomplete/corrupt. So we just skip it.
121
- // See comment on `insert()` for deets.
122
- if ( parsed ) {
123
- entries [ parsed . key ] = formatEntry ( cache , parsed )
124
- }
125
- } )
92
+ const bpath = path . join ( indexDir , bucket , f )
93
+ bucketEntries ( cache , bpath ) . then ( _entries => {
94
+ const entries = _entries . reduce ( ( acc , entry ) => {
95
+ acc [ entry . key ] = entry
96
+ return acc
97
+ } , { } )
126
98
Object . keys ( entries ) . forEach ( function ( k ) {
127
- stream . write ( entries [ k ] )
99
+ stream . write ( formatEntry ( cache , entries [ k ] ) )
128
100
} )
129
101
cb ( )
102
+ } , err => {
103
+ if ( err . code === 'ENOENT' ) {
104
+ cb ( )
105
+ } else {
106
+ cb ( err )
107
+ }
130
108
} )
131
- } , function ( err ) {
132
- cb ( err )
133
- } )
109
+ } , cb )
134
110
}
135
111
} )
136
- } , err => {
112
+ } , function ( err ) {
137
113
if ( err ) { stream . emit ( 'error' ) }
138
114
stream . end ( )
139
115
} )
@@ -163,6 +139,32 @@ function notFoundError (cache, key) {
163
139
return err
164
140
}
165
141
142
+ function bucketEntries ( cache , bucket , filter ) {
143
+ return readFileAsync (
144
+ bucket , 'utf8'
145
+ ) . then ( data => {
146
+ let entries = [ ]
147
+ data . split ( '\n' ) . forEach ( entry => {
148
+ const pieces = entry . split ( '\t' )
149
+ if ( ! pieces [ 1 ] || pieces [ 1 ] . length !== parseInt ( pieces [ 0 ] , 10 ) ) {
150
+ // Length is no good! Corruption ahoy!
151
+ return
152
+ }
153
+ let obj
154
+ try {
155
+ obj = JSON . parse ( pieces [ 1 ] )
156
+ } catch ( e ) {
157
+ // Entry is corrupted!
158
+ return
159
+ }
160
+ if ( obj ) {
161
+ entries . push ( obj )
162
+ }
163
+ } )
164
+ return entries
165
+ } )
166
+ }
167
+
166
168
function bucketDir ( cache ) {
167
169
return path . join ( cache , `index-v${ indexV } ` )
168
170
}
0 commit comments