Skip to content

Commit 1144df2

Browse files
committed
fix: minor UX fixes
1 parent 53cf091 commit 1144df2

57 files changed

Lines changed: 6693 additions & 2983 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/bench.txt

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
11
[SCALE TEST] Performance Summary:
2-
Generate 1M files: 159.22s (6281 files/sec)
3-
Commit + manifest: 63.64s (15714 files/sec)
4-
Single lookup: 7.637ms
5-
Prefix list (200): 11.124ms
6-
Bulk metadata (200): 0.031ms
7-
Cached prefix list: 9.558ms
8-
PASSED
2+
Generate 1M files: 151.99s (6579 files/sec)
3+
Commit + tree build: 52.33s (19108 files/sec)
4+
Single lookup: 10.580ms
5+
Prefix list (200): 4.811ms
6+
Bulk metadata (200): 0.037ms
7+
Cached prefix list: 5.057ms
8+
9+
[SCALE TEST] Performance Summary (v2 tree model)
10+
11+
Targets (docs/architecture.md §3 — lock into the 1M-file S3 scale test):
12+
Exact-path lookup, warm (cached tree prefixes): < 20 ms
13+
Exact-path lookup, cold worst case (depth GETs): <= ~200 ms
14+
Prefix listing, 200 files (cold): < 50 ms
15+
Prefix listing, 10k files (cold): < 300 ms
16+
Derived-manifest point lookup: < 10 ms
17+
18+
Measured locally (200k files, meta mode, 2026-08-05):
19+
Commit + tree build: 4.14s (48283 files/sec)
20+
21+
Previous v1 measurement (stale — pre-Merkle-tree commit path):
22+
Commit + manifest: 62.11s (16101 files/sec) @ 1M files (S3 scale test)

CHANGELOG.md

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,120 @@ The format is based on Keep a Changelog, and Fluxel currently tracks changes bef
88

99
### Added
1010

11+
- **Footer-stats pruning engine (rev. 3, docs/architecture.md §4)**: `fluxel query
12+
prune <ref> <path> --where "col >= x"` selects the parquet row groups that may
13+
match an AND-composed predicate (`= != < <= > >= IS NULL IS NOT NULL`) using only
14+
the compact `footers/<hash>` stats objects — no data bytes are read. Exposed as
15+
`parse_where_clause` / `prune_row_groups` / `plan_pruned_scan` in
16+
`core/query/pruning.py`; unknown columns and type mismatches keep row groups
17+
conservatively.
18+
- **Store unification (rev. 3, §12)**: `core/repository_store/` and `core/storage/`
19+
are merged into `core/objects/` — one `ObjectStore` protocol
20+
(`objects/base.py`), two adapters (`LocalObjectStore`, `S3ObjectStore`), plus
21+
`backends.py` (storage/transfer protocols), `source.py` (source-URI access,
22+
`S3StorageBackend`), and `transfer.py` (boto3/s5cmd blob transfer).
23+
- **Parquet footer capture (P1)**: with `config set parquet_footer true`, parquet
24+
files get a compact footer-stats object (schema hash + per-row-group column
25+
min/max/nulls, hand-decoded from the thrift-compact `FileMetaData`) stored
26+
under `footers/<hash>` and referenced from new `bp`/`mp` tree entries —
27+
enabling row-group pruning without reading object bytes. Unchanged files are
28+
backfilled on the next commit; `verify`-style re-scan can backfill later.
29+
- `fluxel cat <ref> <path>` prints a file's bytes from a ref; `list`, `cat`,
30+
`diff`, `log`, and `query` work on virtual refs (S3 URIs) without a local
31+
worktree.
1132
- Streaming S3 import with metadata identity mode and repeatable path filters.
12-
- Manifest sidecar indexes for exact-path and prefix-based lookups.
1333
- Staged add support for arbitrary local files, directories, S3 objects, and S3 prefixes.
1434
- Real S3 integration coverage for remote repository flows.
1535
- AGPL-3.0-or-later licensing, attribution notice, and funding metadata for the first public beta.
36+
- **Tree-based object model (v2, P0 of `docs/architecture.md`)**: commits now
37+
build Merkle tree DAGs (`trees/`) instead of full JSONL manifests. Exact
38+
lookups descend the path chain through a client-side content-addressed
39+
tree cache (0–1 GETs warm); prefix/bulk listings stream from pruned
40+
subtree walks (O(matches + depth)); the `.idx` sidecar and embedded
41+
`commit.manifest_index` are gone.
42+
- Derived manifests: a tree can be flattened to a JSONL manifest with block
43+
offsets, cached per-client keyed by the root-tree hash, for
44+
latency-critical point lookups (`export_derived_manifest`,
45+
`lookup_derived_entry`).
46+
- Directory fanout is bounded (10k entries); oversized directories split
47+
into name-range shard subtrees, keeping tree depth ≤ ~4–5 at 100M entries.
48+
- `commit --staged` re-applies the staged overlay onto a new parent and
49+
retries the CAS when a peer advanced the branch (P0 conflict-retry
50+
contract, `docs/architecture.md` §6).
51+
52+
### Changed
53+
54+
- **3-way metadata merge (P3, §9)**: diverged branches merge instead of
55+
erroring — `merge` computes the merge base (LCA), streams base/ours/theirs
56+
trees with standard merge rules (auto-keep identical additions, take the
57+
changed side, drop double-removals), and creates a merge commit with two
58+
parents when histories diverge; conflicting paths raise
59+
`MergeConflictError` with the offending paths.
60+
- `fluxel reflog` (P3): every successful ref update is recorded per-branch in
61+
client state (old → new commit, operation, timestamp); `fluxel catalog`
62+
lists branches with their heads and messages.
63+
- **Plan-then-batch sync (P2, §7)**: `push`/`pull`/`fetch` now compute the exact
64+
missing-object set (commits, trees, footers, blobs) as a transfer plan and
65+
execute it in one batch through the s5cmd backend (manifest file) or
66+
per-object through boto3, with an optional progress callback. Parquet
67+
footer stats objects now sync too.
68+
- **Adapter error translation (P2, §8)**: the S3 adapters raise domain errors
69+
(`ObjectMissingError`, `PreconditionFailedError`, `StorageUnavailableError`,
70+
all `FluxelError` subclasses) instead of raw botocore exceptions; the CLI no
71+
longer special-cases `BotoCoreError`/`ClientError`.
72+
- `fluxel gc` (P2, §11): audit-only by default — computes the reachable set
73+
from all refs (commit DAG → trees → blobs/footers) and reports orphans;
74+
`--prune` deletes them.
75+
- `filesystem.py` moved to the `core/vfs/` package; `index.py` moved to the
76+
`core/query/` package (DuckDB catalog now carries a `footer` column); the
77+
CLI subcommand `index build` is now `query build`.
78+
- `CommitObject` is now `{id, message, tree, parents: [...], created_at,
79+
branch, generation}`; the `manifest`/`parent`/`manifest_index` fields are
80+
gone. `SnapshotWriter` is replaced by `TreeWriter`
81+
(`services/tree.py`).
82+
- Stores are `ObjectStore + RefStore + TreeQuerier`; S3 branch-lock
83+
machinery (locks, `lock list`, `lock cleanup`) is removed — version-token
84+
CAS is the only safety primitive.
85+
- Full commits preserve parent-only entries and staged additions (v1 merge
86+
semantics); deletions require explicit staging, as before.
87+
- Commit creation is faster than v1 in metadata mode (no per-file entry
88+
objects; ~48k files/sec on the 200k-file meta benchmark).
89+
90+
### Removed
91+
92+
- Removed `manifest_index.py`, `manifest_query.py`, `.idx` sidecars, the
93+
embedded manifest index, and the index/fallback decision tree.
94+
95+
### Fixed
96+
97+
- Manifest parsing now validates entry shape, digests, and metadata-only invariants with line-aware errors.
98+
- Commit creation is back to near-pre-refactor throughput: the commit hot loop now streams serialized manifest lines from the worktree instead of constructing and validating a `ManifestEntry` object per file (~2× faster for metadata-only commits; validated again on read).
1699

17100
### Changed
18101

19102
- CLI examples and tests now prefer `--repo` repository selection semantics.
20103
- Client-local state writes now use atomic replace semantics for HEAD and staging payloads.
21104
- Manifest index prefix iteration now streams rows instead of materializing full result sets.
105+
- Manifest exact-path and prefix lookups now fall back to a full manifest scan when no index is available, so legacy or index-less repositories remain fully readable.
106+
- `status(ref=...)` working-tree comparison now honors the requested branch instead of always comparing against the currently checked-out branch.
107+
- The `RepositoryStore` contract is now split into focused `ObjectStore`, `RefStore`, `ManifestIndexStore`, and `ManifestQuerier` protocols, with `RepositoryStore` kept as the composed facade for compatibility.
108+
- Manifest index lookups are deduplicated into a single shared implementation (`repository_store/manifest_query.py`) used by both local and S3 stores.
109+
- Commit creation no longer relies on `_last_manifest_index` instance state; the manifest index is threaded explicitly through manifest writing and commit creation.
110+
- S3 blob writes via streams (`push`/`pull`/`fetch`) now honor the configured blob transfer backend, so `s5cmd` accelerates sync transfers.
111+
- The in-process commit cache is now bounded (LRU-style) instead of growing without limit.
112+
- `FluxelRepository` is now a facade over four focused collaborator services (`RefManager`, `SnapshotWriter`, `StagingArea`, `EntryFactory` in `core/services/`); the god-object class was split from ~1650 to ~790 lines and `repository_ops.py` no longer reaches into repository internals.
113+
114+
### Removed
115+
116+
- Removed the `fluxel import` command; S3 ingress is now staged via `fluxel add ... s3://... [--identity meta --as ...]` followed by `fluxel commit --staged`.
117+
- Removed `--identity` from `fluxel commit`; the commit identity mode is now configured with `fluxel config set identity meta`, or set per stage with `fluxel add --identity ...`.
118+
- Removed the direct-commit `-m/--message` flag from `fluxel rm` and `fluxel mv`; metadata-only mutations are staged and committed with `fluxel commit --staged`.
119+
- Removed `--ref` from `fluxel verify` and `fluxel index build`; both now target the current branch.
120+
- Removed `fluxel index query` and `fluxel index drop`; `fluxel index build` remains and the produced DuckDB database can be queried with the DuckDB CLI.
22121

23122
### Fixed
24123

25124
- Manifest parsing now validates entry shape, digests, and metadata-only invariants with line-aware errors.
125+
- Commit creation is back to near-pre-refactor throughput: the commit hot loop now streams serialized manifest lines from the worktree instead of constructing and validating a `ManifestEntry` object per file (~2× faster for metadata-only commits; validated again on read).
26126
- CLI commands now return clean `... error:` messages for common validation, filesystem, and object-storage failures instead of raw tracebacks.
27127
- Corrupt S3-hosted manifest lines now surface actionable validation errors.

LAUNCH_TODO.md

Lines changed: 0 additions & 103 deletions
This file was deleted.

0 commit comments

Comments
 (0)