cas #
A content-addressable heap with typed digests, for OCaml.
Git, Irmin and the AT Protocol all store immutable blocks under the hash of
their contents, and keep a few mutable names (branches, heads) that point at
those hashes. cas provides that layer once. Cas.Hash gives SHA-1 and
SHA-256 digests distinct types, so a Git object id cannot be used where an
ATProto block key is expected. Cas.Heap stores blocks under their hashes,
binds names to hashes with refs that support compare-and-set, and composes
heaps with combinators. layer top bottom reads from top first and falls
back to bottom, writes to top, and copies into top every block it finds
in bottom, as a cache in front of a store. recording heap behaves as
heap and also keeps every block a find returned; a proof collects the
blocks one computation read this way. It interprets neither
the contents of a block nor any file path: a codec above it decides what a
block means, and a backend below it decides where blocks live.
The cas library is pure. A storage backend implements Cas.Heap.BACKEND,
and Cas.Heap.Make (Backend).v turns a backend handle into a heap. The
companion package cas-eio provides Cas_eio.Fs, a durable SHA-256 heap in a
directory, which refuses a write whose key is not the digest of its block and
checks stored bytes on every read.
Installation #
$ opam install cas cas-eio
If opam cannot find the packages, they may not yet be released in the public
opam-repository. Add the overlay repository, then install them:
$ opam repo add samoht https://tangled.org/gazagnaire.org/opam-overlay.git
$ opam update
$ opam install cas cas-eio
Usage #
Store a block in an in-memory heap under its SHA-256 digest:
Cas.Heap.read_only ~name heap preserves reads while refusing every mutating
operation with an error that names the store. The cas-eio package provides
Cas_eio.Fs.read_only ~dir to open a filesystem heap without creating a
missing store or modifying an existing one.
module Memory = Cas.Heap.Mem (struct
type hash = Cas.Hash.sha256
type block = string
let equal = Cas.Hash.equal
let hash = Cas.Hash.hash
end)
let heap = Memory.v ()
let block = "hello"
let key = Cas.Hash.sha256 block
let () = Cas.Heap.put heap key block
Cas.Heap.Content_addressed wraps any heap so that a put whose key differs
from the digest of its block is refused, and a find that reads a block stored
under the wrong key raises Cas.Heap.Integrity_error.
API #
Cas.Hashprovides typed SHA-1 and SHA-256 digests, their raw and hexadecimal forms, comparison, andCas.Hash.anyfor stores that mix both algorithms.Cas.Heapprovides block lookup, insertion and enumeration, named refs with compare-and-set, the combinatorslayer,recordingandof_list, theContent_addressedcheck and the in-memory heapMem.Cas_eio.Fsprovides the filesystem heap.
Licence #
ISC. See LICENSE.md.