@@ -13,43 +13,29 @@ import {
1313 DeleteObjectCommand ,
1414 ListObjectsV2Command
1515} 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'
1918
2019export 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-
3220 /**
3321 * Whether to try to create the bucket if it is missing when `.open` is called
3422 */
3523 createIfMissing ?: boolean
3624
3725 /**
38- * The multibase codec to use - nb. should be case insensitive.
39- * default: base32upper
26+ * Control how CIDs map to paths and back
4027 */
41- base ?: MultibaseCodec < string >
28+ shardingStrategy ?: ShardingStrategy
4229}
4330
4431/**
4532 * A blockstore backed by AWS S3
4633 */
4734export class S3Blockstore extends BaseBlockstore {
48- public path ?: string
4935 public createIfMissing : boolean
5036 private readonly s3 : S3
5137 private readonly bucket : string
52- private readonly base : MultibaseCodec < string >
38+ private readonly shardingStrategy : ShardingStrategy
5339
5440 constructor ( s3 : S3 , bucket : string , init ?: S3DatastoreInit ) {
5541 super ( )
@@ -62,21 +48,10 @@ export class S3Blockstore extends BaseBlockstore {
6248 throw new Error ( 'An bucket must be supplied. See the datastore-s3 README for examples.' )
6349 }
6450
65- this . path = init ?. path
6651 this . s3 = s3
6752 this . bucket = bucket
6853 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 ( )
8055 }
8156
8257 /**
@@ -88,7 +63,7 @@ export class S3Blockstore extends BaseBlockstore {
8863 await this . s3 . send (
8964 new PutObjectCommand ( {
9065 Bucket : this . bucket ,
91- Key : this . _getFullKey ( key ) ,
66+ Key : this . shardingStrategy . encode ( key ) ,
9267 Body : val
9368 } ) , {
9469 abortSignal : options ?. signal
@@ -110,7 +85,7 @@ export class S3Blockstore extends BaseBlockstore {
11085 const data = await this . s3 . send (
11186 new GetObjectCommand ( {
11287 Bucket : this . bucket ,
113- Key : this . _getFullKey ( key )
88+ Key : this . shardingStrategy . encode ( key )
11489 } ) , {
11590 abortSignal : options ?. signal
11691 }
@@ -154,7 +129,7 @@ export class S3Blockstore extends BaseBlockstore {
154129 await this . s3 . send (
155130 new HeadObjectCommand ( {
156131 Bucket : this . bucket ,
157- Key : this . _getFullKey ( key )
132+ Key : this . shardingStrategy . encode ( key )
158133 } ) , {
159134 abortSignal : options ?. signal
160135 }
@@ -185,7 +160,7 @@ export class S3Blockstore extends BaseBlockstore {
185160 await this . s3 . send (
186161 new DeleteObjectCommand ( {
187162 Bucket : this . bucket ,
188- Key : this . _getFullKey ( key )
163+ Key : this . shardingStrategy . encode ( key )
189164 } ) , {
190165 abortSignal : options ?. signal
191166 }
@@ -224,7 +199,7 @@ export class S3Blockstore extends BaseBlockstore {
224199 }
225200
226201 // 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 )
228203
229204 yield {
230205 cid,
@@ -257,7 +232,7 @@ export class S3Blockstore extends BaseBlockstore {
257232 await this . s3 . send (
258233 new HeadObjectCommand ( {
259234 Bucket : this . bucket ,
260- Key : this . path ?? ''
235+ Key : ''
261236 } ) , {
262237 abortSignal : options ?. signal
263238 }
0 commit comments