NoeFlandre/osm_stats / scripts /build_cache_standardize_first.py
NoeFlandre's picture
download
raw
3.27 kB
"""Build the **standardize-first** cache from the raw taginfo DB.
This is the second of the two cache build modes. It groups the
entire ``tags`` table by the standardized ``(key, value)`` expression
in SQL, sums ``count_all`` within each group, and keeps only the
groups whose merged count reaches the threshold.
It rescues rows that the filter-first path
(``scripts/build_cache_filter_first.py``, which is the default
``--build-cache`` mode of ``src.cli.cli``) would have dropped: e.g.
``landuse`` with 286 occurrences and ``Landuse`` with 450 occurrences
both individually below the threshold, but together (736) over it.
Run with:
.venv/bin/python -m scripts.build_cache_standardize_first
The new cache is written to
``/Volumes/Seagate M3/tag_features_standardize_first.sqlite`` and the
filter-first cache is left untouched.
"""
import time
from pathlib import Path
from src.config import resolve_db_path
from src.core.storage.cache import (
build_cache_db_standardize_first,
read_cache_df,
)
SOURCE_DB = "/Volumes/Seagate M3/taginfo.sqlite"
OUTPUT_CACHE = Path("/Volumes/Seagate M3/tag_features_standardize_first.sqlite")
MIN_COUNT = 500
# Reference numbers from the filter-first path. We use them at the
# end of the build to print the row/occurrence deltas, so the
# maintainer can see at a glance what the new variant rescued.
FILTER_FIRST_ROWS = 224_123
FILTER_FIRST_OCCURRENCES = 3_350_015_993
def main() -> None:
t0 = time.time()
print(f"Building standardize-first cache from {SOURCE_DB}")
print(f"Writing to {OUTPUT_CACHE}")
print(f"min_count = {MIN_COUNT:,}")
print()
print("Aggregating the full tags table by the standardized "
"(key, value) expression. This is one SQL pass over the "
"192 M-row source, so it is materially slower than the "
"filter-first streaming build.")
print()
def progress(n: int, _last: int | None) -> None:
elapsed = time.time() - t0
print(f" wrote {n:,} rows so far ({elapsed:.1f}s elapsed)")
build_cache_db_standardize_first(
SOURCE_DB,
OUTPUT_CACHE,
min_count=MIN_COUNT,
progress=progress,
)
print(f" -> done in {time.time() - t0:.1f}s")
print()
# Sanity-check the output and print deltas vs the filter-first cache.
df = read_cache_df(OUTPUT_CACHE, min_count=MIN_COUNT)
n_rows = len(df)
n_occ = int(df["count_all"].sum())
delta_rows = n_rows - FILTER_FIRST_ROWS
delta_occ = n_occ - FILTER_FIRST_OCCURRENCES
print(f"Filter-first rows: {FILTER_FIRST_ROWS:,}")
print(f"Standardize-first rows: {n_rows:,}")
print(f"Delta rows: {delta_rows:+,}")
print()
print(f"Filter-first occurrences: {FILTER_FIRST_OCCURRENCES:,}")
print(f"Standardize-first occurrences: {n_occ:,}")
print(f"Delta occurrences: {delta_occ:+,}")
print()
print(f"Cache verified: {n_rows:,} rows, columns={list(df.columns)}")
print(f"Path: {OUTPUT_CACHE}")
if __name__ == "__main__":
# Allow the source DB path to be overridden by the env var, so the
# script honors the same convention as the rest of the codebase.
SOURCE_DB = str(resolve_db_path())
main()

Xet Storage Details

Size:
3.27 kB
·
Xet hash:
37a4211ff1ae3a4f0cd8adb7d44379596b37a039a663111d575978377aadd2cb

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.