forked from Snider/Poindexter
5 KiB
5 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Poindexter is a Go library providing:
- Sorting utilities with custom comparators (ints, strings, floats, generic types)
- KDTree for nearest-neighbor search with multiple distance metrics (Euclidean, Manhattan, Chebyshev, Cosine)
- Helper functions for building normalized/weighted KD points (2D/3D/4D/ND)
- DNS/RDAP tools for domain, IP, and ASN lookups
- Analytics for tree operations and peer selection tracking
Build Commands
# Run all tests
make test
# Run tests with race detector
make race
# Run tests with coverage (writes coverage.out)
make cover
# Run a single test
go test -run TestFunctionName ./...
# Build all packages
make build
# Build with gonum optimized backend
go build -tags=gonum ./...
# Run tests with gonum backend
go test -tags=gonum ./...
# Build WebAssembly module
make wasm-build
# Run benchmarks (writes bench.txt)
make bench
# Run benchmarks for specific backend
make bench-linear # Linear backend
make bench-gonum # Gonum backend (requires -tags=gonum)
# Fuzz testing (default 10s)
make fuzz
make fuzz FUZZTIME=30s
# Lint and static analysis
make lint # requires golangci-lint
make vuln # requires govulncheck
# CI-parity local run
make ci
# Format code
make fmt
# Tidy modules
make tidy
Architecture
Core Components
kdtree.go - Main KDTree implementation:
KDTree[T]generic struct with payload type TKDPoint[T]represents points with ID, Coords, and Value- Query methods:
Nearest(),KNearest(),Radius() - Mutation methods:
Insert(),DeleteByID() - Distance metrics implement
DistanceMetricinterface
Dual Backend System:
kdtree_gonum.go(build taggonum) - Optimized median-split KD-tree with branch-and-bound pruningkdtree_gonum_stub.go(default) - Stubs when gonum tag not set- Linear backend is always available; gonum backend is default when tag is enabled
- Backend selected via
WithBackend()option or defaults based on build tags
kdtree_helpers.go - Point construction utilities:
BuildND(),Build2D(),Build3D(),Build4D()- Build normalized/weighted KD pointsComputeNormStatsND()- Compute per-axis min/max for normalization- Supports axis inversion and per-axis weights
kdtree_analytics.go - Operational metrics:
TreeAnalytics- Query/insert/delete counts, timing statsPeerAnalytics- Per-peer selection tracking for DHT/NAT routing- Distribution statistics and NAT routing metrics
sort.go - Sorting utilities:
- Type-specific sorts:
SortInts(),SortStrings(),SortFloat64s() - Generic sorts:
SortBy(),SortByKey() - Binary search:
BinarySearch(),BinarySearchStrings()
dns_tools.go - DNS and RDAP lookup utilities:
- DNS record types and lookup functions
- RDAP (modern WHOIS) for domains, IPs, ASNs
- External tool link generators
Examples Directory
Runnable examples demonstrating KDTree usage patterns:
examples/dht_ping_1d/- 1D DHT with ping latencyexamples/kdtree_2d_ping_hop/- 2D with ping + hop countexamples/kdtree_3d_ping_hop_geo/- 3D with geographic distanceexamples/kdtree_4d_ping_hop_geo_score/- 4D with trust scoresexamples/dht_helpers/- Convenience wrappers for common DHT schemasexamples/wasm-browser-ts/- TypeScript + Vite browser demo
WebAssembly
WASM module in wasm/main.go exposes KDTree functionality to JavaScript. Build outputs to dist/.
Key Patterns
KDTree Construction
pts := []poindexter.KDPoint[string]{
{ID: "A", Coords: []float64{0, 0}, Value: "alpha"},
}
tree, err := poindexter.NewKDTree(pts,
poindexter.WithMetric(poindexter.EuclideanDistance{}),
poindexter.WithBackend(poindexter.BackendGonum))
Building Normalized Points
pts, err := poindexter.BuildND(items,
func(p Peer) string { return p.ID }, // ID extractor
[]func(Peer) float64{getPing, getHops}, // Feature extractors
[]float64{1.0, 0.5}, // Per-axis weights
[]bool{false, false}) // Inversion flags
Distance Metrics
EuclideanDistance{}- L2 norm (default)ManhattanDistance{}- L1 normChebyshevDistance{}- L-infinity (max) normCosineDistance{}- 1 - cosine similarityWeightedCosineDistance{Weights: []float64{...}}- Weighted cosine
Note: Cosine metrics use linear backend only; L2/L1/L-infinity work with gonum backend.
Testing
Tests are organized by component:
kdtree_test.go,kdtree_nd_test.go- Core KDTree testskdtree_gonum_test.go- Gonum backend specific testskdtree_backend_parity_test.go- Backend equivalence testsfuzz_kdtree_test.go- Fuzz targetsbench_*.go- Benchmark suites
Coverage targets:
make cover # Summary
make coverfunc # Per-function breakdown
make cover-kdtree # kdtree.go only
make coverhtml # HTML report
License
EUPL-1.2 (European Union Public Licence v1.2)