I'm already using some components from DASL in my project, and needed to shard and store some blobs, so I tried to do it the IPFS way! I'm documenting my approach, and suggesting that it be a new standard. Here is the proposed standard:
CASL defines a deterministic mapping from a CID ([[cid]]) to a sharded storage path, suitable for filesystems and object stores that need to store large numbers of content-addressed payloads. CASL standardizes only the “where does this CID live in the store?” question; it does not define chunking, DAG layouts, replication, or transport.
Introduction
Storing hundreds of thousands (or millions) of CID-addressed resources in a single directory (or under a small number of object-store prefixes) is operationally expensive and can become a performance bottleneck. CASL provides a deterministic sharding rule so that independent implementations can store and locate content-addressed payloads consistently.
The key words “MUST”, “MUST NOT”, “SHOULD”, “SHOULD NOT”, and “MAY” are to be interpreted as described in RFC 2119 ([[rfc2119]]).
CASL is intentionally narrow in scope. It does not define block chunking, Merkle DAG layout, or retrieval/replication behavior. CASL is only about mapping a CID to a storage path.
Terminology
Storage root
An implementation-defined directory or object-store prefix under which CASL paths are constructed.
CASL key
A deterministic string derived from the CID’s multihash bytes. It is used for sharding and for the leaf name by default.
Shard
A short string used as a directory (or prefix) component to distribute objects across buckets.
Deriving a CASL Key
CASL sharding operates over a CASL key, derived from the CID’s multihash bytes. CASL does not shard on the CID’s string form.
Use the following steps to derive a CASL key:
Accept a CID in either string form or bytes form ([[cid]]).
Decode the CID to obtain its multihash bytes (hash function code, digest length, and digest) ([[cid]]).
Base32-encode the multihash bytes using the base32 algorithm from RFC 4648 ([[rfc4648]]) with:
the RFC 4648 alphabet (A–Z and 2–7),
no padding characters,
and an uppercase output.
Store the resulting string in key.
Return key.
NOTE: This style of key is compatible with the character restrictions used by FlatFS-style filesystem datastores (e.g. the FlatFS implementation used by Kubo).
Sharding
CASL’s default sharding rule is next-to-last/2: it takes the two characters immediately preceding the last character of the CASL key.
Use the following steps to compute a next-to-last shard:
Accept a string key and an integer suffixLen.
If suffixLen is less than 1, throw an error.
If the length of key is less than suffixLen + 1, prepend _ characters to key until its length is suffixLen + 1.
Return the substring of key that consists of the suffixLen characters immediately preceding the final character of key.
Use the following steps to derive a CASL shard:
Let key be the result of running the steps to derive a CASL key.
Let shard be the result of running the steps to compute a next-to-last shard with suffixLen set to 2.
Return shard.
NOTE: The next-to-last/2 rule matches the FlatFS default sharding function used in Kubo’s FlatFS block storage (as defined by the FlatFS implementation’s default shard constant).
Path Construction
A CASL path is constructed from a storage root, a shard, and a leaf name.
Use the following steps to construct a CASL path:
Accept a string root and a CID cid.
Let key be the result of running the steps to derive a CASL key on cid.
Let shard be the result of running the steps to derive a CASL shard on key.
Let name be key. Implementations MAY append a deterministic, store-wide extension (for example, .data), but if they do, it MUST be applied consistently for all objects in that store.
Return the concatenation: <root>/<shard>/<name>.
Example
Given CID: bafkreifn5yxi7nkftsn46b6x26grda57ict7md2xuvfbsgkiahe2e7vnq4
The CASL key (base32 of the multihash bytes, uppercase, no padding) is: CIQK33ROR62ULHE3Z4D5PV4NCGB36QFH6YHVPJKKDEMUQAOJUJ7K3BY
The CASL shard (next-to-last/2) is: 3B
The CASL path (for some chosen root) is: <root>/3B/CIQK33ROR62ULHE3Z4D5PV4NCGB36QFH6YHVPJKKDEMUQAOJUJ7K3BY
I'm already using some components from DASL in my project, and needed to shard and store some blobs, so I tried to do it the IPFS way! I'm documenting my approach, and suggesting that it be a new standard. Here is the proposed standard:
CASL defines a deterministic mapping from a CID ([[cid]]) to a sharded storage path, suitable for filesystems and object stores that need to store large numbers of content-addressed payloads. CASL standardizes only the “where does this CID live in the store?” question; it does not define chunking, DAG layouts, replication, or transport.
Introduction
Storing hundreds of thousands (or millions) of CID-addressed resources in a single directory (or under a small number of object-store prefixes) is operationally expensive and can become a performance bottleneck. CASL provides a deterministic sharding rule so that independent implementations can store and locate content-addressed payloads consistently.
The key words “MUST”, “MUST NOT”, “SHOULD”, “SHOULD NOT”, and “MAY” are to be interpreted as described in RFC 2119 ([[rfc2119]]).
CASL is intentionally narrow in scope. It does not define block chunking, Merkle DAG layout, or retrieval/replication behavior. CASL is only about mapping a CID to a storage path.
Terminology
Storage root
An implementation-defined directory or object-store prefix under which CASL paths are constructed.
CASL key
A deterministic string derived from the CID’s multihash bytes. It is used for sharding and for the leaf name by default.
Shard
A short string used as a directory (or prefix) component to distribute objects across buckets.
Deriving a CASL Key
CASL sharding operates over a CASL key, derived from the CID’s multihash bytes. CASL does not shard on the CID’s string form.
Use the following steps to derive a CASL key:
NOTE: This style of key is compatible with the character restrictions used by FlatFS-style filesystem datastores (e.g. the FlatFS implementation used by Kubo).
Sharding
CASL’s default sharding rule is next-to-last/2: it takes the two characters immediately preceding the last character of the CASL key.
Use the following steps to compute a next-to-last shard:
Use the following steps to derive a CASL shard:
NOTE: The next-to-last/2 rule matches the FlatFS default sharding function used in Kubo’s FlatFS block storage (as defined by the FlatFS implementation’s default shard constant).
Path Construction
A CASL path is constructed from a storage root, a shard, and a leaf name.
Use the following steps to construct a CASL path:
Example
Given CID: bafkreifn5yxi7nkftsn46b6x26grda57ict7md2xuvfbsgkiahe2e7vnq4