| 1 | """Disk-usage measurement shared by the mount and contention lanes.
|
| 2 |
|
| 3 | Visible bytes (st_size) and allocated bytes (st_blocks * 512) diverge on
|
| 4 | lazily-hydrated trees: a mount can show a full-size tree while having
|
| 5 | allocated almost nothing. Reporting both is what lets the marginal-disk
|
| 6 | claim survive scrutiny; collapsing them would overstate either side.
|
| 7 |
|
| 8 | stat() never reads file content, so walking a lazy mount with this probe
|
| 9 | does not itself hydrate data.
|
| 10 | """
|
| 11 |
|
| 12 | from __future__ import annotations
|
| 13 |
|
| 14 | import os
|
| 15 | from pathlib import Path
|
| 16 | from typing import Any
|
| 17 |
|
| 18 | DEFAULT_MAX_ENTRIES = 200_000
|
| 19 |
|
| 20 |
|
| 21 | def bounded_tree_usage(root: Path, max_entries: int = DEFAULT_MAX_ENTRIES) -> dict[str, Any]:
|
| 22 | visible_bytes = 0
|
| 23 | allocated_bytes = 0
|
| 24 | entry_count = 0
|
| 25 | truncated = False
|
| 26 | if not root.exists():
|
| 27 | return {
|
| 28 | "visible_tree_bytes": 0,
|
| 29 | "allocated_tree_bytes": 0,
|
| 30 | "disk_entry_count": 0,
|
| 31 | "disk_usage_truncated": False,
|
| 32 | "checks": {"ok": False, "exists": False},
|
| 33 | }
|
| 34 | for dirpath, dirnames, filenames in os.walk(root):
|
| 35 | entry_count += 1
|
| 36 | if entry_count >= max_entries:
|
| 37 | truncated = True
|
| 38 | dirnames[:] = []
|
| 39 | break
|
| 40 | for name in filenames:
|
| 41 | entry_count += 1
|
| 42 | path = Path(dirpath) / name
|
| 43 | try:
|
| 44 | stat = path.lstat()
|
| 45 | except OSError:
|
| 46 | continue
|
| 47 | visible_bytes += stat.st_size
|
| 48 | allocated_bytes += int(getattr(stat, "st_blocks", 0)) * 512
|
| 49 | if entry_count >= max_entries:
|
| 50 | truncated = True
|
| 51 | dirnames[:] = []
|
| 52 | break
|
| 53 | return {
|
| 54 | "visible_tree_bytes": visible_bytes,
|
| 55 | "allocated_tree_bytes": allocated_bytes,
|
| 56 | "disk_entry_count": entry_count,
|
| 57 | "disk_usage_truncated": truncated,
|
| 58 | "checks": {"ok": True, "exists": True},
|
| 59 | }
|