code wiki / (root) / nx_phash_index.nx

nx_phash_index.nx

buildroot/runtime/nx_phash_index.nx

3924 B84 linesdepth 5pulls 7 transitivereach 5 importersview sourcekind librarytopic phash
docsdependenciesstructsconstsfunctions

about

nx_phash_index.nx -- SUBLINEAR Hamming-metric index (BK-tree) over 64-bit perceptual fingerprints. The reverse-image engine (nx_phash / nx_image_search) ranks by a LINEAR O(N) Hamming scan; that is correct but does not scale to a TinEye-class corpus (10^8..10^10 images). This adds a metric tree that, for the small-radius near-duplicate regime, prunes the candidate set to a SUBLINEAR fraction of N via the triangle inequality -- while returning the EXACT same match set as the linear scan (no recall loss). Integer + deterministic end to end (reuses nx_simhash_hamming = popcount64 of XOR; ZERO new metric math). genealogy_id: burkhard_keller_1973_bk_tree (metric tree) over krawetz_2011 dHash fingerprints WHY a BK-tree: Hamming is a true metric (identity, symmetry, triangle inequality), so for any node on the path |d(q,node) - d(node,child)| <= d(q,child). A radius-r query can therefore skip every child whose edge-distance to its parent lies outside [d-r, d+r]. For clustered corpora (real image collections: near-duplicates + visually-similar groups) this prunes the vast majority of nodes. HONEST: on uniform-random codes at large radius it degrades toward linear -- that regime is the Multi-Index-Hashing rung (Norouzi 2012), the next step up. Layout (caller-owned flat arrays, room for `cap` nodes): fp[i], pay[i], and 65 child slots per node at ch[i*65 + d] (d = Hamming edge distance 0..64 inclusive), each = child node index, or -1 = empty. The caller owns/sizes the arrays so the index composes with any storage tier. license_tier: ORIGINAL

dependencies 1 imports · 2 importers

nx_simhash.nx nx_phash_index.nx nx_imgsearch_engine.nx nx_phash_index_gate.nx

imports: nx_simhash.nx

imported by: nx_imgsearch_engine.nxnx_phash_index_gate.nx

structs

none

consts

24const PI_SLOTS: i64 = 65 // Hamming edge distances 0..64 inclusive

functions

27func pi_init_children(ch: *i64, cap: i64) -> i64
37func pi_insert(fp: *i64, pay: *i64, ch: *i64, n: i64, f: i64, p: i64) -> i64
57func pi_query(fp: *i64, pay: *i64, ch: *i64, n: i64, q: i64, r: i64, out: *i64, out_cap: i64, out_visited: *i64) -> i64