hyperdir 0.7.0

A container for inodes implemented as a Hyperfile
Documentation
# Hyperdir

A filesystem **directory namespace** on S3, implemented as a Hyperfile.

A directory is a [`hyperfile`](https://crates.io/crates/hyperfile) whose
on-disk B-tree maps a file-name hash to a directory entry `(name -> uuid +
cached inode)`. Hyperdir provides the namespace operations a filesystem needs
— create, read, rename, hard link, unlink, garbage collection — on top of
plain S3, using a scatter-then-compact commit protocol and S3 conditional
writes.

## Status

PoC. The directory protocol is implemented and validated end to end against a
real S3 bucket (see `tests/e2e_s3.rs`). See [`docs/design.md`](docs/design.md)
for the full design and the list of known limitations.

## Where it sits

```
hyperfs   FUSE filesystem (protocol, ino<->uuid)   -- separate crate
hyperdir  directory namespace (this crate)
hyperfile single file: bytes + inode on S3
```

Hyperdir owns the namespace. File byte content lives in `hyperfile`; the FUSE
protocol lives in `hyperfs`.

## Highlights

- **UUID-addressed layout** (`DIR/<uuid>`, `FILE/<uuid>`, root = nil UUID):
  identity is decoupled from path, so rename moves no data.
- **Scatter commit point**: each mutation first writes a small conditional-PUT
  object (`.inode` / `.tombstone`) into the parent directory; a later `compact`
  folds it into the B-tree. Reads (`read_dir`) are pure and concurrency-safe.
- **CRC64 collision handling** via open addressing (linear probing +
  backward-shift deletion).
- **Atomic same-directory rename**; **cross-directory rename** via a commit
  intent object with crash recovery (`fs_recover_renames`).
- **Hard links** with `nlink` authoritative in the file inode.
- **Tombstone deletion** with retention and a separate GC pass (`fs_gc`); the
  tombstone preserves the full inode to enable a future undelete.
- **Compactor leader lease** plus hyperfile's per-inode OCC for safe concurrent
  compaction.

## Layout

```
s3://<bucket>/[<base>/]DIR/<uuid>/      a directory
s3://<bucket>/[<base>/]FILE/<uuid>/     a file
s3://<bucket>/[<base>/]DIR/<nil-uuid>/  the root directory
s3://<bucket>/[<base>/]_TXN/<src_parent>_<b64(src_name)>.intent   cross-directory rename intent (source-scoped)
s3://<bucket>/[<base>/]_TXN/<ulid>.reclaim                        displaced-child reclaim intent
```

## Requirements

- `btree-ondisk 0.20.0` (handles a directory-entry value larger than the
  fixed 56-byte B-tree root, and provides `collect_meta_ptrs` — the reachability
  enumeration for a payload-leaf map like a directory). It must be the **same**
  version hyperfile pins (currently `0.6.11`, which also pins 0.20.0): hyperdir
  passes hyperfile's block loader into its own bmap, so two copies of
  btree-ondisk in one graph do not compile. See `docs/design.md` §13.
- Running the integration tests needs a large stack because debug-build async
  futures are large; export `RUST_MIN_STACK` (e.g. 64 MiB):

  ```sh
  export RUST_MIN_STACK=67108864
  export S3_BUCKET=... S3_REGION=...   # plus AWS credentials
  cargo test --test e2e_s3 -- --ignored
  ```

## Documentation

- [`docs/design.md`]docs/design.md — on-disk layout, scatter/compact
  protocol, deletion/retention/GC, rename, concurrency, constraints.

## License

This project is licensed under the Apache-2.0 License.

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.