Skip to content

Commit 7c79086

Browse files
committed
v2.0.1: add storage_class_distribution to stats, --verbose flag for CLI
1 parent 0e31a9d commit 7c79086

5 files changed

Lines changed: 37 additions & 2 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "farchive"
3-
version = "2.0.0"
3+
version = "2.0.1"
44
description = "Local content-addressed archive with locator-scoped history for opaque bytes."
55
requires-python = ">=3.11"
66
dependencies = [

src/farchive/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@
2121
"RepackStats",
2222
"StateSpan",
2323
]
24-
__version__ = "2.0.0"
24+
__version__ = "2.0.1"

src/farchive/_archive.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,6 +1379,18 @@ def stats(self) -> ArchiveStats:
13791379
entry["logical_stored"] = logical
13801380
codec_dist[row[0]] = entry
13811381

1382+
storage_class_dist: dict[str, dict] = {}
1383+
for row in self._conn.execute(
1384+
"SELECT COALESCE(storage_class, '(none)'), COUNT(*), "
1385+
"SUM(raw_size), SUM(stored_self_size) "
1386+
"FROM blob GROUP BY storage_class",
1387+
).fetchall():
1388+
storage_class_dist[row[0]] = {
1389+
"count": row[1],
1390+
"raw": row[2],
1391+
"stored": row[3],
1392+
}
1393+
13821394
return ArchiveStats(
13831395
locator_count=loc_count,
13841396
blob_count=blob_count,
@@ -1388,6 +1400,7 @@ def stats(self) -> ArchiveStats:
13881400
total_stored_bytes=total_stored,
13891401
compression_ratio=(totals[0] / total_stored) if total_stored else None,
13901402
codec_distribution=codec_dist,
1403+
storage_class_distribution=storage_class_dist,
13911404
db_path=str(self._db_path),
13921405
schema_version=db_version,
13931406
chunk_count=chunk_count,

src/farchive/_cli.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,24 @@ def _cmd_stats(args: argparse.Namespace) -> None:
3838
f" {key:<12} {d['count']:>8,} blobs "
3939
f"{d['raw']:>12,} raw {d['stored']:>12,} stored ({r:.1f}x)"
4040
)
41+
if st.storage_class_distribution:
42+
classes = sorted(
43+
st.storage_class_distribution.items(),
44+
key=lambda kv: kv[1]["stored"],
45+
reverse=True,
46+
)
47+
if not args.verbose:
48+
classes = classes[:10]
49+
print("\nStorage class distribution:")
50+
for key, d in classes:
51+
r = d["raw"] / d["stored"] if d["stored"] else 0
52+
print(
53+
f" {key:<12} {d['count']:>8,} blobs "
54+
f"{d['raw']:>12,} raw {d['stored']:>12,} stored ({r:.1f}x)"
55+
)
56+
if not args.verbose and len(st.storage_class_distribution) > 10:
57+
remaining = len(st.storage_class_distribution) - 10
58+
print(f" ... and {remaining} more class(es) (use --verbose to show all)")
4159

4260

4361
def _cmd_history(args: argparse.Namespace) -> None:
@@ -205,6 +223,9 @@ def main(argv: list[str] | None = None) -> None:
205223
# stats
206224
p = sub.add_parser("stats", help="Show archive statistics")
207225
p.add_argument("db", nargs="?", default=_DEFAULT_DB, help="DB path")
226+
p.add_argument(
227+
"-v", "--verbose", action="store_true", help="Show all storage classes"
228+
)
208229

209230
# history
210231
p = sub.add_parser("history", help="Show span history for a locator")

src/farchive/_types.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ class ArchiveStats:
111111
total_stored_bytes: int
112112
compression_ratio: float | None
113113
codec_distribution: dict[str, dict]
114+
storage_class_distribution: dict[str, dict]
114115
db_path: str
115116
schema_version: int
116117
chunk_count: int

0 commit comments

Comments
 (0)