From 4a1fb3c3bd2c4ef85512cda1435b4aa93c33439f Mon Sep 17 00:00:00 2001 From: Yifeng He Date: Fri, 6 Feb 2026 19:40:31 -0800 Subject: [PATCH 1/9] refactor: move gamecov-core Rust crate into monorepo --- .gitignore | 5 +- AGENTS.md | 29 +- README.md | 26 ++ gamecov-core/Cargo.lock | 438 +++++++++++++++++++++++++++++++ gamecov-core/Cargo.toml | 19 ++ gamecov-core/pyproject.toml | 18 ++ gamecov-core/src/bktree.rs | 168 ++++++++++++ gamecov-core/src/lib.rs | 126 +++++++++ gamecov-core/src/monitor.rs | 131 +++++++++ gamecov-core/src/unionfind.rs | 132 ++++++++++ gamecov-core/tests/prop_tests.rs | 176 +++++++++++++ pyproject.toml | 1 - src/gamecov/__init__.py | 9 +- src/gamecov/frame_cov.py | 73 +++++- tests/test_rust_frame_monitor.py | 133 ++++++++++ uv.lock | 2 - 16 files changed, 1471 insertions(+), 15 deletions(-) create mode 100644 gamecov-core/Cargo.lock create mode 100644 gamecov-core/Cargo.toml create mode 100644 gamecov-core/pyproject.toml create mode 100644 gamecov-core/src/bktree.rs create mode 100644 gamecov-core/src/lib.rs create mode 100644 gamecov-core/src/monitor.rs create mode 100644 gamecov-core/src/unionfind.rs create mode 100644 gamecov-core/tests/prop_tests.rs create mode 100644 tests/test_rust_frame_monitor.py diff --git a/.gitignore b/.gitignore index a250447..d5fdddc 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,7 @@ assets/ .vscode/ .hypothesis/ prof/ -.coverage \ No newline at end of file +.coverage + +# Rust build artifacts +gamecov-core/target/ diff --git a/AGENTS.md b/AGENTS.md index 54931df..c60ee78 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -20,7 +20,7 @@ Future metrics (e.g., audio coverage, state-graph coverage) will follow the same │ ├── cov_base.py # Abstract protocols: CoverageItem, Coverage, CoverageMonitor │ ├── frame.py # Frame dataclass (PIL Image wrapper with average-hash) │ ├── dedup.py # Deduplication algorithms (pHash, SSIM [deprecated]) -│ ├── frame_cov.py # FrameCoverage, FrameMonitor, BKFrameMonitor, BK-tree, UnionFind +│ ├── frame_cov.py # FrameCoverage, FrameMonitor, BKFrameMonitor, RustBKFrameMonitor, BK-tree, UnionFind │ ├── loader.py # MP4 loading: bulk, lazy (generator), last-n │ ├── writer.py # MP4 writing: imageio and OpenCV backends │ ├── stitch.py # Panorama stitching of unique frames @@ -35,6 +35,7 @@ Future metrics (e.g., audio coverage, state-graph coverage) will follow the same │ ├── test_load_write_assets.py# Differential tests across loaders on real videos │ ├── test_monotone.py # Coverage monotonicity (FrameMonitor & BKFrameMonitor) │ ├── test_BK_frame_monitor.py # Differential: FrameMonitor vs BKFrameMonitor +│ ├── test_rust_frame_monitor.py # Differential & monotonicity: BKFrameMonitor vs RustBKFrameMonitor │ └── test_monotone_smb.py # Real-world monotonicity on SMB dataset ├── assets/ │ ├── videos/ # Small sample MP4s for integration tests @@ -48,6 +49,26 @@ Future metrics (e.g., audio coverage, state-graph coverage) will follow the same └── README.md # Human-facing documentation ``` +### gamecov-core (Rust extension) + +The `gamecov-core/` subdirectory contains a Rust crate (PyO3/maturin) providing +high-performance replacements for the BK-tree, union-find, and coverage tracker. + +``` +gamecov-core/ +├── Cargo.toml +├── pyproject.toml +├── src/ +│ ├── lib.rs # PyO3 module: BKTree, UnionFind, CoverageTracker +│ ├── bktree.rs # BK-tree with POPCNT Hamming distance +│ ├── unionfind.rs # Flat Vec-based union-find +│ └── monitor.rs # CoverageTracker (BK-tree + UnionFind combined) +└── tests/ + └── prop_tests.rs # proptest property-based tests +``` + +Build with: `cd gamecov-core && maturin develop --release` + ## Design See [docs/design.md](docs/design.md) for the coverage framework architecture, frame coverage pipeline, BK-tree optimization, and loading strategies. @@ -59,7 +80,7 @@ See [docs/design.md](docs/design.md) for the coverage framework architecture, fr | `cov_base.py` | `CoverageItem`, `Coverage[T]`, `CoverageMonitor[T]` protocols/ABC | | `frame.py` | `Frame` dataclass (PIL Image + average-hash) | | `dedup.py` | `is_dup()`, `dedup_unique_frames()`, `dedup_unique_hashes()`, `ssim_dedup()` [deprecated] | -| `frame_cov.py` | `FrameCoverage`, `FrameMonitor`, `BKFrameMonitor`, `get_frame_cov()`, `_UnionFind`, `_BKTree` | +| `frame_cov.py` | `FrameCoverage`, `FrameMonitor`, `BKFrameMonitor`, `RustBKFrameMonitor`, `get_frame_cov()`, `_UnionFind`, `_BKTree` | | `loader.py` | `load_mp4()`, `load_mp4_lazy()`, `load_mp4_last_n()` | | `writer.py` | `write_mp4()`, `write_mp4_cv2()` | | `stitch.py` | `stitch_images()` (panorama via AffineStitcher) | @@ -80,7 +101,8 @@ See [docs/design.md](docs/design.md) for the coverage framework architecture, fr | `opencv-python` | Color conversion, video writing, image processing | | `scikit-image` | SSIM metric (deprecated path) | | `stitching` | Panorama stitching via OpenCV features | -| `numpy`, `numba` | Numerical arrays, optional JIT acceleration | +| `numpy` | Numerical arrays | +| `gamecov-core` (optional) | Rust extension: BK-tree, union-find, coverage tracker (PyO3/maturin) | | `returns` | Functional `Result` type for error handling | | `deprecated` | `@deprecated` decorator | | `typer-slim` | CLI framework | @@ -110,6 +132,7 @@ uv run pytest -n auto - **Integration** (real assets): `test_load_n.py`, `test_load_write_assets.py` - **Monotonicity**: `test_monotone.py` (random data), `test_monotone_smb.py` (real SMB recordings) - **Differential**: `test_BK_frame_monitor.py` (FrameMonitor vs BKFrameMonitor produce identical results) +- **Rust backend**: `test_rust_frame_monitor.py` (differential Python vs Rust, order-independence, monotonicity; skipped if `gamecov-core` not installed) Some tests require assets in `assets/videos/` or `assets/smb/` and will skip if missing. diff --git a/README.md b/README.md index db0fa4c..70f58a9 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,32 @@ print(f"Total unique frames: {len(monitor.item_seen)}") print(f"Unique paths: {len(monitor.path_seen)}") ``` +### Rust-accelerated monitor (optional) + +If `gamecov-core` is installed, `RustBKFrameMonitor` provides the same interface +backed by a compiled Rust extension for significantly higher throughput: + +```python +from gamecov import FrameCoverage +from gamecov.frame_cov import RustBKFrameMonitor + +monitor = RustBKFrameMonitor() # same API as BKFrameMonitor + +for recording in recordings: + cov = FrameCoverage(recording) + if not monitor.is_seen(cov): + monitor.add_cov(cov) + +print(f"Coverage components: {monitor.coverage_count}") +``` + +Install `gamecov-core` from the sibling crate: + +```bash +cd gamecov-core +maturin develop --release +``` + ### CLI ```bash diff --git a/gamecov-core/Cargo.lock b/gamecov-core/Cargo.lock new file mode 100644 index 0000000..9ab7af0 --- /dev/null +++ b/gamecov-core/Cargo.lock @@ -0,0 +1,438 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + +[[package]] +name = "bitflags" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "gamecov-core" +version = "0.1.0" +dependencies = [ + "proptest", + "pyo3", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "indoc" +version = "2.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706" +dependencies = [ + "rustversion", +] + +[[package]] +name = "libc" +version = "0.2.180" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" + +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proptest" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37566cb3fdacef14c0737f9546df7cfeadbfbc9fef10991038bf5015d0c80532" +dependencies = [ + "bit-set", + "bit-vec", + "bitflags", + "num-traits", + "rand", + "rand_chacha", + "rand_xorshift", + "regex-syntax", + "rusty-fork", + "tempfile", + "unarray", +] + +[[package]] +name = "pyo3" +version = "0.23.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7778bffd85cf38175ac1f545509665d0b9b92a198ca7941f131f85f7a4f9a872" +dependencies = [ + "cfg-if", + "indoc", + "libc", + "memoffset", + "once_cell", + "portable-atomic", + "pyo3-build-config", + "pyo3-ffi", + "pyo3-macros", + "unindent", +] + +[[package]] +name = "pyo3-build-config" +version = "0.23.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f6cbe86ef3bf18998d9df6e0f3fc1050a8c5efa409bf712e661a4366e010fb" +dependencies = [ + "once_cell", + "target-lexicon", +] + +[[package]] +name = "pyo3-ffi" +version = "0.23.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9f1b4c431c0bb1c8fb0a338709859eed0d030ff6daa34368d3b152a63dfdd8d" +dependencies = [ + "libc", + "pyo3-build-config", +] + +[[package]] +name = "pyo3-macros" +version = "0.23.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc2201328f63c4710f68abdf653c89d8dbc2858b88c5d88b0ff38a75288a9da" +dependencies = [ + "proc-macro2", + "pyo3-macros-backend", + "quote", + "syn", +] + +[[package]] +name = "pyo3-macros-backend" +version = "0.23.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fca6726ad0f3da9c9de093d6f116a93c1a38e417ed73bf138472cf4064f72028" +dependencies = [ + "heck", + "proc-macro2", + "pyo3-build-config", + "quote", + "syn", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quote" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_xorshift" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +dependencies = [ + "rand_core", +] + +[[package]] +name = "regex-syntax" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" + +[[package]] +name = "rustix" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "rusty-fork" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + +[[package]] +name = "syn" +version = "2.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "target-lexicon" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + +[[package]] +name = "tempfile" +version = "3.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" +dependencies = [ + "fastrand", + "getrandom", + "once_cell", + "rustix", + "windows-sys", +] + +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + +[[package]] +name = "unicode-ident" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" + +[[package]] +name = "unindent" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3" + +[[package]] +name = "wait-timeout" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" +dependencies = [ + "libc", +] + +[[package]] +name = "wasip2" +version = "1.0.2+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" + +[[package]] +name = "zerocopy" +version = "0.8.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/gamecov-core/Cargo.toml b/gamecov-core/Cargo.toml new file mode 100644 index 0000000..47ce62e --- /dev/null +++ b/gamecov-core/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "gamecov-core" +version = "0.1.0" +edition = "2021" +description = "Rust-accelerated core for gamecov frame coverage monitoring" + +[lib] +name = "gamecov_core" +crate-type = ["cdylib", "rlib"] + +[dependencies] +pyo3 = { version = "0.23", features = ["extension-module"] } + +[dev-dependencies] +proptest = "1" + +[profile.release] +lto = "fat" +codegen-units = 1 diff --git a/gamecov-core/pyproject.toml b/gamecov-core/pyproject.toml new file mode 100644 index 0000000..48bc67b --- /dev/null +++ b/gamecov-core/pyproject.toml @@ -0,0 +1,18 @@ +[build-system] +requires = ["maturin>=1.9,<2.0"] +build-backend = "maturin" + +[project] +name = "gamecov-core" +version = "0.1.0" +description = "Rust-accelerated core for gamecov frame coverage monitoring" +authors = [{ name = "Yifeng He", email = "yfhe.prsn@gmail.com" }] +requires-python = ">=3.11" +classifiers = [ + "Programming Language :: Rust", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: 3.11", +] + +[tool.maturin] +features = ["pyo3/extension-module"] diff --git a/gamecov-core/src/bktree.rs b/gamecov-core/src/bktree.rs new file mode 100644 index 0000000..a9bb4cd --- /dev/null +++ b/gamecov-core/src/bktree.rs @@ -0,0 +1,168 @@ +use std::collections::HashMap; + +/// A node in the BK-tree arena. +struct BKNode { + val: u64, + children: HashMap, +} + +/// BK-tree for Hamming-distance nearest-neighbour queries on u64 hashes. +/// +/// Nodes are stored in a flat Vec (arena allocation) for cache friendliness. +pub struct BKTreeInner { + nodes: Vec, +} + +#[inline(always)] +pub fn hamming(a: u64, b: u64) -> u32 { + (a ^ b).count_ones() +} + +impl BKTreeInner { + pub fn new() -> Self { + Self { nodes: Vec::new() } + } + + /// Insert a hash value. Returns false if exact duplicate (distance 0). + pub fn add(&mut self, x: u64) -> bool { + if self.nodes.is_empty() { + self.nodes.push(BKNode { + val: x, + children: HashMap::new(), + }); + return true; + } + + let mut idx = 0; + loop { + let d = hamming(x, self.nodes[idx].val); + if d == 0 { + return false; // exact duplicate + } + if let Some(&child_idx) = self.nodes[idx].children.get(&d) { + idx = child_idx; + } else { + let new_idx = self.nodes.len(); + self.nodes.push(BKNode { + val: x, + children: HashMap::new(), + }); + self.nodes[idx].children.insert(d, new_idx); + return true; + } + } + } + + /// Check if any value in the tree is within Hamming distance `radius` of `x`. + pub fn any_within(&self, x: u64, radius: u32) -> bool { + if self.nodes.is_empty() { + return false; + } + + let mut stack = vec![0usize]; + while let Some(idx) = stack.pop() { + let node = &self.nodes[idx]; + let d = hamming(x, node.val); + if d <= radius { + return true; + } + let lo = d.saturating_sub(radius); + let hi = d + radius; + for (&dd, &child_idx) in &node.children { + if dd >= lo && dd <= hi { + stack.push(child_idx); + } + } + } + false + } + + /// Return all values within Hamming distance `radius` of `x`. + pub fn find_all_within(&self, x: u64, radius: u32) -> Vec { + if self.nodes.is_empty() { + return Vec::new(); + } + + let mut results = Vec::new(); + let mut stack = vec![0usize]; + while let Some(idx) = stack.pop() { + let node = &self.nodes[idx]; + let d = hamming(x, node.val); + if d <= radius { + results.push(node.val); + } + let lo = d.saturating_sub(radius); + let hi = d + radius; + for (&dd, &child_idx) in &node.children { + if dd >= lo && dd <= hi { + stack.push(child_idx); + } + } + } + results + } + + pub fn len(&self) -> usize { + self.nodes.len() + } + + pub fn is_empty(&self) -> bool { + self.nodes.is_empty() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_empty_tree() { + let tree = BKTreeInner::new(); + assert!(tree.is_empty()); + assert!(!tree.any_within(42, 5)); + assert!(tree.find_all_within(42, 5).is_empty()); + } + + #[test] + fn test_add_and_exact_duplicate() { + let mut tree = BKTreeInner::new(); + assert!(tree.add(100)); + assert!(!tree.add(100)); // exact duplicate + assert_eq!(tree.len(), 1); + } + + #[test] + fn test_any_within() { + let mut tree = BKTreeInner::new(); + // 0b0000 and 0b0011 have Hamming distance 2 + tree.add(0b0000); + assert!(tree.any_within(0b0011, 2)); + assert!(tree.any_within(0b0011, 3)); + assert!(!tree.any_within(0b0011, 1)); + } + + #[test] + fn test_find_all_within() { + let mut tree = BKTreeInner::new(); + tree.add(0b0000); + tree.add(0b0001); // distance 1 from 0b0000 + tree.add(0b0011); // distance 2 from 0b0000 + tree.add(0b0111); // distance 3 from 0b0000 + tree.add(0b1111); // distance 4 from 0b0000 + + let results = tree.find_all_within(0b0000, 2); + assert_eq!(results.len(), 3); // 0b0000, 0b0001, 0b0011 + assert!(results.contains(&0b0000)); + assert!(results.contains(&0b0001)); + assert!(results.contains(&0b0011)); + } + + #[test] + fn test_hamming_distance() { + assert_eq!(hamming(0, 0), 0); + assert_eq!(hamming(0b1111, 0b0000), 4); + assert_eq!(hamming(0b1010, 0b0101), 4); + assert_eq!(hamming(0b1100, 0b1010), 2); + assert_eq!(hamming(u64::MAX, 0), 64); + } +} diff --git a/gamecov-core/src/lib.rs b/gamecov-core/src/lib.rs new file mode 100644 index 0000000..25179de --- /dev/null +++ b/gamecov-core/src/lib.rs @@ -0,0 +1,126 @@ +use pyo3::prelude::*; + +pub mod bktree; +pub mod monitor; +pub mod unionfind; + +use bktree::BKTreeInner; +use monitor::CoverageTrackerInner; +use unionfind::UnionFindInner; + +// ── Python wrappers ─────────────────────────────────────────────────────── + +/// BK-tree for Hamming-distance queries on 64-bit perceptual hashes. +#[pyclass] +struct BKTree { + inner: BKTreeInner, +} + +#[pymethods] +impl BKTree { + #[new] + fn new() -> Self { + Self { + inner: BKTreeInner::new(), + } + } + + /// Insert a hash. Returns True if new, False if exact duplicate. + fn add(&mut self, x: u64) -> bool { + self.inner.add(x) + } + + /// Check if any stored hash is within Hamming distance `radius` of `x`. + fn any_within(&self, x: u64, radius: u32) -> bool { + self.inner.any_within(x, radius) + } + + /// Return all stored hashes within Hamming distance `radius` of `x`. + fn find_all_within(&self, x: u64, radius: u32) -> Vec { + self.inner.find_all_within(x, radius) + } + + fn __len__(&self) -> usize { + self.inner.len() + } +} + +/// Disjoint-set (union-find) over u64 keys. +#[pyclass] +struct UnionFind { + inner: UnionFindInner, +} + +#[pymethods] +impl UnionFind { + #[new] + fn new() -> Self { + Self { + inner: UnionFindInner::new(), + } + } + + fn make_set(&mut self, x: u64) { + self.inner.make_set(x) + } + + fn find(&mut self, x: u64) -> u64 { + self.inner.find(x) + } + + #[pyo3(name = "union")] + fn union_sets(&mut self, a: u64, b: u64) { + self.inner.union(a, b) + } + + #[getter] + fn component_count(&self) -> usize { + self.inner.component_count() + } +} + +/// Combined BK-tree + union-find coverage tracker. +/// +/// Drop-in replacement for the hot path of Python's BKFrameMonitor. +#[pyclass] +struct CoverageTracker { + inner: CoverageTrackerInner, +} + +#[pymethods] +impl CoverageTracker { + #[new] + fn new(radius: u32) -> Self { + Self { + inner: CoverageTrackerInner::new(radius), + } + } + + /// Insert a hash. Returns True if the hash was new. + fn add_hash(&mut self, x: u64) -> bool { + self.inner.add_hash(x) + } + + #[getter] + fn coverage_count(&self) -> usize { + self.inner.coverage_count() + } + + #[getter] + fn total_unique(&self) -> usize { + self.inner.total_unique() + } + + fn reset(&mut self) { + self.inner.reset() + } +} + +/// gamecov_core — Rust-accelerated core for gamecov frame coverage monitoring. +#[pymodule] +fn gamecov_core(m: &Bound<'_, PyModule>) -> PyResult<()> { + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + Ok(()) +} diff --git a/gamecov-core/src/monitor.rs b/gamecov-core/src/monitor.rs new file mode 100644 index 0000000..56a7c5a --- /dev/null +++ b/gamecov-core/src/monitor.rs @@ -0,0 +1,131 @@ +use std::collections::HashSet; + +use crate::bktree::BKTreeInner; +use crate::unionfind::UnionFindInner; + +/// Combined BK-tree + UnionFind coverage tracker. +/// +/// Mirrors the logic of Python's `BKFrameMonitor.add_cov()`: +/// each new hash is inserted into the BK-tree, all neighbours within +/// `radius` are found, and the hash is unioned with each neighbour. +/// Coverage is measured as the number of connected components. +pub struct CoverageTrackerInner { + bktree: BKTreeInner, + uf: UnionFindInner, + exact: HashSet, + radius: u32, +} + +impl CoverageTrackerInner { + pub fn new(radius: u32) -> Self { + Self { + bktree: BKTreeInner::new(), + uf: UnionFindInner::new(), + exact: HashSet::new(), + radius, + } + } + + /// Insert a hash. Returns true if the hash was new (not an exact duplicate). + pub fn add_hash(&mut self, x: u64) -> bool { + if !self.exact.insert(x) { + return false; // exact duplicate + } + + let neighbors = self.bktree.find_all_within(x, self.radius); + + self.uf.make_set(x); + for nb in &neighbors { + self.uf.union(x, *nb); + } + + self.bktree.add(x); + true + } + + pub fn coverage_count(&self) -> usize { + self.uf.component_count() + } + + pub fn total_unique(&self) -> usize { + self.exact.len() + } + + pub fn reset(&mut self) { + self.bktree = BKTreeInner::new(); + self.uf = UnionFindInner::new(); + self.exact.clear(); + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_empty_tracker() { + let tracker = CoverageTrackerInner::new(5); + assert_eq!(tracker.coverage_count(), 0); + assert_eq!(tracker.total_unique(), 0); + } + + #[test] + fn test_single_hash() { + let mut tracker = CoverageTrackerInner::new(5); + assert!(tracker.add_hash(42)); + assert_eq!(tracker.coverage_count(), 1); + assert_eq!(tracker.total_unique(), 1); + } + + #[test] + fn test_exact_duplicate() { + let mut tracker = CoverageTrackerInner::new(5); + assert!(tracker.add_hash(42)); + assert!(!tracker.add_hash(42)); // duplicate + assert_eq!(tracker.total_unique(), 1); + assert_eq!(tracker.coverage_count(), 1); + } + + #[test] + fn test_nearby_hashes_merge() { + let mut tracker = CoverageTrackerInner::new(2); + // 0b0000 and 0b0001 have Hamming distance 1 (<= radius 2) + tracker.add_hash(0b0000); + tracker.add_hash(0b0001); + assert_eq!(tracker.total_unique(), 2); + assert_eq!(tracker.coverage_count(), 1); // merged into one component + } + + #[test] + fn test_distant_hashes_separate() { + let mut tracker = CoverageTrackerInner::new(1); + // 0b0000 and 0b0111 have Hamming distance 3 (> radius 1) + tracker.add_hash(0b0000); + tracker.add_hash(0b0111); + assert_eq!(tracker.total_unique(), 2); + assert_eq!(tracker.coverage_count(), 2); // separate components + } + + #[test] + fn test_bridging_reduces_components() { + let mut tracker = CoverageTrackerInner::new(1); + // A: 0b0000, B: 0b0011 (distance 2 from A, separate) + // C: 0b0001 (distance 1 from A, distance 1 from B -> bridges them) + tracker.add_hash(0b0000); + tracker.add_hash(0b0011); + assert_eq!(tracker.coverage_count(), 2); + + tracker.add_hash(0b0001); // bridges A and B + assert_eq!(tracker.coverage_count(), 1); + } + + #[test] + fn test_reset() { + let mut tracker = CoverageTrackerInner::new(5); + tracker.add_hash(1); + tracker.add_hash(2); + tracker.reset(); + assert_eq!(tracker.coverage_count(), 0); + assert_eq!(tracker.total_unique(), 0); + } +} diff --git a/gamecov-core/src/unionfind.rs b/gamecov-core/src/unionfind.rs new file mode 100644 index 0000000..7cc605d --- /dev/null +++ b/gamecov-core/src/unionfind.rs @@ -0,0 +1,132 @@ +use std::collections::HashMap; + +/// Disjoint-set (union-find) with path compression and union by rank. +/// +/// Maps arbitrary u64 hash values to internal indices for flat-array storage. +pub struct UnionFindInner { + /// Map from external u64 key to internal index. + key_to_idx: HashMap, + /// Map from internal index back to external u64 key. + idx_to_key: Vec, + parent: Vec, + rank: Vec, + count: usize, +} + +impl UnionFindInner { + pub fn new() -> Self { + Self { + key_to_idx: HashMap::new(), + idx_to_key: Vec::new(), + parent: Vec::new(), + rank: Vec::new(), + count: 0, + } + } + + /// Register a new element. No-op if already present. + pub fn make_set(&mut self, x: u64) { + if self.key_to_idx.contains_key(&x) { + return; + } + let idx = self.parent.len(); + self.key_to_idx.insert(x, idx); + self.idx_to_key.push(x); + self.parent.push(idx); + self.rank.push(0); + self.count += 1; + } + + /// Find the representative of x (with path splitting). + pub fn find(&mut self, x: u64) -> u64 { + let idx = self.key_to_idx[&x]; + let root = self.find_idx(idx); + self.idx_to_key[root] + } + + fn find_idx(&mut self, mut idx: usize) -> usize { + while self.parent[idx] != idx { + // path splitting: point to grandparent + self.parent[idx] = self.parent[self.parent[idx]]; + idx = self.parent[idx]; + } + idx + } + + /// Union the sets containing a and b. + pub fn union(&mut self, a: u64, b: u64) { + let ia = self.key_to_idx[&a]; + let ib = self.key_to_idx[&b]; + let mut ra = self.find_idx(ia); + let mut rb = self.find_idx(ib); + if ra == rb { + return; + } + if self.rank[ra] < self.rank[rb] { + std::mem::swap(&mut ra, &mut rb); + } + self.parent[rb] = ra; + if self.rank[ra] == self.rank[rb] { + self.rank[ra] += 1; + } + self.count -= 1; + } + + pub fn component_count(&self) -> usize { + self.count + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_empty() { + let uf = UnionFindInner::new(); + assert_eq!(uf.component_count(), 0); + } + + #[test] + fn test_make_set() { + let mut uf = UnionFindInner::new(); + uf.make_set(10); + uf.make_set(20); + uf.make_set(10); // duplicate, no-op + assert_eq!(uf.component_count(), 2); + } + + #[test] + fn test_find_self() { + let mut uf = UnionFindInner::new(); + uf.make_set(42); + assert_eq!(uf.find(42), 42); + } + + #[test] + fn test_union() { + let mut uf = UnionFindInner::new(); + uf.make_set(1); + uf.make_set(2); + uf.make_set(3); + assert_eq!(uf.component_count(), 3); + + uf.union(1, 2); + assert_eq!(uf.component_count(), 2); + assert_eq!(uf.find(1), uf.find(2)); + + uf.union(2, 3); + assert_eq!(uf.component_count(), 1); + assert_eq!(uf.find(1), uf.find(3)); + } + + #[test] + fn test_union_idempotent() { + let mut uf = UnionFindInner::new(); + uf.make_set(1); + uf.make_set(2); + uf.union(1, 2); + uf.union(1, 2); // no-op + assert_eq!(uf.component_count(), 1); + } +} diff --git a/gamecov-core/tests/prop_tests.rs b/gamecov-core/tests/prop_tests.rs new file mode 100644 index 0000000..d292191 --- /dev/null +++ b/gamecov-core/tests/prop_tests.rs @@ -0,0 +1,176 @@ +use gamecov_core::bktree::{hamming, BKTreeInner}; +use gamecov_core::monitor::CoverageTrackerInner; +use gamecov_core::unionfind::UnionFindInner; +use proptest::prelude::*; + +// ── BK-tree properties ─────────────────────────────────────────────────── + +proptest! { + #[test] + fn bktree_find_self(x in any::()) { + let mut tree = BKTreeInner::new(); + tree.add(x); + // x should always be within distance 0 of itself + assert!(tree.any_within(x, 0)); + let results = tree.find_all_within(x, 0); + assert!(results.contains(&x)); + } + + #[test] + fn bktree_no_false_negatives( + values in prop::collection::vec(any::(), 1..50), + radius in 0u32..10, + ) { + let mut tree = BKTreeInner::new(); + for &v in &values { + tree.add(v); + } + // Every value in the tree must be found by find_all_within on itself + for &v in &values { + let results = tree.find_all_within(v, radius); + assert!(results.contains(&v), "Tree must find the value itself"); + } + } + + #[test] + fn bktree_results_within_radius( + values in prop::collection::vec(any::(), 1..50), + query in any::(), + radius in 0u32..20, + ) { + let mut tree = BKTreeInner::new(); + for &v in &values { + tree.add(v); + } + let results = tree.find_all_within(query, radius); + // All returned values must actually be within radius + for &r in &results { + assert!( + hamming(query, r) <= radius, + "Result {} has distance {} from query {}, exceeds radius {}", + r, hamming(query, r), query, radius + ); + } + } + + #[test] + fn bktree_completeness( + values in prop::collection::vec(any::(), 1..30), + query in any::(), + radius in 0u32..10, + ) { + let mut tree = BKTreeInner::new(); + for &v in &values { + tree.add(v); + } + let results = tree.find_all_within(query, radius); + + // Brute-force: every value within radius must appear in results + let mut expected: Vec = values.iter() + .copied() + .filter(|&v| hamming(query, v) <= radius) + .collect(); + expected.sort(); + expected.dedup(); + + let mut got = results.clone(); + got.sort(); + got.dedup(); + + assert_eq!(got, expected, "BK-tree must return exactly the brute-force results"); + } +} + +// ── UnionFind properties ───────────────────────────────────────────────── + +proptest! { + #[test] + fn uf_component_count_nonnegative( + values in prop::collection::vec(any::(), 0..50), + unions in prop::collection::vec((any::(), any::()), 0..30), + ) { + let mut uf = UnionFindInner::new(); + let deduped: Vec = { + let mut s = std::collections::HashSet::new(); + values.into_iter().filter(|v| s.insert(*v)).collect() + }; + for &v in &deduped { + uf.make_set(v); + } + if !deduped.is_empty() { + for (ia, ib) in &unions { + let a = deduped[ia.index(deduped.len())]; + let b = deduped[ib.index(deduped.len())]; + uf.union(a, b); + } + } + assert!(uf.component_count() <= deduped.len()); + if !deduped.is_empty() { + assert!(uf.component_count() >= 1); + } + } + + #[test] + fn uf_union_is_symmetric(a in any::(), b in any::()) { + prop_assume!(a != b); + let mut uf1 = UnionFindInner::new(); + uf1.make_set(a); + uf1.make_set(b); + uf1.union(a, b); + + let mut uf2 = UnionFindInner::new(); + uf2.make_set(a); + uf2.make_set(b); + uf2.union(b, a); + + assert_eq!(uf1.find(a), uf1.find(b)); + assert_eq!(uf2.find(a), uf2.find(b)); + assert_eq!(uf1.component_count(), uf2.component_count()); + } +} + +// ── CoverageTracker properties ─────────────────────────────────────────── + +proptest! { + #[test] + fn tracker_total_unique_monotone( + hashes in prop::collection::vec(any::(), 1..100), + radius in 1u32..10, + ) { + let mut tracker = CoverageTrackerInner::new(radius); + let mut prev_unique = 0usize; + for &h in &hashes { + tracker.add_hash(h); + assert!( + tracker.total_unique() >= prev_unique, + "total_unique must be monotonically non-decreasing" + ); + prev_unique = tracker.total_unique(); + } + } + + #[test] + fn tracker_coverage_leq_unique( + hashes in prop::collection::vec(any::(), 1..100), + radius in 1u32..10, + ) { + let mut tracker = CoverageTrackerInner::new(radius); + for &h in &hashes { + tracker.add_hash(h); + } + assert!(tracker.coverage_count() <= tracker.total_unique()); + } + + #[test] + fn tracker_reset_clears_state( + hashes in prop::collection::vec(any::(), 1..50), + ) { + let mut tracker = CoverageTrackerInner::new(5); + for &h in &hashes { + tracker.add_hash(h); + } + tracker.reset(); + assert_eq!(tracker.coverage_count(), 0); + assert_eq!(tracker.total_unique(), 0); + } +} diff --git a/pyproject.toml b/pyproject.toml index fadb637..2dc0e95 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,6 @@ dependencies = [ "hypothesis>=6.136.7", "imagehash>=4.3.2", "imageio[ffmpeg]>=2.37.0", - "numba>=0.61.2", "numpy>=2.0.0", "opencv-python>=4.11.0.86", "pillow>=11.3.0", diff --git a/src/gamecov/__init__.py b/src/gamecov/__init__.py index abc9cd9..49e2298 100644 --- a/src/gamecov/__init__.py +++ b/src/gamecov/__init__.py @@ -1,7 +1,13 @@ from .cov_base import Coverage, CoverageItem, CoverageMonitor from .dedup import dedup_unique_frames from .frame import Frame, HashMethod -from .frame_cov import BKFrameMonitor, FrameCoverage, FrameMonitor, get_frame_cov +from .frame_cov import ( + BKFrameMonitor, + FrameCoverage, + FrameMonitor, + RustBKFrameMonitor, + get_frame_cov, +) from .loader import load_mp4, load_mp4_lazy from .stitch import stitch_images @@ -19,4 +25,5 @@ "Coverage", "CoverageMonitor", "BKFrameMonitor", + "RustBKFrameMonitor", ] diff --git a/src/gamecov/frame_cov.py b/src/gamecov/frame_cov.py index 8a2bcca..25f9125 100644 --- a/src/gamecov/frame_cov.py +++ b/src/gamecov/frame_cov.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import hashlib from dataclasses import dataclass, field from typing import Iterable @@ -13,6 +15,15 @@ from .loader import load_mp4_lazy +def _imagehash_to_u64(img_hash: ImageHash) -> int: + """Convert an ImageHash to a u64 integer for the Rust backend.""" + hash_bytes = np.packbits( + np.asarray(img_hash.hash, dtype=np.uint8), + bitorder="big", + ).tobytes() + return int.from_bytes(hash_bytes, "big") + + def _trace_and_unique( frames: Iterable[Frame], threshold: int = RADIUS, @@ -243,14 +254,11 @@ def add_cov(self, cov: Coverage[ImageHash]) -> None: """ self.path_seen.add(cov.path_id) for img_hash in cov.coverage: - hash_bytes = np.packbits( - np.asarray(img_hash.hash, dtype=np.uint8), - bitorder="big", - ).tobytes() - if hash_bytes in self._exact_bytes: + x = _imagehash_to_u64(img_hash) + x_bytes = x.to_bytes(8, "big") + if x_bytes in self._exact_bytes: continue - x = int.from_bytes(hash_bytes, "big") neighbors = self._bktree.find_all_within(x, self.radius) self._uf.make_set(x) @@ -258,7 +266,7 @@ def add_cov(self, cov: Coverage[ImageHash]) -> None: self._uf.union(x, nb) self._bktree.add(x) - self._exact_bytes.add(hash_bytes) + self._exact_bytes.add(x_bytes) self.item_seen.add(img_hash) @property @@ -272,3 +280,54 @@ def reset(self) -> None: self._bktree = _BKTree() self._exact_bytes.clear() self._uf = _UnionFind() + + +class RustBKFrameMonitor(FrameMonitor): + """Rust-accelerated BKFrameMonitor using gamecov-core. + + Behaviorally identical to :class:`BKFrameMonitor` but delegates the + BK-tree, union-find, and coverage tracking to a compiled Rust extension + for significantly higher throughput. + + Requires the ``gamecov-core`` package to be installed. + """ + + def __init__(self, radius: int = RADIUS): + try: + import gamecov_core # type: ignore[import-untyped] + except ImportError as exc: + raise ImportError( + "gamecov-core is not installed. Install with: pip install gamecov-core" + ) from exc + super().__init__() + self._tracker: gamecov_core.CoverageTracker = gamecov_core.CoverageTracker( + radius + ) + self._exact: set[int] = set() + self.radius = radius + + def add_cov(self, cov: Coverage[ImageHash]) -> None: + """Add coverage using Rust-accelerated data structures.""" + self.path_seen.add(cov.path_id) + for img_hash in cov.coverage: + x = _imagehash_to_u64(img_hash) + if x in self._exact: + continue + + self._tracker.add_hash(x) + self._exact.add(x) + self.item_seen.add(img_hash) + + @property + def coverage_count(self) -> int: + """Order-independent coverage from Rust implementation.""" + count: int = self._tracker.coverage_count + return count + + def reset(self) -> None: + """Reset all monitor state.""" + super().reset() + import gamecov_core # type: ignore[import-untyped] + + self._tracker = gamecov_core.CoverageTracker(self.radius) + self._exact.clear() diff --git a/tests/test_rust_frame_monitor.py b/tests/test_rust_frame_monitor.py new file mode 100644 index 0000000..1821285 --- /dev/null +++ b/tests/test_rust_frame_monitor.py @@ -0,0 +1,133 @@ +"""Tests for RustBKFrameMonitor: differential correctness and monotonicity.""" +import os +import random +import tempfile + +import pytest +from hypothesis import given, settings, strategies as st, HealthCheck + +gamecov_core = pytest.importorskip("gamecov_core") + +from gamecov import FrameCoverage, BKFrameMonitor +from gamecov.frame_cov import RustBKFrameMonitor +import gamecov.generator as cg +from gamecov.writer import write_mp4 + +N_MAX = int(os.getenv("N_MAX", 100)) + + +@settings( + deadline=None, + suppress_health_check=(HealthCheck.data_too_large, HealthCheck.too_slow), +) +@given(data=st.data(), n=st.integers(min_value=1, max_value=30)) +def test_differential_python_vs_rust(data, n): + """BKFrameMonitor and RustBKFrameMonitor must produce identical results.""" + created_files: list[str] = [] + covs: list[FrameCoverage] = [] + + for _ in range(n): + frames = data.draw(cg.frames_lists) + with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as tmp_f: + output_path = tmp_f.name + created_files.append(output_path) + write_mp4(frames, output_path) + covs.append(FrameCoverage(output_path)) + + py_monitor = BKFrameMonitor() + rust_monitor = RustBKFrameMonitor() + + for cov in covs: + if not py_monitor.is_seen(cov): + py_monitor.add_cov(cov) + if not rust_monitor.is_seen(cov): + rust_monitor.add_cov(cov) + + assert py_monitor.coverage_count == rust_monitor.coverage_count, ( + f"coverage_count mismatch: Python={py_monitor.coverage_count} " + f"Rust={rust_monitor.coverage_count}" + ) + assert len(py_monitor.item_seen) == len(rust_monitor.item_seen), ( + f"item_seen count mismatch: Python={len(py_monitor.item_seen)} " + f"Rust={len(rust_monitor.item_seen)}" + ) + + for f in created_files: + os.remove(f) + + +@settings( + deadline=None, + suppress_health_check=(HealthCheck.data_too_large, HealthCheck.too_slow), +) +@given(data=st.data(), n=st.integers(min_value=1, max_value=30)) +def test_rust_order_independent_coverage(data, n): + """RustBKFrameMonitor.coverage_count must be order-independent.""" + created_files: list[str] = [] + covs: list[FrameCoverage] = [] + + for _ in range(n): + frames = data.draw(cg.frames_lists) + with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as tmp_f: + output_path = tmp_f.name + created_files.append(output_path) + write_mp4(frames, output_path) + covs.append(FrameCoverage(output_path)) + + # Original order + monitor_a = RustBKFrameMonitor() + for cov in covs: + if not monitor_a.is_seen(cov): + monitor_a.add_cov(cov) + + # Reversed order + monitor_b = RustBKFrameMonitor() + for cov in reversed(covs): + if not monitor_b.is_seen(cov): + monitor_b.add_cov(cov) + + # Shuffled order + shuffled = list(covs) + random.shuffle(shuffled) + monitor_c = RustBKFrameMonitor() + for cov in shuffled: + if not monitor_c.is_seen(cov): + monitor_c.add_cov(cov) + + assert monitor_a.coverage_count == monitor_b.coverage_count + assert monitor_a.coverage_count == monitor_c.coverage_count + assert len(monitor_a.item_seen) == len(monitor_b.item_seen) + assert len(monitor_a.item_seen) == len(monitor_c.item_seen) + + for f in created_files: + os.remove(f) + + +@settings( + deadline=None, + suppress_health_check=(HealthCheck.data_too_large, HealthCheck.too_slow), +) +@given(data=st.data(), n=st.integers(min_value=1, max_value=N_MAX)) +def test_rust_monotone(data, n): + """len(item_seen) must be monotonically non-decreasing for RustBKFrameMonitor.""" + monitor = RustBKFrameMonitor() + prev_item_count = 0 + created_files = [] + for _ in range(n): + frames = data.draw(cg.frames_lists) + + with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as tmp_f: + output_path = tmp_f.name + created_files.append(output_path) + write_mp4(frames, output_path) + cov = FrameCoverage(output_path) + if not monitor.is_seen(cov): + monitor.add_cov(cov) + + assert len(monitor.item_seen) >= prev_item_count, ( + "item_seen count should not decrease" + ) + prev_item_count = len(monitor.item_seen) + + for f in created_files: + os.remove(f) diff --git a/uv.lock b/uv.lock index 0526a09..2fb0220 100644 --- a/uv.lock +++ b/uv.lock @@ -213,7 +213,6 @@ dependencies = [ { name = "hypothesis" }, { name = "imagehash" }, { name = "imageio", extra = ["ffmpeg"] }, - { name = "numba" }, { name = "numpy" }, { name = "opencv-python" }, { name = "pillow" }, @@ -242,7 +241,6 @@ requires-dist = [ { name = "hypothesis", specifier = ">=6.136.7" }, { name = "imagehash", specifier = ">=4.3.2" }, { name = "imageio", extras = ["ffmpeg"], specifier = ">=2.37.0" }, - { name = "numba", specifier = ">=0.61.2" }, { name = "numpy", specifier = ">=2.0.0" }, { name = "opencv-python", specifier = ">=4.11.0.86" }, { name = "pillow", specifier = ">=11.3.0" }, From 5eec2b1b7989499bb2950f003071f0dd62b55040 Mon Sep 17 00:00:00 2001 From: Yifeng He Date: Fri, 6 Feb 2026 20:06:04 -0800 Subject: [PATCH 2/9] refactor: merge gamecov-core into single maturin-built package Replace hatchling with maturin as the build backend, embedding the Rust extension (gamecov-core) directly into the gamecov package. The compiled module is now installed as gamecov._gamecov_core. - Move Rust sources from gamecov-core/src/ to src/ - Add Cargo.toml at repo root with module-name config - Add type stub _gamecov_core.pyi (eliminates type: ignore) - Update CI to install Rust toolchain before build - Delete gamecov-core/ subdirectory Users can now install the full package with: pip install . --- .github/workflows/pytest.yml | 27 +- .gitignore | 3 +- AGENTS.md | 37 +- gamecov-core/Cargo.toml => Cargo.toml | 4 + gamecov-core/Cargo.lock | 438 ------------------ gamecov-core/pyproject.toml | 18 - pyproject.toml | 9 +- .../tests => rust-tests}/prop_tests.rs | 0 {gamecov-core/src => src}/bktree.rs | 0 ...mecov_core.cpython-311-x86_64-linux-gnu.so | Bin 0 -> 545784 bytes src/gamecov/_gamecov_core.pyi | 23 + src/gamecov/frame_cov.py | 11 +- {gamecov-core/src => src}/lib.rs | 1 + {gamecov-core/src => src}/monitor.rs | 0 {gamecov-core/src => src}/unionfind.rs | 0 tests/test_rust_frame_monitor.py | 2 +- 16 files changed, 76 insertions(+), 497 deletions(-) rename gamecov-core/Cargo.toml => Cargo.toml (85%) delete mode 100644 gamecov-core/Cargo.lock delete mode 100644 gamecov-core/pyproject.toml rename {gamecov-core/tests => rust-tests}/prop_tests.rs (100%) rename {gamecov-core/src => src}/bktree.rs (100%) create mode 100755 src/gamecov/_gamecov_core.cpython-311-x86_64-linux-gnu.so create mode 100644 src/gamecov/_gamecov_core.pyi rename {gamecov-core/src => src}/lib.rs (98%) rename {gamecov-core/src => src}/monitor.rs (100%) rename {gamecov-core/src => src}/unionfind.rs (100%) diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index aabc9ca..1e343d9 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -3,19 +3,22 @@ name: Unit Testing on: [pull_request] jobs: - unittest: - runs-on: ubuntu-latest + unittest: + runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 1 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 1 - - name: Install uv - uses: astral-sh/setup-uv@v5 + - name: Install Rust + uses: dtolnay/rust-toolchain@stable - - name: Set up Python - run: uv sync + - name: Install uv + uses: astral-sh/setup-uv@v5 - - name: Run Unit Tests - run: uv run pytest -n auto + - name: Set up Python + run: uv sync + + - name: Run Unit Tests + run: uv run pytest -n auto diff --git a/.gitignore b/.gitignore index d5fdddc..29ac4fc 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,5 @@ prof/ .coverage # Rust build artifacts -gamecov-core/target/ +target/ +Cargo.lock diff --git a/AGENTS.md b/AGENTS.md index c60ee78..0a1c7d5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -13,10 +13,17 @@ Future metrics (e.g., audio coverage, state-graph coverage) will follow the same ``` . +├── Cargo.toml # Rust manifest (maturin builds the extension) +├── pyproject.toml # Project metadata, maturin build backend ├── src/ │ ├── main.py # CLI entry point (Typer) +│ ├── lib.rs # PyO3 module entry point (Rust) +│ ├── bktree.rs # BK-tree with POPCNT Hamming distance +│ ├── unionfind.rs # Flat Vec-based union-find +│ ├── monitor.rs # CoverageTracker (BK-tree + UnionFind combined) │ └── gamecov/ │ ├── __init__.py # Public API re-exports +│ ├── _gamecov_core.pyi # Type stub for Rust extension │ ├── cov_base.py # Abstract protocols: CoverageItem, Coverage, CoverageMonitor │ ├── frame.py # Frame dataclass (PIL Image wrapper with average-hash) │ ├── dedup.py # Deduplication algorithms (pHash, SSIM [deprecated]) @@ -27,6 +34,8 @@ Future metrics (e.g., audio coverage, state-graph coverage) will follow the same │ ├── generator.py # Hypothesis strategies for property-based testing │ ├── env.py # Runtime config (RADIUS env var) │ └── py.typed # PEP 561 marker +├── rust-tests/ +│ └── prop_tests.rs # Rust proptest property-based tests ├── tests/ │ ├── test_generators.py # Frame/FrameList generation strategies │ ├── test_dedup.py # Dedup monotonicity properties @@ -42,32 +51,20 @@ Future metrics (e.g., audio coverage, state-graph coverage) will follow the same │ └── smb/ # Super Smash Bros recordings for stress tests ├── docs/ │ └── design.md # Architecture and design documentation -├── pyproject.toml # Project metadata, dependencies, tool configs ├── .pre-commit-config.yaml # Pre-commit hooks ├── .github/workflows/ # CI: pytest, mypy, ruff, pylint ├── AGENTS.md # This file └── README.md # Human-facing documentation ``` -### gamecov-core (Rust extension) +### Rust extension (gamecov-core) -The `gamecov-core/` subdirectory contains a Rust crate (PyO3/maturin) providing -high-performance replacements for the BK-tree, union-find, and coverage tracker. +The Rust extension is built as part of the package via maturin. The compiled +module is installed as `gamecov._gamecov_core` and provides high-performance +replacements for the BK-tree, union-find, and coverage tracker. -``` -gamecov-core/ -├── Cargo.toml -├── pyproject.toml -├── src/ -│ ├── lib.rs # PyO3 module: BKTree, UnionFind, CoverageTracker -│ ├── bktree.rs # BK-tree with POPCNT Hamming distance -│ ├── unionfind.rs # Flat Vec-based union-find -│ └── monitor.rs # CoverageTracker (BK-tree + UnionFind combined) -└── tests/ - └── prop_tests.rs # proptest property-based tests -``` - -Build with: `cd gamecov-core && maturin develop --release` +Build the package (includes Rust compilation): `uv sync` or `pip install .` +Run Rust tests independently: `cargo test` ## Design @@ -102,7 +99,7 @@ See [docs/design.md](docs/design.md) for the coverage framework architecture, fr | `scikit-image` | SSIM metric (deprecated path) | | `stitching` | Panorama stitching via OpenCV features | | `numpy` | Numerical arrays | -| `gamecov-core` (optional) | Rust extension: BK-tree, union-find, coverage tracker (PyO3/maturin) | +| `gamecov._gamecov_core` | Built-in Rust extension: BK-tree, union-find, coverage tracker (PyO3/maturin) | | `returns` | Functional `Result` type for error handling | | `deprecated` | `@deprecated` decorator | | `typer-slim` | CLI framework | @@ -132,7 +129,7 @@ uv run pytest -n auto - **Integration** (real assets): `test_load_n.py`, `test_load_write_assets.py` - **Monotonicity**: `test_monotone.py` (random data), `test_monotone_smb.py` (real SMB recordings) - **Differential**: `test_BK_frame_monitor.py` (FrameMonitor vs BKFrameMonitor produce identical results) -- **Rust backend**: `test_rust_frame_monitor.py` (differential Python vs Rust, order-independence, monotonicity; skipped if `gamecov-core` not installed) +- **Rust backend**: `test_rust_frame_monitor.py` (differential Python vs Rust, order-independence, monotonicity) Some tests require assets in `assets/videos/` or `assets/smb/` and will skip if missing. diff --git a/gamecov-core/Cargo.toml b/Cargo.toml similarity index 85% rename from gamecov-core/Cargo.toml rename to Cargo.toml index 47ce62e..4a03770 100644 --- a/gamecov-core/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,10 @@ pyo3 = { version = "0.23", features = ["extension-module"] } [dev-dependencies] proptest = "1" +[[test]] +name = "prop_tests" +path = "rust-tests/prop_tests.rs" + [profile.release] lto = "fat" codegen-units = 1 diff --git a/gamecov-core/Cargo.lock b/gamecov-core/Cargo.lock deleted file mode 100644 index 9ab7af0..0000000 --- a/gamecov-core/Cargo.lock +++ /dev/null @@ -1,438 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - -[[package]] -name = "bit-set" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" - -[[package]] -name = "bitflags" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" - -[[package]] -name = "cfg-if" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - -[[package]] -name = "errno" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" -dependencies = [ - "libc", - "windows-sys", -] - -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "gamecov-core" -version = "0.1.0" -dependencies = [ - "proptest", - "pyo3", -] - -[[package]] -name = "getrandom" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" -dependencies = [ - "cfg-if", - "libc", - "r-efi", - "wasip2", -] - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "indoc" -version = "2.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706" -dependencies = [ - "rustversion", -] - -[[package]] -name = "libc" -version = "0.2.180" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" - -[[package]] -name = "linux-raw-sys" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" - -[[package]] -name = "memoffset" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "portable-atomic" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "proc-macro2" -version = "1.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "proptest" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37566cb3fdacef14c0737f9546df7cfeadbfbc9fef10991038bf5015d0c80532" -dependencies = [ - "bit-set", - "bit-vec", - "bitflags", - "num-traits", - "rand", - "rand_chacha", - "rand_xorshift", - "regex-syntax", - "rusty-fork", - "tempfile", - "unarray", -] - -[[package]] -name = "pyo3" -version = "0.23.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7778bffd85cf38175ac1f545509665d0b9b92a198ca7941f131f85f7a4f9a872" -dependencies = [ - "cfg-if", - "indoc", - "libc", - "memoffset", - "once_cell", - "portable-atomic", - "pyo3-build-config", - "pyo3-ffi", - "pyo3-macros", - "unindent", -] - -[[package]] -name = "pyo3-build-config" -version = "0.23.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94f6cbe86ef3bf18998d9df6e0f3fc1050a8c5efa409bf712e661a4366e010fb" -dependencies = [ - "once_cell", - "target-lexicon", -] - -[[package]] -name = "pyo3-ffi" -version = "0.23.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9f1b4c431c0bb1c8fb0a338709859eed0d030ff6daa34368d3b152a63dfdd8d" -dependencies = [ - "libc", - "pyo3-build-config", -] - -[[package]] -name = "pyo3-macros" -version = "0.23.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc2201328f63c4710f68abdf653c89d8dbc2858b88c5d88b0ff38a75288a9da" -dependencies = [ - "proc-macro2", - "pyo3-macros-backend", - "quote", - "syn", -] - -[[package]] -name = "pyo3-macros-backend" -version = "0.23.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca6726ad0f3da9c9de093d6f116a93c1a38e417ed73bf138472cf4064f72028" -dependencies = [ - "heck", - "proc-macro2", - "pyo3-build-config", - "quote", - "syn", -] - -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - -[[package]] -name = "quote" -version = "1.0.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - -[[package]] -name = "rand" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" -dependencies = [ - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_xorshift" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" -dependencies = [ - "rand_core", -] - -[[package]] -name = "regex-syntax" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" - -[[package]] -name = "rustix" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys", -] - -[[package]] -name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "rusty-fork" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2" -dependencies = [ - "fnv", - "quick-error", - "tempfile", - "wait-timeout", -] - -[[package]] -name = "syn" -version = "2.0.114" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "target-lexicon" -version = "0.12.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" - -[[package]] -name = "tempfile" -version = "3.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" -dependencies = [ - "fastrand", - "getrandom", - "once_cell", - "rustix", - "windows-sys", -] - -[[package]] -name = "unarray" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" - -[[package]] -name = "unicode-ident" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" - -[[package]] -name = "unindent" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3" - -[[package]] -name = "wait-timeout" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" -dependencies = [ - "libc", -] - -[[package]] -name = "wasip2" -version = "1.0.2+wasi-0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - -[[package]] -name = "windows-sys" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" -dependencies = [ - "windows-link", -] - -[[package]] -name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" - -[[package]] -name = "zerocopy" -version = "0.8.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/gamecov-core/pyproject.toml b/gamecov-core/pyproject.toml deleted file mode 100644 index 48bc67b..0000000 --- a/gamecov-core/pyproject.toml +++ /dev/null @@ -1,18 +0,0 @@ -[build-system] -requires = ["maturin>=1.9,<2.0"] -build-backend = "maturin" - -[project] -name = "gamecov-core" -version = "0.1.0" -description = "Rust-accelerated core for gamecov frame coverage monitoring" -authors = [{ name = "Yifeng He", email = "yfhe.prsn@gmail.com" }] -requires-python = ">=3.11" -classifiers = [ - "Programming Language :: Rust", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: 3.11", -] - -[tool.maturin] -features = ["pyo3/extension-module"] diff --git a/pyproject.toml b/pyproject.toml index 2dc0e95..2796384 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,8 +23,13 @@ dependencies = [ ] [build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" +requires = ["maturin>=1.9,<2.0"] +build-backend = "maturin" + +[tool.maturin] +python-source = "src" +module-name = "gamecov._gamecov_core" +features = ["pyo3/extension-module"] [tool.pylint.messages_control] disable = [ diff --git a/gamecov-core/tests/prop_tests.rs b/rust-tests/prop_tests.rs similarity index 100% rename from gamecov-core/tests/prop_tests.rs rename to rust-tests/prop_tests.rs diff --git a/gamecov-core/src/bktree.rs b/src/bktree.rs similarity index 100% rename from gamecov-core/src/bktree.rs rename to src/bktree.rs diff --git a/src/gamecov/_gamecov_core.cpython-311-x86_64-linux-gnu.so b/src/gamecov/_gamecov_core.cpython-311-x86_64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..948d55a59b63c97378313bb7db8cb230154866ab GIT binary patch literal 545784 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

dl%FSA+lRo3lx?<&@ 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 z zQ{-L$(lO=2NPsl(?f)i6i@ZvL33t($_n>c#R^URPry~iGo%*(v% zppa20@=jjDo3uV^%+_H|^+f>U=k%5zYwnl&I0a+{MFcj=aMBC|O(Unk>_zB3?qcV9 zV=GoPx{vX^4LD;eKgLpRI5|A;_1kz2*{f8f(2=U6PX(g-#k3SLutjcJ}_&Zbw&oAF{<An2Xh(}GwsU>z><5MvNzrze5T`_Jx3T`ZVMM?n*wF>$0`K2 z>@gCVRD3Ro4HX>L!Cg;AS$C@+EiCZncLj91o4Sc#~#!2R~g+YJr!@>kP`ckh>C<&;)%r$-262j+1eP>nG+OA29Kj;+m8u#A+KCuTek zr3Wh&CM*<>Kud#n!1Sf1p=9kh)p?4T2DJxwK$$PCj->DNW3V^^_Kr=Au{<#H70W+~ z-rye^WexYnJ=%!h4u}IvF~n&gID>l+`-Gmr-e*}1g@q{p26I4-%TldKZ&|t53bMKX zPOXVWI||}=(%lGC zU>p>lV}S0X5hRt3FtNebP!4kl!J?cT&_3b9sXV?LQ4~6iE0>uojIi*`kuVjUt$_mRx{_G?ZMu5V|dsF~L*D zl&D6HQtXwRujrm?d=Mc1OwKATn3bG0gkyN6$fC=?!(}5-RsY)}4!zd>?p5ehHROv& zL+R8A;`2NxlHvaz)A_M-xiFpY@iM3M`pii*us*%<7zzV65$_1ND|sp^CRaCWlv6$% zM~We5m4Ov^hzB=F-?*{M80<7w75j_op>pway!LEpqP293z3;={)C+OFlF7q*ZZ*6v z-GIRyjn0k`rUrVDsv(pyVw6=0-skwPBbWGtKTRf`W?V%^u{^JO8rS9@sxl@BkYVvn zSnyT;!^wkXb4mj@qhvcM-d7s`$rq4BVNTw{@j7Rf^d@symZ>dO2Xo1>$d)@Lndwky znY2A(Z%EXANe<V#l1_?Wl9nlrXVjtjKABYUIT*x%qqhSJ)=NLt4? zTjy2aHINlf+qXfgdt81(Rouq;7j8byXuqE@plk*O)^_P9g$PEKX$6BsnnIT_TUJ%` zT5k+Q!?mBqzaFZ6BR-m*^FVj6;5r_K+e+1wRN>shzz&2F+tFy%Tk*<}Go>QrjGPdv z-HCC;PT?XN7f9+9io1ClE=mmC?-J#^}lmqigVYW1ZsIO|r|h75Ti0 z#_?#inN_NJ)sZKw{%NnQHM4Lw0y zAtMrdkNK| z2AhIMdM-qb*g9e`+zgraY}%OKro>208K)m=w?D^_LC~cjQS`L~*5fiDc*jJ=z#_{^ z*TeyFs1=gK>q_7spUdmKXk%yn$E|hVe(42b%0_Z|kkYYzN1X823k)i+jCA*l>J> zb@9{;xZjYASoPhICZ$7t6c-<~wiZH)zS!91^>()>Lr%SqE-z}oA9ijS1p|1e{MGn+{LTb)N zLPC=(+9y}~py1U|)*0ZHpT5uI)q39L&(b3khOzP_NRjlzQipr{6@3K$B>JpENEN2Z z+C{775w3bB?0YslKC$s`LTDPZX6sxGo0k+OvunNdPgoU@-vDkGR#~hh}L6^3_-*SW^|<9cDrtdB*RmQ z*fV7a>I#_|jFQ02w-uE<+fz0C`a|SfvzWFUuwgExKV9Aj+H-PWgyk)j-V`xSo5+9ikD`<)%bM0$-Vz3 z?b9!XxAT7w-jn*lJ6hoV8ojCT+Q4>5$4)gcQ^hKQCl9km=P7z}Q4`A2?;%VFYW*S_ z$o3om=TLY3??L^o%ldlx9D%y34{G!u1JHr1U#diyXpH+U?dD)J++>&Zv1%7N9Ez|S zI@c`J%{?Aqg{{Q5_5TI5eInWi>sLjFacUo|T^_7(vmA>Nh6QFhE6P`PFG+4LVf+O$ zb|?+3$beIzX#22C2q^p^lc`QWt{yO_&Zd#_Pu|1KsgwJFLtT%uhn1v1wxaKfou+EH zO?>2L&VsYz=Y^f=u$^}^jph384=|CO1=}1iNFL-))E|+Kqd#a$lLybX8X5^^VfV2~ z;%4rPN5gvWWj9cK9@nzsp2v7W3OEZf+1xMw5Dz5fZq#Yy3X4O;T(}I+JndY96yK7) z{J)v|7|Fe!zK}mF%2}&rzQYu_&QM8A*lDAZhF9U)OdG2?=^y4s3vuF#!-;3+ou0j( zHU{BLU(AO8m-zyc58G`0vqH7ot!3vNrl=>tCn0P|zZh>Jl`yC> zo*Zd0D8t)o6aTjR$n~I<*(tC@ybg0)pMKbIF64XL{oa7@a%REXOlTcQLL||h0}}nX zU!rDKeJ|0J0f}OUjaJ$|R*8+3y0KrzE;7;(Au-lEnW0S_VR*Qk*!YRs|L2of%zo@> zlMVqw;ezble2U)|%4t5fYltWEH_Qi{=3Oaw!izrHlzNQsO9p7CFsx(M50aJC+dkUf zVYI?!FUfjb8*GX{k*ybyhR=Wazgc98BEyH4B2-GLqeo%VL8z*3)%q64)PRY65tCT{ z4?mHohkL0EN@Hq7&8!2TUaf1R8UK*s0o?`HVNRtO!N9+zEVQXxiN5lQ5n)oNcXHa$ z<4oL%{WF>4UWzSw&V`$V$kFAV&_7+H7VZdT5;D^GjsBJCP{~B%z^It8a3ir0AW1BO zM-lD?YlNJ<1KbxW%c^cw^Nu@@#ajTy(oj)RC-&cWq zQ+8_Ozj}!vHnQC~wTp9;Dy3csW&8}KU@%8#N6_flWxzHSW|dx>A^admlFn%>XPb(7hCQX+vMAdN=-$HYBV2{zP@rlAsGWxc z>VERmA*)q3rV^hGHClZrd3whY5IWi~lA}<1%=aXX+)DJlO0yn?(j{?;yW_%k!u_BcIE^O#`tFiB`2|6Qj>idLKB0b^SR~Eb#ExMwVmwWz} z9V*@%I8OXj<~)iIrN>`F?YO!sv64TR2+F97+}^QX_HU1epg8ORobrDltPO0CV6^s+ z!@Ky%ZSw+kuI+MXWNCQG)B4S~HCnqp{GrdI&llsLOl*buO1`N-O?6Fp(sAV^izQ%9%Q!@yvIyN;^dI~Y6JP@*JGFvWg zncnH{hWClodOOQ_v(+GH{^l&aHsqvaA~N_|gWd7ruSDwi=yYjxDQ8Hb_JrSJt&!sc#E#`CXkO zqt?HRz7ZpBFNKqJ0foRC#4Lt&sp{?AwVKlynME9(!0!9sJ*0mbOfDfJk0f?azfwM< z>lYbE`Eg7#Mgb#0XQrTN<%%BYoK?B1fG)KvSNrwxaD_hBR_kM99glkG#Z>cjW}4@U zx#qblVVQYxQ9x6Bz)J3rm)qN9PK11$nV-nlOWF{S z1=eevSuS)w;UgRxL?Ut5H%XX3Be0|cw11o?$>Aks^RnZ^UwHv^n(badeU(W$c2{^w zo6OyKdq!>?|B$W_d4T0#p@h)CN~o*lUp-qN4=>cm+D3hBT*;%}@~76Ar?cKXS9F@^ zs-5P!+BMII_nYV1(jLwtl5t}t*X)sBh6YmKB0b~R$x5izgyx!WLP9vc80@OIj@@5x zRc#bLK#CYaS!Ak|N0qq1O4aCVs!lTcQz7%AiPstCgRIbmW}8s82`x0CsV3BDLNbX+ zxzdFECbY(c>P%?82??J-%1#sNHldv+)MY}h3ALKgeiLdkp;GCGs#G0~WCT(p2+pz= zr=}8)fT>`cv>&a?ddLYO?VI7LH72C}HaxXbNlmbs*{?jcy-GO053R+HES%Qx70vos z)uNBpt@?PlOCM{y^|7&sM?LivaETR9$8Vl1D$H|LwRx_tGtY;on&;Y?=DBe$Pj#C! zJeAN_GYrF1P3A)rWjC7-It;^8Ehbbg-8nqfYC=;@sLO1|1O~`M)^_Y+j1Mr%j z&|w&!@|%zj!|+sv3F$BlPgR?c4#V(NoeAkM3{OopAsGf>nQ1~Y2!zD=kDf0uwI>K6 z*lpqwN|#?Kx^jfF@smRxC0`}LOp?`m2dkhv?>~4?mme)@oQdq1mEmStkwMa_$-*Kh z&yvS{g_H=^Zi(E!t#=ZKeb0$+1Lvfl>=lkcl@s1vk2*t6V}YS@#K5DQt=!H6@vA~JU22u>M{ol!c! zBr>*U!AQ}lB-^{=yEA{+p4MKeTj#?Z_PkJfp`T{VM^vt!Bi=ugUcG%swb0h0@~b4; z*7S6yP)wFH8*#SLRLK&o2X&pHM@dSvj@y_s+OH#K6pjnK6ZfHCQ<%vfvA+_suPcRK z?~(zsF~W9AUN^6>wzt6A!gbkms(Yo^^J<8$BO2*{OXI|;usMPXs%3iL-ToVx^e05! zhbIDACDM+3O&%y=MV0!kh6hfj_H=5!W>Ss6a116SbHxdKo;*-Ar|>#!QkR^&mZNOx zwGAYwH@m_5^xA)s9BORHAgoJuT zY)9s6#JPMXuQCNA&cAl*y6eakM6yK!KOJy@@SEr5*z}6-ze>nK5}ow zbrH59nVU|4A$>J-%1OcnOm7mmOM9j4a9O(yIR(NbRfLMf&57BF*XoWDOOxZtlAgIg zfXm=Y#Dpz$BJc;BQ>_7OMTbOxjcAq7LUE-i{qk%eIc^l(>EPpZkfb}3HRoClpBxKU zLnd~co@gQ^owK(9=Q(=0C=9a9|0L@7VTpyM)2!5)K+W|MV6*a$p|Ml(Soa6Y38hOz zcWgsfT|XR7IWpXz`5CeG%S(oRC^$Rj2p$pVq}h843pNNQF%&$My0WT{3=yaNZ$N>XK~g4&*$@J|xC{G8;Ln8G?~AT5si#Twe%k33Qeje`FVQ`H(RjtrJ=IEX8I{K?wV3)(m{65{ z={HrF(j~gul>Rk}*;L&ZU1Oq8lIWVg=xS5Q?>^A}l9qSN(#H8WVjg!57!vK8=(i-g z&g7Tq9uxht$QG2Q1(S%4 zRVSR3&^%#Ag+RfK3PrN2R?H9%?uMoo)gPSX6~defX=yqL#r}4!|8J zH%g5KR>M|dm5~_`LbfzR9{7uBd$*$g)K^fWB3gVMuWa?F?!@`dv$PkfMNhbDzqNEF z8Nd2hmQSxd$C zjj`cP$QL9pj&uw^;=es%CE+RQk>8t~zTn@2_CLVno9_86ciF99TZ2Y4kbA41?SH-f z*X#_>(xBeczl8`(9fYOQYz<+7gRlUWtt31XSnKT@o3kep@SDJz>@Wh-3Q|h5g7(3n z{U%O^cO%N;5}%90OP>9)fXnIL* zzaFZ3*;+abZlIo>cI`oHX(8{N_)9xV*FYb+a^fFM$a*y?XtS1f6G*EPl+jemhJ^`g zc&^2=mdfpqX3Q8NwY}XDWzG{FVggDNUtPL(`y1r zKU337_mF;#rjKfr^bT2+&S@4+BU#SY?**F0$chE3<1|)!pIl1qG?ylmT>I!%I1%}7 zn}_7uMQlCnipi$*Esf!sawL(eE!NUj$(E9_hAe5aT6zuc3+#7v{V2i=&e2t(Xf$+8 zlcpVA62$sJB6*}8CHqFCu92QZ#ZdyER&+7(+Ba!ONV)W}w6n-Z?fS-8nRsoO#_Jod z#Z0{RfX2&P=C7qdnq2MjQB1IUc+yc4wO^v(R%en7g;wk$1h}*HeQ)gRkV?rS*VF7l zc>+K0Hr*(!&PFK#3Msiggv<^@`hpHJTVb9oJ*S}TA!n|<=+BUCAO7S_hV1Tx3Rowa^1=Fb>4eWoz+j7C(`W00mh*MeaRokYm+> z_Tp2{<(eI@1}_O--@>&oSj#RV1ttsvbJ+KW>X&HI?p*mD+Xb#S^SO*pK;&51i!4I` zZp70N){2COIe-B4fwg!vi}rXZ&5fxJ|1CCrWOYZ|sWNb`?kLaqw|$ zZV-+}>@nBy#cHTOMw3k>AWF+i(y{8EOVU?WBR|$HpS!SD5~vuf&rX;Vvhj=Ie03bX zlU<9qu~x#5(or0VFU2lfU^Uh+R>N+He$^1TZ%=ZxK zhn(`IFCm>9eyzJyS|bN@>^3%=Vu1vQ#EKp45}mkJ-$`+bYP|(aH3dwQ0<3G@fEJ)$ zYw~3%`8UPrYhOuS0$6WJgG@=sc_r=pm4LEhs!n(VjbXwSAbssCsdYd}Pa?FZQJ=pE zOh;YoKCC58Z_Wc0Z1x(}+*g3k-(FDeGX=!%paB21?wtk{ouOXG7#XSoMdJHPsvFS1 zqfJRa5>SR+>wd+6vZfc5H6AEy`U;pjpnx7%+wx5*;Mi;3UBA>`5u#w!UmmT1Nqxp6 z7L=rBPQ9&p*c9>AIi@u~Gey*C$3CsYZ1#y(J@ZLl4KQ#!o;YI698<*dKbdA+PZ4r- z$Nmf1smwKX=8>6QMy<*4Ey-~7weFdwPN7+1HPKt{Q6|}KUa}&RAvk6tK~rGr>!0_O zdc3j|H~KyB5aU~8>XUM?4@;7*dtQ2MEEowpAvPnup=0I?A{#b74NAnT#Oj+9BQ zsyz5fF_S`m*2QZ`URllbv0{ck)TR`AIhzoYAHzC0YLaip#8eTi))n46Yz6&-G zxswp2t=mM(_!8-A%8fnxP$4T*xS)rWum>a|R4O5Rqn`&mxe*#lRp?_yr9ReH%OknE zhKDR7A$hi^rt)C3ZWI>wsv7FpB%6<1`3WzAwZe>k$5Kq$pnDQ-J;__?y)SaDjY63) zif3akR4G^f%RiAVPwpgINO-RNUnJVF=Zxf$LVS(H{ln6PTN3c_(YQfH-i$`GjgCk&&#&Q3&QzZC?v-X~F&eCEff&0SGSYf<(N{J_6#OPBrI4 zhWNso^+pJilA^LV!fzs~dm|LVFv#wW(6ysOIVyk_)D?_@|K>7NQ| zh{A;oX5@>khn^aNjKYUN0%48L6l2G0uh4O_Rq-3KAD$|sX0M&0Nt~G)a%RgTy+T(I zgbNy(TBwn-kgiDRt62r@R3jm#Ws@dzR+><=39T`q786>pp^dHjSlua+9$#pux=cuV zjDg!}LfW}@s@sHwDDllTp{XWikA{LQg{l4KgAO9{n;t11g9$q&;E{tPpYzCp1slY|aX502ITajNbH@La(ZhFn`mRQ%Y&TPc zYip*|A!nZric`}<9$@@h3A&q_!6ReYTEATFRhb;MG%h_jJ*@~DNIld$-30FP|m|r5vTl1>@8#^Yf1Z?T^!t zAwDYf!BmUOjtLOexqxl?CtA>@OHQ%;)6PXgF_SovP)wC?XmohUnT2UuhLE5<8<)CO z%hR^I7yks7Zkmbk08_)J=Y&1~06X7-?0Kg9BLO}oN$VR|3kB`pR-pWVDEpEk1lxu` zr}qR}#M2W{VhB{C^i&`#6=rMrv~y7v(T?F0t+2BIDYmD=ULm!(cPbC8Gv}~F(4s@| z=zt+8j1Na_tV19lGQ#+KJ!n04$%I+(nG`KOX!(0PuuGza$Dym@zOSZHlnL$WFJNvRCJVmk3=iPcNC9RlcPnMo-kym||?Jy*;2U(g+F_+!XVI6`fQMfs!UM>vjq-!k{zbHAY*usS{9hjH_VWcj)>es-|&*YXB|p|-Tngn<3v@k9meheq-U+dq>< zF!OijTp;loi{~ryX07{7EKgsdzd}yQ6U>7=ZhX=Eg_>Ka?~7lO&i%JS%#MOb>wYkq znhJs1AHus>eIpXe=`FlA)i=J&Ym?a9k5Ctlw*Udse6EwfYE%WHeYPXg0nyIP_xS=R zP$QjQrF$GgArtD6>4t{agbE-tgl3zN--H&LP=yIKnozX~tu&!J6Ix?JQ%z{S3C%R2 zP7|7ILOV?;VM4C=O;Fdb#1}XdCL|P>P?HG>#U<2iLNkr_SCIu}xCto+`BQZ!BzQ%c zLXAbs4LJ}#jpeS62OL0+B>R6)*$v2|>!vHFdJQxoWhy*FIAO@t2u>J!nZWjox$+yI z*1b3_m#A4G>)UO!!q&H6nq}SDDdbmT#cCu|^g7*yZYi3cT?u~0;Pj?eXUhe{1|Zkd zZ;{T^KgEuwMp<_`v5+g@vstS8q)*w@DVY^lACgSQKFB-h5wRceN9WhBK@NFD z>~B}%J+7KEYlw1h86%u-v?Z^lyVjc2S&xMfic_mWxSHevG=F!1>~hRBePgp~sLGyZ z%&P^aws$J<2uTG~Wxda&nCRjY;G^ix-j0^~!~RrBxrf~qPzC*RGe`3|GsOSVb(^s43} zWgmJy?;^}#)>29*_hE8b){}@1YL6F?XBp>dbN@W=#_SBnNrV{ zq+!{phEA~5)bOBO`ATDCEn&MCGLZ&(Qd2e3V@4mIsoxZfJgjre&&O-f@0dINz#o9u z-GYVbjpnhoRYTM1K-JT__iTaO3syeL@xWf?>tROaADapb8ea7}I)0Y>`Fr%3Zk7!C zci^~#7`;C6YJVQp7o5jfE_tT&_yK2VAN6IY2a=16ORa`|f0YH91A4NLe3t-#wLnb6 z=>;Q1qWyi$oI0%^wUutQQqRlhqP1)IJo?qdxRVQFqeVJcyEDEg^LxI@Q3% zk&boBcR#_H6yM}7FBUf-e+?yf;ZE|3V)kt4XSP~P=S#VWewWRW7jy2=+f#9#b1_J6 zEo&5MqhW{;HHMh2Dg(_uRah{wy0igq4{H$v`NMZ3+qxt6}L zjaBk``bz#1M2P8c_9oz**TRB%TMYa_$}aWhHgl-~SQ zC6Kv4`{(Dm%->aGqlXPynWaGYqzPo}tA?E_v9PQ{K}6yh0r3(<<&T8h-o_kY^-rXC89^#j9@U`qn+_YYgM z{`CbFf+4}K%wF8RGC4iNN;#cx4})lywompCYMgx0td7Yw1%)1?=RQhHmMhCrd|+JB z{2M*q!@YEplx9Tdwi+z~P{4}%xZ#^ioc*CTmD4cBfTlT*~q~rvEQ~nDW6eBlw zC%#WF{){mmP=xfA@i>Ut^?Oe;e7zki7xy$=#I0+veBIKsjw2ftYj^+^16KnY*14bA z=c4L?^#5};+Bcyd>5bt3GbVihGp=T!VQc2N zeV7Z^iFU=K8O0ytxKW*NS`F8L3^<(lQtG|_X{h(}uZd)u?CQ$}8Q(&g;>p_*ShlL_ z$yzp;vt!&)L8+VvN~^{a0;lsrG&!}s;D?(_pNkda zopO*&3UyVWHmH!|H4bEPIgdc*r_2#ML?t-=WU-;tNsWV1tT?&J&qc^$5~0 z`(=r&)O*F5x2HF=U&)oXY(R73V@s|=V9vlvHf@d(S!=Cz07tC>>xb=fGu>WMa3Mxi zIzwcKURM{XU0p!BIEp1@1mYQTRwz|W8_~EJfq62JiKQ)r8YlW^ zZ73+5WnWSQLs8#2?;;46?3`F>Ay~%>!D^iBpJiXh_mAouAGiqOKbv{WIwAXOB`xo} zA6*2Q*9Z&}RzdS24zi(^GgCYDn}qV;^1JkuEcKv~6lD3$KHYEj=~XL)DPV`Jo6joU zsRH;27I8diR+C8z6j7-t@-Uq!FEbP>SO?b9q?H{tibVw&JFHxooJq7x#3T zhNsSzZ+xs5_hRF`q!H}?#E)rf>`VrlNGUINdZc#0)v&Ob+RV|QiS5O;=i=&K@HUJ8 z4kHe(;vPwCDIZ)(?Ou7aCU(@<6vw|cv7@-=oNwNCOVn8~$RL+ux}tfqbr5yNN)3ja zW6ZB|nRFkPm(UhbROZoqWJJ)sm1+RwLI6P#*o)^856=U9jtoTd=ht~i&IO0)LTMU{ zsf@(Cb<&}%nZ{=htmb}ksaK^7Oyan?8fBP-x((d@T!gl=-TqvI#pFi*1J8!=wY!?rK4H~AdgSo~F zUJ33>1W##QKN&9>QMa4QSZZ~2^DI`wrIgM7=u)Tn0_nN&Ue8@fDV?ifR!VPjM|{e% zI)!w-?8-miCT0vVq`Kt~vi|OK_xEu5?-mi!OLt2p6cs;wcSp!NslE7uFLt-MiCTtf zAe8JQb5Kl5QXIP$&TDk5N8vp37CVaDlb~*LT0O6t7P=-H|EU5(t%4v^0%HIo7#T+V zfYpG7lZ^O;JnDJhBUJ}Nwa;72mhw5`gGj8EVo*B6C;d@I{0+g={v&?S-G8x}LW6}X zH-nby3#c_-b$MCMN*992o%RTTM(h$3h8PZUpNYDC!H zn`l6JV>M}i@-3>G%s-S{GQ|$Mj*?kuq~sxoNxmqNsfF9`tHAifkmRq8>xEW}{n3DQ zSawOG^?iw001`TfSSq<_NRGta`gb}+e&5;blw09#F?vE9uC*^rH7RFFJCNAyXd+@ z%6o@&**e*O_uDM2eMC14nQfpTpF{x8ohHl?Y8J-Xtxv+kEF!}F@yYnfEhSM#Zn@`~ zpAuGscu)2~&z0Xok(pR;k~%X*h7-ZO&oncjUPUPT5V=StZ!DGkspcMIPoW#p9oqYG3{oI{?!GGHt0X%&QPFhQmVaU3HRYd%l#C;W*lPhzw zfcxh%c<-j?|6GquFl@h6Z%0u&Yz#^2bdid}mTNg2!mQ&+!r7ON z#CmGBj!+TwsxTyeDY5W#$``DmAQ7_Ru9r*&vv9Lo&aBWS6-Dq2Dk2}KF?1Xy^Ffvu zJ}m70KsgwN6U=mL!b?Y(vWJe%$i@g+fipDmA2QYY7YbNX=|JP|Czp8Sb4Vr?zltkeU>Vel0vosvh!XFkN|g zmr4Dbc9d(fuVkE)YR zGjGMC_=${y_4lJw;rE77)mGJwm{6!6fA$j6HzI_WhH8`b4NC@zaE6|%tu_{!&d}kL zy#ep@72OFS1=+gV(?ketBYP^U?H`mfT#W~<>h5WF>r&40lY zi`x?D0DD2)$WB2>6+R>!1cj>5-?hJ5myD6lW}Kea>)*gVibupHlNd$-tb=UQUR zd7!%9nS2e`2Mw;X*6l;1x8It0u&(jRq2?s6_;A@z1G?sSvLE2cRdH2#N$XrXKCnSb z4_AG_>^=qB&h}ZLH8%sfJ7DKI!SAQb62xC0xamv$%_iTQZER)nk&8Bb0c0wqN@Udc&uG>A@#f4`1aNi7rUz`AQVQeMwJ+e8K13$D62c(O zr4eGVBIKxUqQw{46$MwuZy-%$$SL{fSfK>si2ek(qMQC9y&fxW@v&2G#bN2}ezOHk>G*e9vbdRkulqx;>_niQ zTS1GsyP}B?PD$>E0_pVTr?AH@aCaf0IAlFbzBhy0p91zvoKVMIvOWFJiNzJZ_}xmJ zhBgIs-ZM1iCBKjXnche@sA`K9XC?Gl4Ak@E;tcHqQ;6!%B)G74q09sK=y?RGHw8BgCsSHK>K1O$vKa@USG>tTD4TLZ#-tgCil`urtTvf{s_=*O`kp=dV1{g$0&KkFlx0s9%e=P~*-`i*{`%6-AVES(9* zAwoa<)6kLwiwRrH(sX~sSuM<*Y})OYb;G^}`2lK`@yg?cxl531fQK!p9KEgI{SS#J z%k{I>@T~MHhbn5j;_qhOl7Qn((H-@!{gJ9&v9FHaW}Q;dmwrV){nq%qVdt6;Py*dE zC_7zWpGtUtp-lxo^XJ{y5J@)-RWQ^4GBiZ#Vf&M46_)^R<_^?oRcExUGkofv=&75- zwR_@f4=BarQ?WBPJ>*WA!%J63cH2JSuC>W~jtiJ!zPq0N)a__+-0 zcyT#>HS_E)1hl0E>kErZ5&p!k&NNC3xX1ISf-k`?o&S(F{E~~haZ;&9WJ}Y*7wk#J zqg(AF@ncJW_Zuck9mldqsXi?=excNPq}`Rh+^Z*kIshD55I={^qQb;CAI}zbX`u_`UaC zfIj$`t+)5cO&Na?cbTK|F5_cw<{hi{_7-aO*31?L#16gy0h5qgk2#zoRV2hb+07h{ z@0?&~=HE&81^QHjHS&l^`lixo?JL%gS|jOM{%GxP>-)IFuu``RzmDA>xfHMw%K zwJtX36b>qJ6dGSjjG2{uR;Y_Jxq?K^p(pa#Cf83#t>3@TfjHbs_iLXNzI3=u7kevM z%}}>Sd`!Lr)`APGaWj0Tx&+wng_o_o_E94YIwDy+-Ob%;OkGfFDPj_hFZmVf? z=&AioX8snV+^MsE)LvKma%`BYQ9u13NE&@xWpnl^!c??DTeuY{eI+N9w{Se0E7-8f z+aQ?2ODAj|M-HN`Pnn3#?gejP@UmzpK8WeTZlPWg`+Qnct;{4n-^~cPtn@#SdVbuM zZ^yv(1%83sBy|7#EjHKR;i`0u(8O?zOVQ8}0Y?Jz(-^ChE%*#{3-KcZiE*P4HDCwM z5Tefh10ydwGDg}CfP31yF~YE*%CDf}%m*^9$v=WLvD=>@ji{1E>N&kD(t-#c!*NmdN z8#{T#+#AE`%kX!)C3aOf4cVY~ArQUufh%{oPp)kZ_*OfkazPKy5~}CFi_>VDpNs9X z8s(B8>M7N$IT0SYKiSEc(U3c^9n8iR^aUk=z5$@*FQJW)%Okl~npVWWIsp3Eb=vlf zuw4+)mBC+iWq!px(oWDV)7!e{|B+NO2dF4p z_r*T(d|ro=_x1X`zD{#c!4NhYT#DC_?8 zIoBa%3;K8an{XXEuCMUo*1)?f>Wn;s(3uj_dm4u^w7K%fBuP1uuAiR)1Zd#=#Z$hZ z5v1P6O6yaj&romo#=@f`H3IY{2_mJ`NPTVBDBP*AWTTiR&TYh2TWi0EjjNV&Kanw!*>XxsA6xgs|JI;D6aFHBHxp!7_e_ec;c*CvQ z6R!Q(S}FpEh`p1J9>hMzS|&nDyjfgmJr=%r35q!GBP|Z3FR8?JW`mfu;fWMwRmPM5k~7ASVWR47l~5%X-6aONgHO2xP)(b}YP@k>A_nCtF3tW*z_IhwxV z!U_TND22$q$ZD8DhRmP&)~|3aG+&8wLy#m9#kERpJiEMSi}zHf1s_6fyV?I1PeV8m zbw&-!^P@_Cj|KHaaFuKyVXeEOII-JGZ2p{;%}soAaNcXPlJ^cOh`nt2C--<0irpk+ z)(-x5(@ZMKl`s1dV=sjKwPJRcm1fcn=Scf+?U3IS@$iK@RKx?22|;!i(^-~$4Z|`>xocb?klm3Eg7wr-!R&VjBPS^56Nt4 z=H32xby{Td?Fawsx8@)2Kj3ynY6^b-g-`Hv#dV?@n%>SGPBasR{Q|jUJ>vp6Yc1)L zs~y&CLi}qsbh8YLiicb2-%9du+}mX8m@A1T+t85+b;XfOTg@&X83@L!#}`pVRAXZO zub`0Y#=xB?K=z?;%0Si*=Y<6?=$J$T z(xE)gL3f)C^DcYvhB;)vge>fpn?)q`dYm{u;m+pegl(KLa|c>S*9+VHXgSVo8%t$Z z=2G+B!1HeI4LdbawOZJle@%WI_*M`^3N`wC<4Hk1-$x#-*B1l)wD`>Ji)Bs?y!S@L zQEm=Cw46&{>8*s?>ks9ZKPExVL(>Ka2Zax?Gw0PPakz;^KVu+dQ|1=oyGPo%xyi_p zvA(jG2UbmeWnWZDc&=3B8wRtUvRcMbKJ}gAQOS3Z{^&kA-p)*cC|*>FyShhYD~;io z{fCd#h4&;Mw})$m7uP(b`%Y@li1~-+jyBt6W>D(9F%QX3!Dbvz-V;mh9Xs!Pad-Zh znDcV%!tWJSv9s+U7S^Ad*F5!KrDCwe%8N_P3Ha zK07cu8^>oiBC5*0Gl(18KmJ(i?JAYRr1lJ(f6!otY?OZmY>S-jokgA2+5@I?i!VB+ zXuKuAj8~nn#8Qt{+=^3^vvP|#Yy1kUDetPo3%YSflAD~wgjA|V_nTN9Y-k~$lTuOR z33|bP{`Ui};TNPKXlIjDMn)+j9V=h(c?nZj5k|b(mcd#NOHlRy0$tta{DBSz$IPshq-eMqXaZCO7d4uo*%{^Dop_B0L5e~*#t5nEF)gWw@*7k1;lY8%5+7^fb zdG+rQUiecodJQHQ6Q1nx)1Q$G@t=2Oe+Q8rB?}ov)nZVLOc{yy%gjg!D*4qcFqNSQ zM8DYZaXwe1bbV3Q7%Je?c=C4*Ie%!IXVGtG5F!I@&z~G=A~PZD-oH%g;dgNgi!r6`D5NdN+&x zt5Gg6VJ4N-4FsU1%{lO8;7^n7v?))EcP%d_F6-mL-`~B)R?Ox|nlhrIJkl z9w_U;`bMXFdA@=Z~r2+6hyu9ohlo)XXuq`*7w8NZK>s#ITdY zLKR(sYi~7ga$M(4be{MYF>j*x#4vEv$d9{9zqw)krWQ@C?^S&0)DMZ}sA*?;6j1;_ zXltt%Z!8zptu)n^OHsJZd!RTZnLVU|J_V5)_ zqn#Py{#=}b8#{S%2u^#e8XvH$Ux?Sfw_uoFPr;z66>y7&0!WZc(?Vi`cx$N=Fd)4VCZ;Bdjb87R_4 z28k43@VQ{#bW%VY^QP0xY@0V7bnF_^hr*93bXspIOF6VIqkMNm-Jyw-^@Wgk5 zTruLbdAekCR+#0oQcaaP3zI08>2tMUTa*5*SSCLN>r^DX(-jQIQM4elRk}j3m^Ru? z9zk6yP=kJ1&)vK;4q3he&vtn;v;!HIh^uT@JqIwB3W%H5k;R_Xn~FvtXV@K5a$sYw zO$*^kUVyHgO>x%ybbe$#tER|mh(N-DozeIcS1g6|EFa8|Ad@Bjgw@haKBHInwuwxU z`#S(h)ejcw{*J)+97@ZY6EMY6LK?zSVirG`N8D3cLq@Td_-(I7VSCzdkX2h01Lw{O%!5btXcwTCXyvdLe2OQThgkaOLsXi!Ts|5 zSmsXH-_uQG4Y=Q@lJ8L4%t5tXrnQOcv5EomWicwiWd*|c_5#n1bo>;_wm%Kr=pO{8 z#)xbbA}Uq~$GtC_ICB#esK2vYJ1;j)JSlm)Y(di_s;Azvo)yGt!g5}KgotT}TUK_9 zN=nHk%hlVxmTQvP5MGr&FWzHr`HzzXL*o%bA|T6`J(kuh{u2Z>Se1|QS=SXNG^B{1 zoS(cT+AES6N{+ML5x3tV`&xPqNHegsMXiqnPB)n~x)R+D^6ni4#UGsO+AKs;z7VG{ zc?nY|)eJ~biLMTSYWK*@%tfR*651;g&Aiw?$~`=>s~F5TT6A;Gm;H?gE;^J*5njOG zC{!cUCe>2AtT8Hp=C@)}at8K~U20N-qXVe9^pKv&y4<8IZ)B@0dSr;UW&2Rm$3cVP z-A`w%wQAO*CXg5+>3-?iVzHG< zVzmqyZ$hi$PG3CaVRypF)`xduotDiR>$EI=6J|(|7aNjya`mV>#DWp~Bwx4B`}eUj z06H6NnNqoch=oTL79NkWp$4tXm)vj`b)x#+cr8rw(k7(>i#p?>cV$2_$*dX$zl8}% zBJ@v&S|QDBFmMC&KfI9#sEyBALOir3H8>MeB(2EyFVi!0EC(hleIXxn3Fv_2F5u(^ zwAY_!Xi?SDW@=B8Eba!KdVEDN@N(4f77BxvF-_Kba)p%h_w-5oYEKV|E|RRug>c|VJ6?3h$&pKJ}GCVw<;2-FB)i^Y=i-gi%(o5WJ?vU<-vm%H&&^I1sPn^*K z=K$gk^q%{b#bOKCc&fOCV0p7Ij3Q+)Q^0u!WRft|to^r`Z&~vGHf%O+jI^Ysj6KW7 zYa8=oMe3%*&UKi_Iv(43WNKxnu{mr^udpIB(YrN!Znf^f;;LdU*<|LGJUO{sE8v^w zecqv<*q~K)it;9B^+5`~%r?233%WYw%s|K%IQNH2`te#2I>2rJT%r5UV}prWDIJ5{ zt6CAC`qArp+u&}#?A<%rZNJ7hMoEnhUIL+V!%5Kbu^FFSLfBC$zU4K!Bj=R?T`L7A z1z&RKN)1dR+D`EIg;eYuXcK~zglFX=&NqY{-A++`mu6(26kl;Q;7`767N6+2Y^~l! z>g#OKE;w0mT?BM^rcnInOmvde<-F_t8rK_v6rx|gbq!V0zC4#vZ|GqB%I>4SO#ihQ^6~HhN^*&mi$f+Gk5a7p;5(vKAVJKM z2L~s&eV%t8N`}Ebo7n#84fyZKsRFsh`Y@4@Sb8BRCzr2Buk6>XH619xFB%+GF)q%z z2lbW$9eqcPz5Qmk#4C_JEZQ#8GUp|445PJaIQw@#S&7-&y?ja>xUsgYQg;HX&## z+cavlD5a4&a4_2#ch|&#l596c@U0E5d+f-*1E!O z!mUc%R%95ys93ERAexo?+XVNxGurLU1t)RBxX(V$T-`RKp~#R;2{-K?4Z3z)=@Uqx z*86d|wGmLo3$wN4YHIXLO?%NzQ))x^bAVdZ-T!@(eBa6X7u`^w- zGH~>!zV*g!B9k_~`hZ>~oF~20=mezCS|TK|zjJSRC;TM@IJuy6TvLtYe=+`zTs)*> zXbaG>20FGv#>Hx0N7HP-G3WBiLg$b?WSNs2w^`|P_ zLj6t3ILgc~d7aVmH?jD*w$6WT?k=pnJgb!?~&dM)6`h z)ScgffVP6`jN;sMf!a>xLRRwz88GMT;Z37P`ZrTd^JJ#g;2R`_pxBm(0NkRavf&(V zEGYkJ--ZdbIG##Tk(~lnL!cj-Qp!k=vr5k^Jn_uwcIL`3H{KDZR{Ss_ zLwDTs1W_XA(9QG4i5yI;I?jc8w--QYz_YG)o zedQ!kpd~on`^lZT+r`{zfyAoAgbI7d=W^d1qR%)!uNMsc=PSy8^`yqbxQ4WA_a=8r zY@3&H(Vr~M9ijCrt0=+ku#n~iawNX0PfQ+abLCmP7f0o?{6qWf>b=QdjeoJw(^%NZpSxdh~*80&%Uc;yiAii+tq5os< zblp=&bK?LpK_uqJN5dT@TES~h4UAYr%ipbZhS3>x{%vS^r*RBi@S%aevQcbL?Zve2 z`!s`_oW{%X#(flHI8wEap9t3G$TLr@v)WMTd#dpWS*F>hogqTHos>Ih$oO%JNgko> zIvq-u=f1t)eGNfSTk?&UVr@Pg${XqyHxEl*mKnruPiEOAX!Q>{7GP?}>u6k+%0~wM zIQ?!lKcVl75N_<14z_%mY`Im1`}jb}1?IkRsI2U&jSAvh5uUowp>E1>KA;BqJwuNS1iW< zeONNaAw`g;a9~fKY7Xn7%QcI`Iuc)VTK`Z^>jkAC?i){sv0)PPWhe5$;yAdosJE!- zi)sUSR#6k1EW@|>QE9!O%Yt9b+e}86}8QCsG1Frj!rnAM@N>(&5 zA}Y$r=0@Y9m-l3^s2;Z!u?pA~!u)JfvF6Cu^clP$&JZDG(Xcq~NO}0($oq$}c{lAD z+4#lT%giR1KAWNHS5T~0OH1~W3R30558Kool!OY>&>D}&sPk-Vn>oj7*_bowXm%GV z!0sXgj{t8fdf(6SJFLOkT;G~LoYZ>fPxY;CxqNq?Y;_Og0ZdycmAmRK+{AVr_P`QUM|`_T}bZ{Sa+-#w6wkF{1uC*i!; z&+{2w#6&x+-qFJ9u|exV@FT;(tBw$S+LRMp8~z;4O!+eRpG*@s4bTo@f*-FbJXQOL`ZB&s&-5))g|g^{uN#lvLlk;W8;;M#?*0 z4(W>@6*L}1l?Q0-{`fvY@qO#9V>#*7T@9)F+Ako7&NFJTv_WLG;CK~3jb|xEIr3)6 z0+NxIA`vxmz{ByX*f!zs!&lZyG?}jLh5_o4Fc-3d#H2$aiDjA4Ph29K;~-yEwlSW< zfj_4e3u$yyL(|CChTme{wo1i=W=GW=-rY!XkoYwz-NXa7lFB%0&&i7s#0X~EumQuQJ=% z=l=sC;(B(Phxk(Tu>8rFl}TS^7~bUrq;pf`GCml1-#m?9;9 zAMhve2aWS#!bWklt_vl5ZP#3R1s8Gdh!;`+W#%Uc{O*WF>>j+$mA66W;sqT?H@J>z zXkr9K6Q31x+NDy)DA;)i+zap@0kcRFFs(YXQl><#7r6+OS{d*EX`rijiUC*uI2&7I zjtKN?8*T~NP>E4B=Lv0B7^1Ml#fy|K_g6VP8armUk7>By!v`3SEdEiQUaaV$2Zu zG)h&|DR>a8Wh)PWE&g~;H13aj64n2dsK!h0;gc=mad9igO){(EnHv!@h;uIys{Oto zRBIy@i39hTXe9*7knlq0$WE4tA4!FGw{UKZ*UDo%tjFcTq&&P=T`rh4Nm;&tuR6-~ixJjl8ptdbzy z>MZo^gYjqXnxdPFk3R95TQF|eh*wQ@Py=Jti|42<-O!tGRkrQH{o}{coPgL+aIhZ!NIibua{C}j1-Ym(%Gie^8QlGgHp=} zO0`q!ekpZep;U<}wXDC?vY^zmfl{56T0W$$XT%c|K^k-z4UooPp9#z(=>x@)otIrR zr1(9i`1HZW_2tt-4An?3x9kL|!76}#fvI8U;2QMB)F6)o0I+Pz4jt0#gSEIA?*t?K zDdB+Tns#$DX?JX)-4`Zm#}^K6S6@uK^4Q;QAi^x$A~lRI)Ue#tFl%rP`eJI3$AKCm zlFKdok<@Tdp@xf14TkIlgRd{926-H)L1-H_EF98{Lre|jgJIAYQ-eGX)Ue&u@P|tV z_hRcAIu1ozLlDbIUra0`c{DYM^eZDp`={=Qrf8Tfa>(nPJ>RF7_sPm<$q@8MI8gMbdF(Kc z?L2mxN0yG8HIMAAZnt@4X}CS+v6aW|`e;;9h?QX86i12qW8S9gsJOkRP!omv%!irg zLy^K`-0W~hGthyHZp3`BO}29Lw$Qv)m^Z};m|pWH*h0A)^QLo+e;D&N$9$_ZZ#s*P zYn!)n^KH7kIV)zGL^GN0EZ(>$ox=}&85C28TjD@vjP4W;g7|iQ=xfZ;`@*70ai)>r zP#g%GHu>Xvm$!Lfy=JG5Y+I2bg&P~b34%i}=P ziq&q}uce03g&J-$H5eQZYS0%`gFFt@5YV}AOAQAVYB=81U{*p5HjB9tUcWg~AlveZk;ftTHtekyB`vk~@8|>Ny`Mk4g=4G^FTN zQnY{eZZt*1T2vUt0ZNIs#~?}xhg^1^6g{BO^OH?cVQJ+Y?3SH1q~?S9Y-nQ-{2)si zDj*TK_}MN$5^ogZW*)OVdgf8cqC|BfgAhv-)(Jl;L^hLK@JvF8Wmq2#K10*YTb+)e zTW+$k#@!0@!JxKVW!~nRY&GU>rg;;0fe;_tyw&NOx+JsB2gM#-kD0fHCfiK&7SP05 z=1p*hrstTqfF{m0Z;BX%mNRcUmxPuxZ#v}!tlW8*&`AMzx_<>mV%1;o>>FimsmvUIxHV&M0 z*T{So;yFpkoq(b?YB2NVeN=;UQm+=@OM^6k-LwfIy+$^|_2uyM$Veo}&CFi@?+coG z_R65C7b@g5$xb`a8kfov5N%D5u;qm51H+J;sCE@RF86pEN|a;Vv>LgBLBKVE{suF- zPzpIF^jT_UD{r)Kl#r!o56XGLNiN4F;^lIKb8QwAa)`d-h^s;507WX{a^AZMH*8HC zb~6mat(NYCDSF)MCizCFK@!orix1x*ZBT=TB6IZ3p14AQPJWKVlstIPVSU2Nn#(hX z92QwacA9fTMc*{%)Cv>obRnOpL@GyL9c!C+aLq3hjSPn~%5p39#L)~CzU&2h+clcX zsfwcO!z@TUY^P>Lm@@TqXp=mUhJ_zGDs^0RPhdjisF}K2vaXN?$F)esZd%DKLqJZU zHbukCvOe=B$b8o_@yOBIrns1yUO^_sV=+i8oYRcTtBWeHp&9gB*Sfn#+Vnm=mAVPo zBn_flt3Rt1OSne1TK?@I`Fw5-lQ@_DTan>bEL}?>9R9<zTleL!*-MW)ud81Bm zv}?!k>+_c-5GfsNPi)z?1A$KzUpdjH=f$m7ES2pOoN9cD3xb{8v5yc5#d|ikV^;I_ zBc!%JY@0w;xqIzzJu;UF15I~cA4-k^iDbf52NFw5xZ6`Za{BEhKJOM!@!{(y8Yq81}h9f1`s*~Pf+ zX)r};m$RWmCP=*eXn?j|%KzY8sUG1_5Sn|#99fHjIX0f-9W`1Z!EDgR3A)yhr7kDA z%IQ^*bjR*`wHPcN@EeFRxxlbFEr#;?WDM`&w;cT9SKh7d3*mOOo=}OB? zw+m#&U888_y7JjO{ZScTS62rnHUJCJF!XZwiB`+q7@YyEGEAI(Xcj86TzYK+-qD|S z-Z1)~VYO_LC9*DStxc>-^&M27xv|4)$pU7o?_j7XA5(p$RvHfrdNt5bw_B;ed)n8A z6b{)uYsr=B8*8Pf$Z`pMU(^~|U1mcQMXcs+1~>uQw(iqNj0MK3nmFrE@EN_IXdV@! z-J`6fU5CqiAM{a%I_@4%0GQK``*3f5>NgJgo*jBG|08u+=<*T>U-BYmvd= z$9H`i_&<Bw?q*HxgveqTqlcTJ4t_90c--V{{v=+CMy8p{t(J9;IgMsDfs^Fd@eY)_%_c{sXD0W zuXF;recOEETBtw0duU_oi<(Xhx0dYr9F$2K)iE*cQEx-5e}DiZ>TFA%Cr=buQHM1> z@79F14Wmd+6f>_gMs~d#DS0BANznaQ#kiR6Z=w5L;r^b(>;nauD?QgiF%aA?mElf> z9tR?uw8^MLl)KfyFry!a83u;>|2G&I4P;9O02z(kIMce=Tn4RkzQ?3Tv!o@9qEIkH zvvF9*u7KtLBdi@x4ZFB;vs%R2s*t(ySv-XrqKw0!KB|DG=9M=nwY4tIkPxPU|RwlUFQiYA#j-Ux^g_#2|C{N`e=d&TkZzw;Zf zy)irg4+U-ci5onsN*+v|@&Ng&Y2f1FwQIG`UXtR@ZqQ)_Xr8s5L&9z1Mtl*xIDDj2yc}w?1Cr z(99hn|4B0JQi4Li?;?lUz=J5)x@_5^!dMeosUMN|vpaLVbmrx6{EN=~D>N7im|vs4 z@K4|euN=j(P#2b-{A^Z)3FbgR6;~sP+S9ExirSoyFJZ*Y(YLzCYQBc^t1K{COL%nY z=M|R8kPh9B7F-d6uIs@U{{U?Ka`ZK%6txjqW9&_P`008j()DJzWOK>W1dT$aq{rF4 z>-p>}aF#ReXFOs4>YDO0Zxd+MTDqH^ug+TgbmyU9g7u%>R_aYsz+zeFTyv9|fnUr= zf?+mZpW0n)r5|M);8Lv?0v;4OPvKpLd)>!z*kLvQ2PrXpBBlC@t>(C#2+@^H?f3{= z@M5c_P7XtvOFxQca3q`Ui@7n5r;o%-UTB27rIOk!vd+%NU;49YP8+zO&;W+&rh&Tt z2GFP6Nqwe)eKf$C@8yV`w$@#`kLo{SAHW3kn(RIrmVrQrRmZwpeRb+k-^&mXeO$OXSaGFa-1u^qs?n4c z5dkE`wde}PmgZ6hgIxrF2C8#mEiIDK$*h*IDylREG0p^o3^~-w>4epCKYRdr`#|pa z#MS$g=!Uado^`VZEl*JxfJCL)m|iv9$^NQ-um6j(%3hN@`U10&jz~0t>~I%(d8>1m2j>Z6^W&;86`VqVelEI3Pz)o z&`daR4TM;MJi(BD=|A4r8ruE;B8E#r)?mKnuv%5Y4PXnm+~DkscKw5CUWC`9cO(8U z!18)MpVGAiu3Je&?3Oi5V`hbJ>c&`(EfOzWV&8{_4KDvFiIJiV!u5ILX<*NzGOE)Uuia-Y`6dNepd%6($ntZ2_%gjj+UZSBi&`#Z?_e}aMVH9g z=%1yv50*f5j1(H1I|yYT@JuH)wKB}y%07pgKKAPL5AlQqJ^@pC@qRQ7@*1GRpqYl=0e;- zKbX>qNFGHH08!>xbYFKm@?OCcWeq8lyS|{m0~2 z^M*&5P4;n&bJlL+uoN%p0$?ZEI+LsMxkbQmT!du39lxx6JPVF7nzR!>OCbOtp@w z7HpM%;HwUCtROSu*ogkLX?>+ggiDbOm*PoqgGdpX53w2FTqzhW3GB)f!4H)onx06i z+$LzOB1SJuph6uj?w6Elmltm(3=h1~GHE^on||FMarFc7T5gA)UN6sF>>`fDZ@X&E zr~Cx^|hf)XHW2uyv`%KyZ(ey9m)eR}e!I{Xfg(nbV2agUcTPH#Mys zT$2!RseedWuVb2YqG6dVcPqV)nxFtMcI5P)<*excQYtT;bFN@t-9EI21(QHbJF{px zegLlP)m~rszWfAB;l3sj=*cZ-^4MTCl-|?VFWoKKGi`m^Y;#}Gj8sK4`qS1aKc#nj@~!l) z?fTQK1@E@kcPAQa#Gzr3qqS!;6-?SjfpT2J#9 z-e~yyyxC6k4)bl6T*_3rbM>dKNq<%>lb_ONIWp65pZ?q(*7ko~&JVTBQ9h-)O5eb0 zr@4m5xO4Xe{rR!5Ze%Mr*=$Yx#dMQst`(bSYT{jRL6S3Ua?a7j=DC_E&LEo?%A@n+ zCX>=mN~?KX&f_v36f|rLNXeMiLyj-f_zsaI|uLDQZ#pCfMhlZ7N2fomIZns_zy- zL7*^G{WtOxnN_X1sJz5s^GX+(2&jeKYmF5%y+_JZ%xkC#@t}@Ln>~Bt=Omo4b zlvO-&%Py0${mmU?%F2DA0ac$&+2E0~pp#p6k`z3+(CFKT=v*x~aEd;mz$w3yzn%P* zL-PND{9G3k%Zw6Sc<&GmA<6aP-u(5ELajg0T!>Y!6{iza)&oAYl6CK(T@DpuX#Fzp zI@UqMT{mJ{_;JDPB4f}%iZ*PANXX$rYKglmW!n-3VvbMg^FTN@S-hzPSCjfu&Wr3i z`clP9PvK<(FFOh^HZSG|P;BeH*KqF?y$h3BOytDIZ}4)^kiK}YW0ji4GM6K@9)7$( zBtk_GAcoms$ll-$#;cgc-B#wz%0X4tZf-o7u*7r+BY9kqSBAaYr~!{T#Qh0-H}Q;e zv8a*`QbKNJ)nv@AzLU0CtB@zLI}o*7IYr!w@^B#nZm`dKZ+x5WG7d)=u!CIh<6QIzN$7g5*beQr z-Af|ZM_|m*p5J0;E{@m}51oISomo&GbGqaZW%c4ou-HP(7il~=;YNF>PQ1w4k#M@^ zy%NJ4E?yJ*VooIHfFdq#-4NJ{1dw1QEf2qp%=b6@K@>0}UP1tS0J41lK|<1GH-GSb z;6HdKF?yXR{SkaJ_t2b~gwpv>fu#K@S+K(Y11X$`=n!fX>`a zQ+D2qW#(4JCe97dzcQ9tSiu^p!#9R9g9t$qPPg=N%nts>$4F1(Vsir+F0!F)LyYeh)V#Tl{Mo71J@aN8-m}zsi&H6v0 zK*wQn3X3@(XRcV4Tfa$RIG7d$TXKYV(?cdGAh6XtdnqkPO+ zDzlI)CNQWuB;qu(A1PlzV5~R%9rMEGqBMXH!s)`QI7iH^ZD`%`O+DDLH?YZ6cnBg3|<}kIrhukCIBdBHDBUi zcut`rhr`>A6ES^!F(MN-Ie+yZq&fkWb1uRk_g?ie#$nf+&&Va5w?A>{z5NV5eS11d;`^kRr+nEp zCV5VO@?1?$NOHjPt5Sn9`)`gB)_*93C=q3I^StA*_VvERAHbA*DcK4ntEzStV$TYm zdM9(l)g8hXC9jKc0imafcEOTE&m64sl{>PiZ4Lqz!L2^-G6e z`Uf4JgSU%*gU0=>K(>Q#G3U?7(ly@DUTf_V0rboZt@KymoTI5br{mG{avl?zb;8Gs zVH|NtmM)WFFgLV0rsEv8AU$L7X|8-?BY{|-Q-#f@kPXhILP*I}AwQedK9jaZQBN2? zeRLPW@U2lQ(|EMpD9q?++H*nDX1A@9QV2vZ!D6Q!6UkMx0d4At^)=%#G+aPwYtr+e zO^swTw+E>+uqe8AdGh#p=4zCvt}oA>Zmmt;pGo`qlhO(2@ojYJ7@HW-d&4aPQ>z02L7#~uPtv%$1qbx z+*xk4HWmtCZju|9SG?9=$XCMWGsF_>hB^W#-|2BUYPwOd-!_x`#Q)ZMUTp#QBn zu0Zc-v`m__sH0GE0~LEz+(5;0w|VXISmsDvrshw?xT)PrcatAmtmCAcyXvY!$VSAT z;kYm&r7FHrnO##T#+4d{SX#ra?^!a;G$f{1hT(p(5erm=D2VKA=i*sBGtL)J=a=*0 z#UR#EOz9jMK<8q1!Ud56hwWTkZacVKai&$po$u5T$!h|?b^LGpGASU0Db{VH7bKV= z5=Q0D{jA_jVZ1*%Cgc?0wXbWpatF1m>y5Bo!sW=0h^Q$9=Nk0ys27Rc(qPrJd_cWt zUXYv|%lxo{o}$Y{fQ-!Vg>r?$J~ddyf+Ox8Ew+%3mP}D z;v_YwNxUi!8MyITH1|~er$!Jcv-X<$aQ(w_ z0daQ7;vXmQxn+H$2|0!;7`=JdJK|PhNIsK3O^|V83F6&P3a7q`_*VD_JQazfBJooM zg3C9n^b(|f=OOJweP_xnW@ra(BGRlOBc_!XPe(hnN0NqEqeG-VHSTe#YRqyXkQ*Un zM=~Is7G!MopjHQAtKvn@cGGEW0?(*Q)-V7alz4C%K<3LvoPxI9Or1o$PZ)A3C1Cs; znhM84S*{7rR>XL^ywVmk)e8AkMIIJiePuZV8Lyn)n&?j8?Y;km@Xm6--vV+CX` zt`NPHmf?bK65}*;akxJ7bpoYLL78u>m6i|Ok6P((fh z*mYsRMHq*>)B*pZBx;72WxCvj6~qfGUobU3aZY&t-|dOv1urKY0g3owELRp6VGO7* zbs9C>*F7y_aeMgG2qXkd)J;A2g(3b_w79r*njYE&WVV|?GenQB;4WLux533u#xmUGpUh$&ewLGRulYr(2~{rt{1EOkvhTRs^pJ5xgfvF0HXjzs~=7wkid4 zN=F)OT0`yrYWO(?C6j#CQS+jDXT=}*Vx0ClX>l9HU1Ya_;%pE!g77slqucd^x$1X} zmbGI%PdIIYI;p0dgzw(LMy4~>J? zFWS${(;d^!a4Rd0qbCWzc55D(I!8U=Vv>r}g>&7p*RUlO+rtsUIAgb~cKQ{tubUIq zA0z9=nwRVDk1@*D8&{&U$c`zC1Dk8kM7hJ&!2QI6{~qB&s<()i$pY~I346<1Q{7X~ zh&jD6uE@@H&m4Jf?d2mQx4by-xp=L$U`uW*bp-k{xGXv_R(tt@ky}okcXGUT^erdE zYo~@69Gl2ob6`0>=+PctHAjjR%{ISeq7Nm}bOSKI>yl9A<*FRY9&(q_i1sh$IDW>G8CfFeebk6#4z ziFD2RZIZ<;n>|i^#k>jnc6;U5W9K}U#NV)Qc%ykEq}s6Dp~j}Sqe$YmF6zve-F0HY z(l^u4Zlj0>S7a&I3VXb$-9zgUGVrqZDyHk+4L=#g`wixIGe_H*R1vFQiXYU^^h%1i zU3%$06qe`9YlQpUn{PaXJm-c9#%WmC{4v9TLxV3GMpkp5NbX$N+x25TFKD@lDOW&t!ty;6!t$vggyphoCg!VOmlG`^ER8KXAuP`g z!xT^hf?fQYn1#e@0lSc71R*TF#v7o)|C{)g$4Mj4Uoiy!OQIJ?1AjY35e8v%F&9|; zE`EEz*M(fHD6JJAOk($uIfqq*IF3L*cIHkZo4}m@OvceLrxW-nB44Y;=}(+%$1`)G zM|E|41i`qh5B2iciueCm*WYozxk&2k6mL7Z1G!k|%J5NY5TAch&?@x)ytfj>3aI|u zyjSBBlkKs$ zgk!CY-0&&o(Ou`1Q1&;xa>HD1HLu_al`|`Sk0x#M>atsRsw=K+Y{(ZJiCs_JEy1@7TIG@X=sX<^a}Mx ziMC-o{(M+(`pBg|&iQhObxIftdfa`=u=Q6bzj@^;Q-_yyHGWQ8F5SorZ+1K9LK2*-LOS+BC(m*L_5(9nddpob3;~KBnuu84Ip>e z{{BW%kJiD~WE-2Ku>bMU-g)of>LW%dfY;*_Z*0HiWhR$t9PwQgWCSZjgX1M(1!RJC zayOVL0OFLBs5Kh-IQbj)`1L2=Mlb1|T{}kBojVV6gk(q3ZS7`imvZ(({b6G`n1Alg zSr}3!*qRnMZN#yvl*xaCO;)(13dLjDj-k*r9%J?|uVnh4*T`Po!St^q18)EAloyU$ zlXqCnzmoE)kI)GFsg`AohR-aw7f-w_9-CyPm+I$7Kgtj+Ewyp1MU2x$%e`Z&h5kGT za2SCLg%&SoJH4k!79X8op^%^84^gHS&F;zKddEMDl(;)$)iJ}09>lysx&vav8aYpS z-}s&`d12n<%<$F0v4;+1}ys-wU12uB|XQ|r9nPIbpd zYzJ2sc$ZD>2`!i%bEoc$yK{$G>&m0f%hA;4eH{2XKBmN*YwF`(tC^k%EvI2oDNeZa z@H0OLw^()w?JgV%1hc|~ZjCgQd{m!VI1JK7%WsAgC2ykn_H@{PjPf!feQ?6{m3w%@ z?%|@!-9tP0IQq2Kx~=h&N7yDfpg(T(wBgAAVwXHYrF1YGFWF&l9tjkX<|*8T@av#U z>6}9_!BN6v4_d8e;Cw-=*{QuFtn`zTUG$?w=t$>@Iws6EglBj#$dCImS=_38zJyQo zb&qt3EJ$j_>9N)FbJ9@-PJL_7{v+G;0jLmkgoa!GB$`Myh(58S0 za+2-!pQ2mVx{Xoi(Wrhy0T0chtiPW0LT_k1cRTY$_X1dNxgq*TIj={p|9ooxEM{)b zF#7lr(>!k$w3#WE0U+rEzAYRR=g6^xNuC9~H&kwy{G%BUoXTX!M!Q~T#$N}$gW2Yy zmpt*zHI+NSxHrSO%3y-QT~QLDesubM;H3V(pc9_Q?~-N5-08h8XN>q7%jKwLWu=SbI7_5$pjVtE~DF!JsC z4B!buz79fC0eOJ#^{`_07CLJ~-FDFNG19oHe-qWLon=Xd+o^9Xeb*)q%*>H(Dk4?a z52szJ*{0^Wsd;-`YBr9;{1J4S%*FnxqANH6_%Xa9kRW7J0JAhOAv{{Mznu3$ZAciz|4SRPlKlFib>2vw|K|ZuQE_3we_VhbNdHd* zp0lGHCQ%vKucp;9p~Dw^wJ@0zX<)|=i%(e=3ZHO6Tx(~(yStpa zb3Ya%0?tphL^GJ`q-r0Vf9wMXqekiP zMEVXw&JAVkVY1#wf_xRRl0R$SXZaWlZ9;zB3rYYT#8(6B2m$7?oF*jII2DjftXMVP zT!b;!<}q@F?#0~|!ZNVlg@Abp=e?olQ3(AR4~$fkSyeV)`YWmjrp+>DsaG(WeZ|JL zY{I=QlqmUgLreD7gE5;$)h~gq1YS}f_BV`#w4`xVdmhax18!3Vd)vN*d;Ku#pBi$W zO1*Js%j37sR8oGZf;IPJJ`b1A!<;9u&Fy*>tEpWj&yj7sW_y=<`J5nFFVdf-2U01K zH-!j(WUXVHI#9Adl@P)HrrEMZyg|KMa*Zk3P;@3Hz|WG}+R$O#2%<16djvxo3?3sI zJdr3OR2k9DD$$oG5=G`{63c@p5-a)>MMNf_Wfr)$r84AZf8}TViwetH@Rit@hz}E@ zp+2L?=}GOlvt{e87bE?#T6UYy`}izFH6!F~OTBq#*PDz*wxo}2Cuz2=WV6qE25F;IM?H`K|ROk4V;FGN6CJw}{DrNm=@Wm`IN#o*_`&}dU%T~rSogmmmq?XF8$iEb*>kZ$|n zYizO4k?GCH#y!o@#!5EFO3+u+2}ABt#~17iLdlEd`h^Q>xo$);Tb54pP=ZTh#Web# z9K4Tc=cr?r6s1J~%do3_$T^bT`VMuihvu=C=Ssl;khP2WL@MHL0e0wh0Fg$BMfvb_ z0jliz&%^l3w0#S90imA}>qZfX)qPUHN92rBB50HnNdxWG&1sR#FpbbemCcYcr;y^R z&<4mWJ^=EoP#gi|S<+Ky=JdF;aAuI18DcU6C72^n;u8QKmP#KKQnOw-Zm;u)6yL1l z1<`}E*LEc0rPF{IPvJn#paD8ZuS4|OO0|{?T%z>=ebjE*&XHVN-4P0lzi~%L#s7|FLkYJDz)NGsO3kXH+IQRB&5^%gx^{I*0-*?lpk!- zF)jQ$PmX&Tf4LBy#Sf6wDL_N~NK`2ZAjKTXQW`R@f5ipxr8NwfbO9$6b%FC1W7|jV z!e?MH+|inTP@mEQS!?tXoFeexL@%@n?jvR0H3FZvb;ZZ|maGUGf;G#fKUaGjFc1-R zNx#u28ZUT(eBfYl9>JC@r`Z2u&R~2ylmVX zXXW+$aL}p1Q^d-fWLN{w#6-j6jT%f*^~3`OkbzYS0PQI}g7G}Iu8`Se-skf3a2<{0 z%Rc6UPifm}Sfk;36Y!)0REiZjB5jh_imYgopVFbkjcLnG=^v8Z=Q?4Yiu~D_mOK#7 z4SQg;`uiaI8aI}V#VfHAoG$6~d#8US3t~n$+?bXAt}embBCv}{x~A4K7|XQLNnAbP z0is$x4l!T?3WgcW7%6DT+6d+1?l~Wi7kj#4$aN$p3jPYn1?dv-S<%vCoJtTE#a_%2 z8wU&+`!0S}oHXF$nY@jXk-!B-OB5>RacQ)H}0A2dFpez}A^;pj@+U7R{3)|1H>GYhBxy zD4kjJ1*s4PBl&>}A*!gcOWspaMVDBWn<~}E4^{a8fICpE+bRzkz2fA8O&9>xn$S5; zj*ja!5Pm_*;+fl+nmlR|2ZLTlEdt?}_J?7VcDa78(Vq4Xm6>pm)3wnO6WGvs7O9*U015_=I>m3mguQi-xp=ERQ7wRzQe7h z67Xyr8dCUKBEPSc%8q=14%MB3w6B-c=q@h% zxgj;n?l5W>Jd7PzTp2?$sme4l;>?SYlkRo_wxxETm|UnvY7OnM)It}bl0E!DThJ=H z6JUT#jY*82D}=38@HFEJ8W98FM?(J$wTio%Q!LiHFJKL3lp$?0+qsqAE}hJ%I|$X} z1;0gu9FSz4QE~gfs91H)srcJe9MouM8sIb@q*hUPrMv$9G7_jf$=cP`WQZ1AemGZ$ z!l7BL#!PO~Zs9cG^4a&*b2dwa?41apDKr*mLNo_$h zjkDmT2CAI5Iu?3VIn^a2ATx~YT#B+=$i4^l<0f(5M=@fs7DsVT>O9@`Zt-Hem$$6u z$>dM%=1%Vdp-&G>SN*rx9y-nbCi-d;Y@r=A5c-(fpnG5AwOnDrpM~k9;m;yG<;!Z& zS0uTjKeQRV`jhK4d6-F_F3Bh{HNrq_n5kbpRJ_Dhgt<_cCK;bj=?wNo+NX3@ ze%QkqnpX_UQL$MFH2V+#(qa6Z(S0tYTZVimFyg2^1-4leg*gfH&z0Y;n0s ztkDG=okhV49#Ny1PFA^ZBdc@>7`e#Q@W?!_;?XuG>lBW~%NS7#*YIYQE^gwD@~x)f zIVR^aZ9@Zt^367NFEro6T1&b~-ki2plW54Hi3<)dZz@}EzRAo3M7w#5nBuGSt)aU$ z-N6$K{gj{)o!#788Dm(jx_HY*8Yb_OhaJck0qU%a?R|3p>xf+S)yAkT(^=c$*Iv&ED z=m2}QTtE~rPK3In`5n}3wfv2u*4iQsAjmNF$Z#=$TlH6KU9*K}?HSCv^C*{asFbY} zBVxORz=j-I(SCSEoIz|>o!DSLqA;9S!ElCz;bc6s45W}wH4T>+?>kVO0#Omu@Gyyk zDauP+UwjHh*=&+0^yjYQDPPuMl9i&U?eU*~f)K`Y3$@p7F~ovMpFtwu}w3J8)1lbkA({ z2y8%J+nq-K#Ik_GBEo8&@zWOE1a?Tf`Rt~K&7s+;MeW60Jjf--X);OyadmC9Dh3s; z3$-?E=9XR^e+CsYPK4B;;70<1J4;l@Te)!!C2uZJgz=C28>w~Rwa}NVm0|LqXA6$5JIbFxLUi5H zz7p?DP_5P!cPqcD11RpvIdBJ*h{sMIMQF-nHb~WJvzGovQpNEjk>ZQkI@Sl-WS8d? zB^qR|!IHfR=S}Wwh(~j5QR5-!x~CpXbVvMdiq+Oz{wOdz?(DEXB)Z@u=eosw%)$k= z%7ExKjF>ejYcf#*OCAmbED$0H{`D>d!M~j>-viZBiMCjL0SZ@LM{C=6h##J7&<9k* ze%LGH$1el2U>X{8iw}`KNR)0bVsung7Vy_7W4C%Q?UcHWbipvwEQ0AWut6Y>54ovc zxdUi!o(gLzU+SGc@p}m$H*}N3afQD|`s%Kk#SA?x!}Z5H{&>GT9o(CywC*Dxg%nXs zl1)J&_yhXsY|fexZOSA6IbCw#t4VU8w5W1{ACV?}20H{dOx>YwXzvKzYRZ%c3U10p zbwdAH_ApMy-7;@-n?c-il8mY@;{u0uQK(ns+I_q+XonDa5S5t~f&!ov>IP)5y`sr# zSv3?~W642HG7<@AhqnUod6n)kJ_@tBW}pfx#&-;-qQID8;tH8oE3LsD`{($-MA*M6 zs(lu0WaNb(RP=VX2SaV-lgLqW6`c$uT~z*(#X(047@7MDJo+}OfB~@9t@sO1B^%jW zD>7->ZxM(BRCmrJlHT4GJW)|*q|JA{a z22P_t+|D;y8iFl1Uyd3g?ovNvZTw!Gy3CZ}P(DJ&h&b-(!ILbrEdd?t!#k1^lo^%U z)A?csW0ilEv@i&$3`=(Cf)SrR;Gj%p;T#X@8F%rrh5Q2o^J$Cc1}UIZh0_W4zlXT~ z5wh0APf>0Gy^~aGu3$am{-@ky$&~k!FaeMyp-;{+)bi<cpJ|9IsOdHVn+4}Azi4<%8lc4ooe*G36^R$Bx0Ee zG$yv3Ok80CF@))4>{ba85`jXpv+2wOCw@!RRWRDZ_w`0$aF_tK3EYggMNyVCBG$%d(<>L981(4W(X4buvdo zru}VJm;V8OK8t!tZWA3*aiJey9*}|$@h6~z0MhT%%^c%HhUev^r1+K=@dNh?9fGsm ziki2X0L7b#6lg|!i~xc+hD~TA-&Dwf!bEAhgEAmnmLKT|--@KNh`GK*P-ebINYwA^ z(npbkR6x%2ne^ejAWh&Iys6W{RZm30naxVS{|+{q+75Xzk}kZxo&gEr7}_*S6E+yZUFw&as!`^O(+Nfv%7x@%L2z}iZ$ zmy(nlZR#JvkCu~BE+QsgYC~ZU4R3731z!KL)oR%V@czgAVPiGB?pf3{q(l<^Ugf*; zW#i=A;Ns#T$(KVPP3CYK6p3Iabw2rS+Mq{EW?)2~QZ ze?*(XE#1HEU|TrW`^|MGC?6aQNaB49;vo^)hU0vJ+Qj5x4jCn>_jjz<+sKYVt^)VT z1N)OePyJfcxS*!>QfxBC2HS_IJ@j016b}3k$&2SwK6U%7lNx8)sfSdfL^jxmvLxrr zdiTm;KGegD?z<0(&=~y%9n+-1GmpL2@C1}9_@c?e@B;TN1r#z?V600>_e+~vQv+SzeZR8 zpdaOVqxQ=G$=`}T(Z7ECkJQ`v^j>?iT*rx3bF^vS@FXXWJCS^SvwZV8VK($4f1+&b znWIt<^)jHCGkj0?1hjXg)d@w(L#(yaA=Y*T+iEKfL(OK?je20j&P*@o@>Ne^M&55n zjM@-q{7~bUxUpS^FWWuy#iNMiy5*&F-9zdca1k)^ z_$^lR8fuSEykSc?Dx&@(E2R>|OneLWWp(()?XpsD3wTIA+_8_x-6Ok20Y2_rk*#k{ zZo^D?73WB}EA~hi3t_QtbZ2anvmC$dwKJCU%Z4zcJ$0toH7=yG7*+$Z)Wo9XR}o*F z8;)frNAQ1XrC$Mnn6oi=EYRh?keOSOsT=E@bBJ?GY3n5s+c~d)0GSeK+*YH>D%ftd zJVjFKp>F=t$hY~y@~B6CXa{pPdCHt?29M3VUEe3;O$7mh#7RGC{I1}>PLyl5c$liy z#GEZS=N&O^;tk;l4j-S3SHq~GK!Jbd7m%`yVAvuNt69_{3$ohxgcK(eHRsn~h2fB6a7J~MeNCg5GKmY2L&@&qO8!5t|YEV~@>Tav8+hc=w|rOULlzy!hxE?VjT zmacqDyHfT;4?^KQ9d|Z)UpN`PF}LiWn=d7C#?n-SejK(}W};BFO}S!dYYMPn)o6 zxT1+>mIx_^wc-+Pi7bDZ4cWtDnI%HH;f0p7o|cr534Kvgh5QExW8Sjnt)1EuneWWP zF<|2tpxgPf!x5_Jgk773r%oRJFg+mQC2us)n3v5BQkp~}0qeZx%l?cuVIuR#CX&~e z^G6J)K756Fw3cByROq~P5v#7Q#=|vU?0s)YQ!k;#)b0J?OGrVk8z&{NMeu%OXCiac zLV@aNg{p=6fhysA1d(YKz&@wv-CQS0`UG>QlsxvZj5Ghv2EKMdPlqtY$5TF*`N47l z+dZ<4pQ3o}9x-wn04~*~bD#hor2rl{03herc5mk~0QqQzbiHkrj@*CCo*`gXE0}*n zS^=0a8uFRZ7VZ%xVnkrUNaj`rW2m154!&WkR{%6c4YADH4nC}(DRn!&45YQJ%YJZR z6njwY4nNTdkTP}x8aR2?>(cfnFD^hHT_Hu+2tOLj{7iQ+)KzML4cAZkveOjKE;Oj^ zOq(*TjyhfBEQ7*hXYvR$xc^a*>UB~Nz=$>^)LT_0SP;w|hE(~or%?+8rMk%w%Y3hg zpG0O!ul}eydo1%+B2#Jvf8RMq+apCJJfMenf0#;rz0C9c7xG6ri#GcXrs0L8s-tx9cO zN=YKxiUcN++>X;y6-&SUwqLr~(qA|9TLHCb0+yHxgI0b4YZ{FUS$+`;q_HwJ}oU`&u_fN>jtvNK_&&bE#U#v5v%^> zVQ_>slbSou5L%Bc^4;XwsqbSraV4@A&c8%Cri!2bsW$nb9}%RWd(#uJjPl%}$@= zCTq0pb!+xN4^h*DO2Az~GceP2@U~UIoKLaTWJWe#CJW;Oivp<&yN$y25-4*l$ExVC zef^*ZV}UJn`0MKMw_vcF4j$hR{`^y!k<6VtIU!?r_fu+s(@ zqTSEOQw2k8BuU_!oXMj{RYL+=l_kcK;bB=a{Mo%tGc8iL)7tMKHc>y->^_J&^gs)# zXm(~0Nh*8dYZ^qFPp1C4`>%ig-s=D6uJxa!`p;DTjeL6IEIr+=r;wiHeMKa@bx%2N zmeG0r!cL7tRA*obwCrtzCEp5EIh)XKKq>EuvndyIo_9UxwkC=TxKmgvjGI@+ESHV5 z52m_kV54#0csS42;zI?JpR-XCta8JK?7sNz!P&{YG7AyF>NgBT6x9hJjszg6R+12m zlk9cx#*6+Xc=!}8V>6ZBo>=8pQq`2ivgLH8zm*sUvWiQL_Zs5)XzGG5Fq-~+}Kn4y~fc`W5c!f;YoJ;u50&nfz zs_~-F*`}6r^gssG{S0y?Iu~zvwf1TEGBTrVE9}coM~H*>Fiy3>I$l`=vZCiaBd}6#1~= ziSyNt^DMd^LV1nxxo!hk@9PJqym z;YBLE*gWTM-Tf3k!z-*aICEFuO~0R#r+X!Jyk^e-w@Q|KC6}sX;S&UxXH8ZT6krjK z)dzSWNbTfyh}O!hST7PJ1=6w5a(S1S?WqX|m7_hE=qqN_vtcJ-?? zR^@b@=#doas)lbpIj>dC2i91PM{=%3^HUUv-itl0&u=NK_1Okd63c(otO3_Y46CgA zdzct3{&UyIc3R@r-&%T>=r?3>PoOV*TcQe&^fht5JW^AjC0eNNQIVQ@yO6iNm3NFO z9+^%f(_4cu+-uZ5iaDO*shZ(jLuM>sE9iJJ&Uv?Ukj%`IKv*HqdHf)A zxDegti*Vu{j=Xo`MQ#KW&tW=JaMCQRXQ+pj?m}{c--SNeE!t9?#fHF5jSG+y*9b(` z!j14N@S@a_GB{NxgB12=cS9Uh$@WPnyLs@DwM^H{dB9dS)n(6wa~T?%*%9ZpDx7Pp zZru;vlMx8?fr2I)t4m0j>e00@)r(UXPm%X+XY>2INXKAfGMF9AsQt-1FRl z)RH`UKRr0l^x(#Y?nN{&b+XThJ7y*>o*F(F9UnWe8g*2rAGq`RGqOv2mu`I3rxQfH zTx9yZct_4srmlgczqOI|w47R|gf)f!h{JJ6G<8pV%GgZ_`F!>Yldr8Gg?GN?kgV^OPe77aW5z0``~-zHMF52IT2W&xRXB?!6$tB=u=?{Wk#G7x`KB4`|JD zFrWKl5&$*rXu6|~=y%5me0x*+>_0hVasR+n

2m^+BUMsmD$9&Eu9*P$B)i!7%6- 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%0DsRE4*0vH==)r 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 None: ... + def add(self, x: int) -> bool: ... + def any_within(self, x: int, radius: int) -> bool: ... + def find_all_within(self, x: int, radius: int) -> list[int]: ... + def __len__(self) -> int: ... + +class UnionFind: + def __init__(self) -> None: ... + def make_set(self, x: int) -> None: ... + def find(self, x: int) -> int: ... + def union(self, a: int, b: int) -> None: ... + @property + def component_count(self) -> int: ... + +class CoverageTracker: + def __init__(self, radius: int) -> None: ... + def add_hash(self, x: int) -> bool: ... + @property + def coverage_count(self) -> int: ... + @property + def total_unique(self) -> int: ... + def reset(self) -> None: ... diff --git a/src/gamecov/frame_cov.py b/src/gamecov/frame_cov.py index 25f9125..0c13849 100644 --- a/src/gamecov/frame_cov.py +++ b/src/gamecov/frame_cov.py @@ -294,13 +294,14 @@ class RustBKFrameMonitor(FrameMonitor): def __init__(self, radius: int = RADIUS): try: - import gamecov_core # type: ignore[import-untyped] + from gamecov import _gamecov_core except ImportError as exc: raise ImportError( - "gamecov-core is not installed. Install with: pip install gamecov-core" + "gamecov Rust extension not available. " + "Reinstall gamecov from source with a Rust toolchain." ) from exc super().__init__() - self._tracker: gamecov_core.CoverageTracker = gamecov_core.CoverageTracker( + self._tracker: _gamecov_core.CoverageTracker = _gamecov_core.CoverageTracker( radius ) self._exact: set[int] = set() @@ -327,7 +328,7 @@ def coverage_count(self) -> int: def reset(self) -> None: """Reset all monitor state.""" super().reset() - import gamecov_core # type: ignore[import-untyped] + from gamecov import _gamecov_core - self._tracker = gamecov_core.CoverageTracker(self.radius) + self._tracker = _gamecov_core.CoverageTracker(self.radius) self._exact.clear() diff --git a/gamecov-core/src/lib.rs b/src/lib.rs similarity index 98% rename from gamecov-core/src/lib.rs rename to src/lib.rs index 25179de..456f929 100644 --- a/gamecov-core/src/lib.rs +++ b/src/lib.rs @@ -118,6 +118,7 @@ impl CoverageTracker { /// gamecov_core — Rust-accelerated core for gamecov frame coverage monitoring. #[pymodule] +#[pyo3(name = "_gamecov_core")] fn gamecov_core(m: &Bound<'_, PyModule>) -> PyResult<()> { m.add_class::()?; m.add_class::()?; diff --git a/gamecov-core/src/monitor.rs b/src/monitor.rs similarity index 100% rename from gamecov-core/src/monitor.rs rename to src/monitor.rs diff --git a/gamecov-core/src/unionfind.rs b/src/unionfind.rs similarity index 100% rename from gamecov-core/src/unionfind.rs rename to src/unionfind.rs diff --git a/tests/test_rust_frame_monitor.py b/tests/test_rust_frame_monitor.py index 1821285..0e3af24 100644 --- a/tests/test_rust_frame_monitor.py +++ b/tests/test_rust_frame_monitor.py @@ -6,7 +6,7 @@ import pytest from hypothesis import given, settings, strategies as st, HealthCheck -gamecov_core = pytest.importorskip("gamecov_core") +pytest.importorskip("gamecov._gamecov_core") from gamecov import FrameCoverage, BKFrameMonitor from gamecov.frame_cov import RustBKFrameMonitor From 1e8178f962b36636ea96473fcd4da92bc89e3cbd Mon Sep 17 00:00:00 2001 From: Yifeng He Date: Fri, 6 Feb 2026 20:09:57 -0800 Subject: [PATCH 3/9] doc: rust code --- README.md | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 70f58a9..c754e5f 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Two frames are considered duplicates if the Hamming distance between their perce ## Installation -Requires Python >= 3.11. +Requires Python >= 3.11 and a [Rust toolchain](https://rustup.rs/) (for building from source). ### As a package @@ -41,6 +41,8 @@ Or with pip: pip install git+https://github.com/SecurityLab-UCD/gamecov.git ``` +This builds both the Python package and the embedded Rust extension (`gamecov._gamecov_core`) in a single step. + ### For development Clone the repo and sync dependencies: @@ -79,14 +81,13 @@ print(f"Total unique frames: {len(monitor.item_seen)}") print(f"Unique paths: {len(monitor.path_seen)}") ``` -### Rust-accelerated monitor (optional) +### Rust-accelerated monitor -If `gamecov-core` is installed, `RustBKFrameMonitor` provides the same interface -backed by a compiled Rust extension for significantly higher throughput: +`RustBKFrameMonitor` provides the same interface as `BKFrameMonitor`, +backed by an embedded Rust extension for significantly higher throughput: ```python -from gamecov import FrameCoverage -from gamecov.frame_cov import RustBKFrameMonitor +from gamecov import FrameCoverage, RustBKFrameMonitor monitor = RustBKFrameMonitor() # same API as BKFrameMonitor @@ -98,13 +99,6 @@ for recording in recordings: print(f"Coverage components: {monitor.coverage_count}") ``` -Install `gamecov-core` from the sibling crate: - -```bash -cd gamecov-core -maturin develop --release -``` - ### CLI ```bash @@ -116,8 +110,12 @@ uv run python src/main.py --input-mp4-path path/to/video.mp4 --confidence-thresh ### Prerequisites +- Python >= 3.11 +- [Rust toolchain](https://rustup.rs/) (stable) +- [uv](https://docs.astral.sh/uv/) + ```bash -# Install dependencies +# Install dependencies (builds the Rust extension automatically) uv sync # Install pre-commit hooks @@ -127,11 +125,14 @@ uv run pre-commit install ### Running Tests ```bash -# Run all tests in parallel +# Run all Python tests in parallel uv run pytest -n auto # Run with coverage uv run pytest -n auto --cov=gamecov + +# Run Rust unit and property tests +cargo test ``` ### Code Quality @@ -147,3 +148,4 @@ uv run ruff check src/ ### CI GitHub Actions runs four checks on every PR: `pytest`, `mypy`, `ruff`, and `pylint`. +The CI workflow installs the Rust toolchain before building. From bd4e04cc1a8041696d88f53431e30935f717c602 Mon Sep 17 00:00:00 2001 From: Yifeng He Date: Fri, 6 Feb 2026 20:28:53 -0800 Subject: [PATCH 4/9] feat: add pytest-benchmark suite for Python vs Rust monitor comparison --- AGENTS.md | 22 +++++++++ benchmarks/__init__.py | 0 benchmarks/conftest.py | 67 +++++++++++++++++++++++++++ benchmarks/test_bench_monitor.py | 79 ++++++++++++++++++++++++++++++++ pyproject.toml | 6 ++- uv.lock | 24 ++++++++++ 6 files changed, 196 insertions(+), 2 deletions(-) create mode 100644 benchmarks/__init__.py create mode 100644 benchmarks/conftest.py create mode 100644 benchmarks/test_bench_monitor.py diff --git a/AGENTS.md b/AGENTS.md index 0a1c7d5..73be73d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -46,6 +46,9 @@ Future metrics (e.g., audio coverage, state-graph coverage) will follow the same │ ├── test_BK_frame_monitor.py # Differential: FrameMonitor vs BKFrameMonitor │ ├── test_rust_frame_monitor.py # Differential & monotonicity: BKFrameMonitor vs RustBKFrameMonitor │ └── test_monotone_smb.py # Real-world monotonicity on SMB dataset +├── benchmarks/ +│ ├── conftest.py # Session-scoped fixtures (pre-generated FrameCoverage) +│ └── test_bench_monitor.py # Python vs Rust monitor throughput benchmarks ├── assets/ │ ├── videos/ # Small sample MP4s for integration tests │ └── smb/ # Super Smash Bros recordings for stress tests @@ -112,6 +115,7 @@ See [docs/design.md](docs/design.md) for the coverage framework architecture, fr | `mypy` | Static type checking (strict mode, returns plugin) | | `ruff` | Linting and formatting | | `pre-commit` | Pre-commit hook runner | +| `pytest-benchmark` | Performance benchmarking (Python vs Rust) | | `pytest-xdist` | Parallel test execution (`-n auto`) | | `pytest-cov` | Coverage reporting | | `pytest-profiling` | Performance profiling | @@ -138,6 +142,24 @@ Some tests require assets in `assets/videos/` or `assets/smb/` and will skip if - `RADIUS` — Hamming distance threshold (default `5`). - `N_MAX` — Maximum number of recordings to process in monotonicity tests (default `100`). +## Benchmarks + +```bash +# Run benchmarks (disabled by default during normal test runs) +uv run pytest benchmarks/ --benchmark-enable + +# Group output by backend for side-by-side comparison +uv run pytest benchmarks/ --benchmark-enable --benchmark-group-by=param:backend + +# Save results for later comparison +uv run pytest benchmarks/ --benchmark-enable --benchmark-save=baseline +uv run pytest benchmarks/ --benchmark-enable --benchmark-compare=baseline +``` + +Benchmarks live in `benchmarks/` and are excluded from the normal test suite. +They compare `BKFrameMonitor` (Python) vs `RustBKFrameMonitor` (Rust) throughput +at the monitor level (`add_cov`/`is_seen` operations). + ## Development - Before start working, refresh your knowledge from contents in `.agents` first. diff --git a/benchmarks/__init__.py b/benchmarks/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/benchmarks/conftest.py b/benchmarks/conftest.py new file mode 100644 index 0000000..88b1ee7 --- /dev/null +++ b/benchmarks/conftest.py @@ -0,0 +1,67 @@ +"""Shared fixtures for benchmark suite. + +Pre-generates FrameCoverage objects so the benchmark loop only measures +monitor operations (add_cov / is_seen), not video I/O or hashing. +""" + +from __future__ import annotations + +import os +import tempfile +from collections.abc import Generator + +import numpy as np +import pytest + +from gamecov import FrameCoverage +from gamecov.frame import Frame +from gamecov.writer import write_mp4 + +SEED: int = 42 +FRAME_HEIGHT: int = 128 +FRAME_WIDTH: int = 128 +FRAMES_PER_RECORDING: int = 20 + + +def _generate_coverages( + n_recordings: int, + seed: int = SEED, +) -> Generator[list[FrameCoverage], None, None]: + """Generate n_recordings FrameCoverage objects from deterministic random frames.""" + rng = np.random.default_rng(seed) + coverages: list[FrameCoverage] = [] + temp_files: list[str] = [] + + for _ in range(n_recordings): + frames = [ + Frame.fromarray( + rng.integers( + 0, 256, size=(FRAME_HEIGHT, FRAME_WIDTH, 3), dtype=np.uint8 + ) + ) + for _ in range(FRAMES_PER_RECORDING) + ] + with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as tmp: + write_mp4(frames, tmp.name) + temp_files.append(tmp.name) + coverages.append(FrameCoverage(tmp.name)) + + yield coverages + + for f in temp_files: + os.remove(f) + + +@pytest.fixture(scope="session") +def coverages_10() -> Generator[list[FrameCoverage], None, None]: + yield from _generate_coverages(10) + + +@pytest.fixture(scope="session") +def coverages_25() -> Generator[list[FrameCoverage], None, None]: + yield from _generate_coverages(25) + + +@pytest.fixture(scope="session") +def coverages_50() -> Generator[list[FrameCoverage], None, None]: + yield from _generate_coverages(50) diff --git a/benchmarks/test_bench_monitor.py b/benchmarks/test_bench_monitor.py new file mode 100644 index 0000000..4a94878 --- /dev/null +++ b/benchmarks/test_bench_monitor.py @@ -0,0 +1,79 @@ +"""Benchmark: BKFrameMonitor (Python) vs RustBKFrameMonitor (Rust). + +Measures add_cov throughput at the monitor level. + +Run with: + uv run pytest benchmarks/ --benchmark-enable + uv run pytest benchmarks/ --benchmark-enable --benchmark-group-by=param:backend +""" + +from __future__ import annotations + +from typing import Callable, Union + +import pytest +from pytest_benchmark.fixture import BenchmarkFixture + +from gamecov import BKFrameMonitor, FrameCoverage +from gamecov.frame_cov import RustBKFrameMonitor + +MonitorFactory = Callable[[], Union[BKFrameMonitor, RustBKFrameMonitor]] + + +def _run_monitor( + factory: MonitorFactory, + coverages: list[FrameCoverage], +) -> int: + """Feed all coverages into a fresh monitor and return coverage_count.""" + monitor = factory() + for cov in coverages: + if not monitor.is_seen(cov): + monitor.add_cov(cov) + return monitor.coverage_count + + +@pytest.mark.parametrize( + "backend", + [ + pytest.param("python", id="python"), + pytest.param("rust", id="rust"), + ], +) +class TestMonitorBenchmark: + """Parametrized benchmark comparing Python and Rust backends.""" + + @staticmethod + def _factory(backend: str) -> MonitorFactory: + if backend == "python": + return BKFrameMonitor + return RustBKFrameMonitor + + def test_add_cov_10( + self, + benchmark: BenchmarkFixture, + backend: str, + coverages_10: list[FrameCoverage], + ) -> None: + """Benchmark add_cov with 10 recordings.""" + result = benchmark(_run_monitor, self._factory(backend), coverages_10) + assert result > 0 + + def test_add_cov_25( + self, + benchmark: BenchmarkFixture, + backend: str, + coverages_25: list[FrameCoverage], + ) -> None: + """Benchmark add_cov with 25 recordings.""" + result = benchmark(_run_monitor, self._factory(backend), coverages_25) + assert result > 0 + + def test_add_cov_50( + self, + benchmark: BenchmarkFixture, + backend: str, + coverages_50: list[FrameCoverage], + ) -> None: + """Benchmark add_cov with 50 recordings.""" + result = benchmark(_run_monitor, self._factory(backend), coverages_50) + assert result > 0 diff --git a/pyproject.toml b/pyproject.toml index 2796384..e049c5f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -72,13 +72,15 @@ warn_unreachable = true warn_unused_ignores = false plugins = ["returns.contrib.mypy.returns_plugin"] -# [tool.pytest.ini_options] -# pytest_plugins = ['pytest_profiling'] +[tool.pytest.ini_options] +testpaths = ["tests"] +addopts = "--benchmark-disable" [dependency-groups] dev = [ "mypy>=1.15.0", "pre-commit>=4.5.1", + "pytest-benchmark>=5.1.0", "pytest-cov>=6.2.1", "pytest-profiling>=1.8.1", "pytest-xdist>=3.8.0", diff --git a/uv.lock b/uv.lock index 2fb0220..b82d9bf 100644 --- a/uv.lock +++ b/uv.lock @@ -228,6 +228,7 @@ dependencies = [ dev = [ { name = "mypy" }, { name = "pre-commit" }, + { name = "pytest-benchmark" }, { name = "pytest-cov" }, { name = "pytest-profiling" }, { name = "pytest-xdist" }, @@ -256,6 +257,7 @@ requires-dist = [ dev = [ { name = "mypy", specifier = ">=1.15.0" }, { name = "pre-commit", specifier = ">=4.5.1" }, + { name = "pytest-benchmark", specifier = ">=5.1.0" }, { name = "pytest-cov", specifier = ">=6.2.1" }, { name = "pytest-profiling", specifier = ">=1.8.1" }, { name = "pytest-xdist", specifier = ">=3.8.0" }, @@ -689,6 +691,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/50/1b/6921afe68c74868b4c9fa424dad3be35b095e16687989ebbb50ce4fceb7c/psutil-7.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:4cf3d4eb1aa9b348dec30105c55cd9b7d4629285735a102beb4441e38db90553", size = 244885 }, ] +[[package]] +name = "py-cpuinfo" +version = "9.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/37/a8/d832f7293ebb21690860d2e01d8115e5ff6f2ae8bbdc953f0eb0fa4bd2c7/py-cpuinfo-9.0.0.tar.gz", hash = "sha256:3cdbbf3fac90dc6f118bfd64384f309edeadd902d7c8fb17f02ffa1fc3f49690", size = 104716 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/a9/023730ba63db1e494a271cb018dcd361bd2c917ba7004c3e49d5daf795a2/py_cpuinfo-9.0.0-py3-none-any.whl", hash = "sha256:859625bc251f64e21f077d099d4162689c762b5d6a4c3c97553d56241c9674d5", size = 22335 }, +] + [[package]] name = "pygments" version = "2.19.2" @@ -714,6 +725,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474 }, ] +[[package]] +name = "pytest-benchmark" +version = "5.2.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "py-cpuinfo" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/24/34/9f732b76456d64faffbef6232f1f9dbec7a7c4999ff46282fa418bd1af66/pytest_benchmark-5.2.3.tar.gz", hash = "sha256:deb7317998a23c650fd4ff76e1230066a76cb45dcece0aca5607143c619e7779", size = 341340 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/33/29/e756e715a48959f1c0045342088d7ca9762a2f509b945f362a316e9412b7/pytest_benchmark-5.2.3-py3-none-any.whl", hash = "sha256:bc839726ad20e99aaa0d11a127445457b4219bdb9e80a1afc4b51da7f96b0803", size = 45255 }, +] + [[package]] name = "pytest-cov" version = "6.2.1" From 8257a29c93edc5631f577014c2e3b8b35e0cca6d Mon Sep 17 00:00:00 2001 From: Yifeng He Date: Fri, 6 Feb 2026 20:42:26 -0800 Subject: [PATCH 5/9] add python v.s. rust performance benchmark --- README.md | 10 ++++++++++ benchmarks/conftest.py | 13 +++++++++---- benchmarks/test_bench_monitor.py | 26 ++++++++++++++++++-------- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index c754e5f..a6aa71b 100644 --- a/README.md +++ b/README.md @@ -135,6 +135,16 @@ uv run pytest -n auto --cov=gamecov cargo test ``` +### Benchmarks + +```bash +# Compare Python vs Rust monitor throughput +uv run pytest benchmarks/ --benchmark-enable + +# Side-by-side grouped by backend +uv run pytest benchmarks/ --benchmark-enable --benchmark-group-by=param:backend +``` + ### Code Quality ```bash diff --git a/benchmarks/conftest.py b/benchmarks/conftest.py index 88b1ee7..cfada86 100644 --- a/benchmarks/conftest.py +++ b/benchmarks/conftest.py @@ -58,10 +58,15 @@ def coverages_10() -> Generator[list[FrameCoverage], None, None]: @pytest.fixture(scope="session") -def coverages_25() -> Generator[list[FrameCoverage], None, None]: - yield from _generate_coverages(25) +def coverages_50() -> Generator[list[FrameCoverage], None, None]: + yield from _generate_coverages(50) @pytest.fixture(scope="session") -def coverages_50() -> Generator[list[FrameCoverage], None, None]: - yield from _generate_coverages(50) +def coverages_200() -> Generator[list[FrameCoverage], None, None]: + yield from _generate_coverages(200) + + +@pytest.fixture(scope="session") +def coverages_500() -> Generator[list[FrameCoverage], None, None]: + yield from _generate_coverages(500) diff --git a/benchmarks/test_bench_monitor.py b/benchmarks/test_bench_monitor.py index 4a94878..b40696b 100644 --- a/benchmarks/test_bench_monitor.py +++ b/benchmarks/test_bench_monitor.py @@ -58,22 +58,32 @@ def test_add_cov_10( result = benchmark(_run_monitor, self._factory(backend), coverages_10) assert result > 0 - def test_add_cov_25( + def test_add_cov_50( self, benchmark: BenchmarkFixture, backend: str, - coverages_25: list[FrameCoverage], + coverages_50: list[FrameCoverage], ) -> None: - """Benchmark add_cov with 25 recordings.""" - result = benchmark(_run_monitor, self._factory(backend), coverages_25) + """Benchmark add_cov with 50 recordings.""" + result = benchmark(_run_monitor, self._factory(backend), coverages_50) assert result > 0 - def test_add_cov_50( + def test_add_cov_200( self, benchmark: BenchmarkFixture, backend: str, - coverages_50: list[FrameCoverage], + coverages_200: list[FrameCoverage], ) -> None: - """Benchmark add_cov with 50 recordings.""" - result = benchmark(_run_monitor, self._factory(backend), coverages_50) + """Benchmark add_cov with 200 recordings.""" + result = benchmark(_run_monitor, self._factory(backend), coverages_200) + assert result > 0 + + def test_add_cov_500( + self, + benchmark: BenchmarkFixture, + backend: str, + coverages_500: list[FrameCoverage], + ) -> None: + """Benchmark add_cov with 500 recordings.""" + result = benchmark(_run_monitor, self._factory(backend), coverages_500) assert result > 0 From b326507c0c4cf75724804c2bf6c2bc32c3732a2e Mon Sep 17 00:00:00 2001 From: Yifeng He Date: Fri, 6 Feb 2026 21:15:19 -0800 Subject: [PATCH 6/9] ci: add Rust fmt, clippy, and test to CI and pre-commit hooks --- .github/workflows/rust.yml | 29 +++++++++++++++++++++++++++++ .pre-commit-config.yaml | 22 ++++++++++++++++++++++ rustfmt.toml | 4 ++++ src/bktree.rs | 6 ++++++ src/unionfind.rs | 6 ++++++ 5 files changed, 67 insertions(+) create mode 100644 .github/workflows/rust.yml create mode 100644 rustfmt.toml diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml new file mode 100644 index 0000000..ca356d0 --- /dev/null +++ b/.github/workflows/rust.yml @@ -0,0 +1,29 @@ +name: Rust CI + +on: [pull_request] + +jobs: + rust-ci: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt, clippy + + - name: Rust cache + uses: Swatinem/rust-cache@v2 + + - name: Check formatting + run: cargo fmt --all -- --check + + - name: Clippy + run: cargo clippy --all-targets --all-features -- -D warnings + + - name: Tests + run: cargo test --all-features diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b63d5d9..595f951 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,3 +19,25 @@ repos: - id: ruff args: [--fix] - id: ruff-format + + - repo: local + hooks: + - id: cargo-fmt + name: cargo fmt + entry: cargo fmt --all + language: system + types: [rust] + pass_filenames: false + - id: cargo-clippy + name: cargo clippy + entry: cargo clippy --all-targets --all-features -- -D warnings + language: system + types: [rust] + pass_filenames: false + - id: cargo-test + name: cargo test + entry: cargo test --all-features + language: system + types: [rust] + pass_filenames: false + stages: [pre-push] diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..4d07e88 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,4 @@ +max_width = 120 +fn_params_layout = "Tall" +reorder_imports = true +use_field_init_shorthand = true diff --git a/src/bktree.rs b/src/bktree.rs index a9bb4cd..510aeab 100644 --- a/src/bktree.rs +++ b/src/bktree.rs @@ -18,6 +18,12 @@ pub fn hamming(a: u64, b: u64) -> u32 { (a ^ b).count_ones() } +impl Default for BKTreeInner { + fn default() -> Self { + Self::new() + } +} + impl BKTreeInner { pub fn new() -> Self { Self { nodes: Vec::new() } diff --git a/src/unionfind.rs b/src/unionfind.rs index 7cc605d..321d0be 100644 --- a/src/unionfind.rs +++ b/src/unionfind.rs @@ -13,6 +13,12 @@ pub struct UnionFindInner { count: usize, } +impl Default for UnionFindInner { + fn default() -> Self { + Self::new() + } +} + impl UnionFindInner { pub fn new() -> Self { Self { From 8299e99b0c6748374f0f7c20db9d7872c3a5f3ec Mon Sep 17 00:00:00 2001 From: Yifeng He Date: Fri, 6 Feb 2026 21:23:07 -0800 Subject: [PATCH 7/9] doc: update for rust dev --- AGENTS.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 73be73d..1cf33c5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -54,8 +54,9 @@ Future metrics (e.g., audio coverage, state-graph coverage) will follow the same │ └── smb/ # Super Smash Bros recordings for stress tests ├── docs/ │ └── design.md # Architecture and design documentation -├── .pre-commit-config.yaml # Pre-commit hooks -├── .github/workflows/ # CI: pytest, mypy, ruff, pylint +├── rustfmt.toml # Rust formatting config +├── .pre-commit-config.yaml # Pre-commit hooks (Python + Rust) +├── .github/workflows/ # CI: pytest, mypy, ruff, pylint, rust (fmt/clippy/test) ├── AGENTS.md # This file └── README.md # Human-facing documentation ``` @@ -68,6 +69,8 @@ replacements for the BK-tree, union-find, and coverage tracker. Build the package (includes Rust compilation): `uv sync` or `pip install .` Run Rust tests independently: `cargo test` +Check Rust formatting: `cargo fmt --all -- --check` +Run Rust linting: `cargo clippy --all-targets --all-features -- -D warnings` ## Design @@ -171,7 +174,8 @@ at the monitor level (`add_cov`/`is_seen` operations). Local variables' types are optional as long as the types can be easily inferred. - Use f-strings for string interpolation. - Use `TypedDict`, `Literal`, `Protocol`, and `TypeVar` from `typing` module when appropriate. -- Always run `mypy`, and `ruff` to ensure code quality after updating code in `src/`. +- Always run `mypy` and `ruff` to ensure code quality after updating Python code in `src/`. +- Always run `cargo fmt`, `cargo clippy -- -D warnings`, and `cargo test` after updating Rust code in `src/`. - Never commit changes or create PRs. Suggest commit messages to the human developer for review after your changes to the codebase. - Always use `typer` to handle CLI commands. From 0173cdec3c3e57120a88ed4251ba32538a9b8524 Mon Sep 17 00:00:00 2001 From: Yifeng He Date: Fri, 6 Feb 2026 21:27:40 -0800 Subject: [PATCH 8/9] doc: add Rust vs Python benchmark results to README --- README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/README.md b/README.md index a6aa71b..c1f975d 100644 --- a/README.md +++ b/README.md @@ -159,3 +159,28 @@ uv run ruff check src/ GitHub Actions runs four checks on every PR: `pytest`, `mypy`, `ruff`, and `pylint`. The CI workflow installs the Rust toolchain before building. + +## Performance: Rust vs Python Backend + +The embedded Rust extension (`RustBKFrameMonitor`) provides significant speedups +over the pure-Python `BKFrameMonitor` for the core `add_cov`/`is_seen` monitor operations. +The advantage grows with workload size as the BK-tree and union-find structures scale. + +Benchmark results (mean time per iteration, lower is better): + +| Recordings | Python (ms) | Rust (ms) | Speedup | +| ---------- | ----------- | --------- | ------- | +| 10 | 4.04 | 2.31 | 1.75x | +| 50 | 42.95 | 15.00 | 2.86x | +| 200 | 424.36 | 111.03 | 3.82x | +| 500 | 2,349.74 | 549.40 | 4.28x | + +The Rust backend achieves **1.8x -- 4.3x** speedup, +with larger gains at higher workloads where BK-tree traversal and union-find operations dominate. +Each recording contains randomly generated `FrameCoverage` objects with perceptual hashes. + +Reproduce these results with: + +```bash +uv run pytest benchmarks/ --benchmark-enable --benchmark-group-by=param:backend +``` From d2d26d6edaea7147d218f8673743e83eecdd59ea Mon Sep 17 00:00:00 2001 From: Yifeng He Date: Fri, 6 Feb 2026 21:35:51 -0800 Subject: [PATCH 9/9] chore: bump version to 0.2.0 --- Cargo.toml | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4a03770..cbd1a7b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gamecov-core" -version = "0.1.0" +version = "0.2.0" edition = "2021" description = "Rust-accelerated core for gamecov frame coverage monitoring" diff --git a/pyproject.toml b/pyproject.toml index e049c5f..64ea7d0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "gamecov" -version = "0.1.6" +version = "0.2.0" description = "Coverage monitoring for directed game play-testing (Game-Fuzz)" readme = "README.md" authors = [{ name = "Yifeng He", email = "yfhe.prsn@gmail.com" }]