@@ -13,43 +13,29 @@ import {
13
13
DeleteObjectCommand ,
14
14
ListObjectsV2Command
15
15
} from '@aws-sdk/client-s3'
16
- import { CID } from 'multiformats/cid'
17
- import { base32upper } from 'multiformats/bases/base32'
18
- import type { MultibaseCodec } from 'multiformats/bases/interface'
16
+ import type { CID } from 'multiformats/cid'
17
+ import { NextToLast , ShardingStrategy } from './sharding.js'
19
18
20
19
export interface S3DatastoreInit {
21
- /**
22
- * An optional path to use within the bucket for all files - this setting can
23
- * affect S3 performance as it does internal sharding based on 'prefixes' -
24
- * these can be delimited by '/' so it's often better to wrap this datastore in
25
- * a sharding datastore which will generate prefixed datastore keys for you.
26
- *
27
- * See - https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance.html
28
- * and https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-prefixes.html
29
- */
30
- path ?: string
31
-
32
20
/**
33
21
* Whether to try to create the bucket if it is missing when `.open` is called
34
22
*/
35
23
createIfMissing ?: boolean
36
24
37
25
/**
38
- * The multibase codec to use - nb. should be case insensitive.
39
- * default: base32upper
26
+ * Control how CIDs map to paths and back
40
27
*/
41
- base ?: MultibaseCodec < string >
28
+ shardingStrategy ?: ShardingStrategy
42
29
}
43
30
44
31
/**
45
32
* A blockstore backed by AWS S3
46
33
*/
47
34
export class S3Blockstore extends BaseBlockstore {
48
- public path ?: string
49
35
public createIfMissing : boolean
50
36
private readonly s3 : S3
51
37
private readonly bucket : string
52
- private readonly base : MultibaseCodec < string >
38
+ private readonly shardingStrategy : ShardingStrategy
53
39
54
40
constructor ( s3 : S3 , bucket : string , init ?: S3DatastoreInit ) {
55
41
super ( )
@@ -62,21 +48,10 @@ export class S3Blockstore extends BaseBlockstore {
62
48
throw new Error ( 'An bucket must be supplied. See the datastore-s3 README for examples.' )
63
49
}
64
50
65
- this . path = init ?. path
66
51
this . s3 = s3
67
52
this . bucket = bucket
68
53
this . createIfMissing = init ?. createIfMissing ?? false
69
- this . base = init ?. base ?? base32upper
70
- }
71
-
72
- /**
73
- * Returns the full key which includes the path to the ipfs store
74
- */
75
- _getFullKey ( cid : CID ) : string {
76
- // Avoid absolute paths with s3
77
- const str = this . base . encoder . encode ( cid . multihash . bytes )
78
-
79
- return [ this . path , str ] . filter ( Boolean ) . join ( '/' ) . replace ( / \/ \/ + / g, '/' )
54
+ this . shardingStrategy = init ?. shardingStrategy ?? new NextToLast ( )
80
55
}
81
56
82
57
/**
@@ -88,7 +63,7 @@ export class S3Blockstore extends BaseBlockstore {
88
63
await this . s3 . send (
89
64
new PutObjectCommand ( {
90
65
Bucket : this . bucket ,
91
- Key : this . _getFullKey ( key ) ,
66
+ Key : this . shardingStrategy . encode ( key ) ,
92
67
Body : val
93
68
} ) , {
94
69
abortSignal : options ?. signal
@@ -110,7 +85,7 @@ export class S3Blockstore extends BaseBlockstore {
110
85
const data = await this . s3 . send (
111
86
new GetObjectCommand ( {
112
87
Bucket : this . bucket ,
113
- Key : this . _getFullKey ( key )
88
+ Key : this . shardingStrategy . encode ( key )
114
89
} ) , {
115
90
abortSignal : options ?. signal
116
91
}
@@ -154,7 +129,7 @@ export class S3Blockstore extends BaseBlockstore {
154
129
await this . s3 . send (
155
130
new HeadObjectCommand ( {
156
131
Bucket : this . bucket ,
157
- Key : this . _getFullKey ( key )
132
+ Key : this . shardingStrategy . encode ( key )
158
133
} ) , {
159
134
abortSignal : options ?. signal
160
135
}
@@ -185,7 +160,7 @@ export class S3Blockstore extends BaseBlockstore {
185
160
await this . s3 . send (
186
161
new DeleteObjectCommand ( {
187
162
Bucket : this . bucket ,
188
- Key : this . _getFullKey ( key )
163
+ Key : this . shardingStrategy . encode ( key )
189
164
} ) , {
190
165
abortSignal : options ?. signal
191
166
}
@@ -224,7 +199,7 @@ export class S3Blockstore extends BaseBlockstore {
224
199
}
225
200
226
201
// Remove the path from the key
227
- const cid = CID . decode ( this . base . decoder . decode ( d . Key . slice ( ( this . path ?? '' ) . length ) ) )
202
+ const cid = this . shardingStrategy . decode ( d . Key )
228
203
229
204
yield {
230
205
cid,
@@ -257,7 +232,7 @@ export class S3Blockstore extends BaseBlockstore {
257
232
await this . s3 . send (
258
233
new HeadObjectCommand ( {
259
234
Bucket : this . bucket ,
260
- Key : this . path ?? ''
235
+ Key : ''
261
236
} ) , {
262
237
abortSignal : options ?. signal
263
238
}
0 commit comments