import { useState } from "react"; const MONO = "'SF Mono', 'Cascadia Code', 'Fira Code', monospace"; const SANS = "'Segoe UI', system-ui, sans-serif"; const colors = { bg: "#0a0e17", surface: "#111827", surface2: "#1a2332", border: "#1e3a5f", borderHi: "#2563eb", text: "#e2e8f0", textDim: "#64748b", textMuted: "#475569", accent: "#3b82f6", accentDim: "#1e40af", green: "#10b981", greenDim: "#064e3b", amber: "#f59e0b", amberDim: "#78350f", red: "#ef4444", redDim: "#7f1d1d", purple: "#a78bfa", purpleDim: "#4c1d95", cyan: "#22d3ee", cyanDim: "#164e63", orange: "#fb923c", }; const levelMeta = [ { name: "Semi-Major Axis (a)", unit: "km", example: "6,798 km (ISS)", color: colors.accent }, { name: "Inclination (i)", unit: "deg", example: "51.6° (ISS)", color: colors.green }, { name: "RAAN (Ω)", unit: "deg", example: "Right Ascension", color: colors.amber }, { name: "Eccentricity (e)", unit: "", example: "0.0001 (ISS)", color: colors.purple }, { name: "Arg. Perigee (ω)", unit: "deg", example: "Argument of Perigee", color: colors.orange }, ]; const ByteBlock = ({ label, bytes, color, detail, dimColor }) => (
{label}
{bytes}B
{detail &&
{detail}
}
); const StructField = ({ type, name, size, comment, color }) => (
{type} {name} {size}B {comment}
); const SectionHeader = ({ children, color = colors.accent }) => (
{children}
); const Badge = ({ children, color }) => ( {children} ); const PageDiagram = ({ type }) => { const isInternal = type === "internal"; const isLeaf = type === "leaf"; const isCompressed = type === "compressed"; const headerColor = colors.cyan; const entryColor = isInternal ? colors.accent : isLeaf ? colors.green : colors.purple; const entryLabel = isInternal ? "KTrieChildEntry" : isLeaf ? "KTrieLeafEntry" : "CompressedPath + Entries"; const entrySize = isInternal ? 24 : isLeaf ? 68 : "variable"; const capacity = isInternal ? "~337 children" : isLeaf ? "~119 TLEs" : "path + leaves"; return (
{isInternal ? "Internal Node" : isLeaf ? "Leaf Node" : "Compressed Node"}
{capacity}
{/* Page visualization */}
{/* PG Header */}
PageHeaderData 24B
{/* KTrie Node Header */}
KTrieNodeHeader 72B
{/* Entries section */}
{entryLabel} × N {entrySize}B each → {capacity}
{/* Show 3 sample entries */} {[0, 1, 2].map(i => (
{isInternal ? ( <> ) : ( <> )}
))}
{/* Page footer */}
special: free_offset 8,192 bytes total
); }; const TreeViz = () => { const nodeStyle = (color, label, sub, pop) => (
{label}
{sub}
{pop && {pop}}
); const connector = (color = colors.border) => (
); return (
Adaptive Trie Traversal — ISS Query Path
SELECT * FROM satellites WHERE sgp4_passes(tle, observer(43.70, -116.35), now(), '2h') — Eagle, ID
{/* Level 0: Semi-major axis */}
L0: Semi-Major Axis
{nodeStyle(colors.accent, "6,378–6,978", "sub-LEO → LEO", "28,441")} {nodeStyle(colors.textMuted, "6,978–13,000", "MEO-low", "412")} {nodeStyle(colors.textMuted, "13,000–30,000", "MEO-high", "89")} {nodeStyle(colors.textMuted, "30,000–42,200", "GEO region", "1,247")} {nodeStyle(colors.textMuted, "42,200+", "super-GEO", "18")}
{connector(colors.accent)}
✓ ISS at 6,798km → first bin, prune 4 branches
{connector(colors.green)} {/* Level 1: Inclination — adaptive! */}
L1: Inclination (adaptive: 12 bins in LEO vs 3 in GEO)
{nodeStyle(colors.textMuted, "0°–28°", "equatorial", "2,104")} {nodeStyle(colors.textMuted, "28°–45°", "mid-lat", "1,856")} {nodeStyle(colors.green, "45°–55°", "ISS band", "8,912")} {nodeStyle(colors.textMuted, "55°–70°", "GPS-ish", "3,201")} {nodeStyle(colors.textMuted, "70°–82°", "polar-adj", "1,877")} {nodeStyle(colors.textMuted, "82°–99°", "polar/SSO", "9,441")} {nodeStyle(colors.textMuted, "99°+", "retro", "1,050")}
{connector(colors.green)}
✓ 51.6° → ISS band, 8,912 candidates remain
{connector(colors.amber)} {/* Level 2: RAAN */}
L2: RAAN (coarse — changes rapidly due to J2 precession)
{nodeStyle(colors.textMuted, "0°–90°", "Q1", "2,156")} {nodeStyle(colors.amber, "90°–180°", "Q2", "2,304")} {nodeStyle(colors.textMuted, "180°–270°", "Q3", "2,211")} {nodeStyle(colors.textMuted, "270°–360°", "Q4", "2,241")}
{connector(colors.amber)} {/* Leaf level */}
~2,304 leaf entries
→ SGP4 propagate only these TLEs
→ Check elevation from observer
→ Return visible passes
Pruned 92.3% of catalog before propagation
); }; export default function KTrieLayout() { const [activeTab, setActiveTab] = useState("pages"); const tabs = [ { id: "pages", label: "Page Layout" }, { id: "structs", label: "C Structs" }, { id: "tree", label: "Query Traversal" }, { id: "levels", label: "Level Semantics" }, ]; return (
{/* Header */}

KTrie

Keplerian Patricia Trie — PostgreSQL Index AM
Adaptive branching · Fixed level semantics · 8kB page-aligned · Patricia path compression
{/* Tabs */}
{tabs.map(t => ( ))}
{/* Page Layout Tab */} {activeTab === "pages" && (
8kB Page Layouts — Internal vs Leaf
Capacity Math
Page: 8,192B — PG header: 24B — Node header: 72B → 8,096B available
Internal: 8,096 / 24B per child = 337 max children (adaptive: use 4–337 based on density)
Leaf: 8,096 / 68B per entry = 119 max TLEs per page
Split threshold: 85% fill → split along next orbital element dimension
Merge threshold: 25% fill → merge with sibling if combined < 70%
)} {/* C Structs Tab */} {activeTab === "structs" && (
ktrie.h — Core Data Structures
/* Node type enum */
/* Level semantics — fixed regardless of branching */
{levelMeta.map((l, i) => ( ))}
typedef struct KTrieNodeHeader {"{"} /* 72 bytes */
{"}"}
typedef struct KTrieChildEntry {"{"} /* 24 bytes — internal node */
{"}"}
typedef struct KTrieLeafEntry {"{"} /* 68 bytes — leaf node */
{"}"}
)} {/* Query Traversal Tab */} {activeTab === "tree" && } {/* Level Semantics Tab */} {activeTab === "levels" && (
Fixed Level Semantics with Adaptive Fan-Out {levelMeta.map((level, i) => (
Level {i} {level.name}
{level.unit || "dimensionless"}
{i === 0 && ( <> Regime boundaries: sub-LEO (<300km alt), LEO (300–2,000), MEO (2,000–35,000), GEO (35,000–36,000), HEO/beyond
Adaptive range: 5–20 bins typical. LEO subdivides heavily (75% of catalog)
Split strategy: Equal-population splits, not equal-range. 6,378–6,578 might be one bin (sparse), 6,578–6,978 might be 8 bins (dense LEO)
Query predicate: Altitude range directly maps → instant prune )} {i === 1 && ( <> Key clusters: 0° (equatorial), 28.5° (Cape Canaveral), 51.6° (ISS), 55° (GPS), 63.4° (Molniya critical), 97-98° (SSO), 180° (retrograde limit)
Adaptive range: 4–32 bins. Fine-grained near SSO (huge population), coarse near 180°
Note: Inclination is the most stable element — rarely changes except under thrust. Best discriminator after SMA
Special: Flag nodes containing 63.4° ± 0.5° as HAS_RESONANT (Molniya critical inclination) )} {i === 2 && ( <> Range: 0°–360°, wraps around
Caution: RAAN precesses rapidly due to J2 (~0.5–7°/day depending on altitude/inclination)
Adaptive range: 4–8 coarse bins (fine subdivision pointless — RAAN drifts between TLE updates)
Reindex trigger: When mean RAAN drift since last reindex exceeds bin width
Patricia compression: This level frequently compressed away for near-circular orbits )} {i === 3 && ( <> Range: 0.0 (circular) to ~0.95 (extreme HEO)
Distribution: Massively skewed — 90%+ of LEO objects have e < 0.02
Adaptive range: 2–4 bins. Usually just "near-circular" vs "eccentric" vs "highly elliptical"
Patricia compression: Almost always compressed in LEO branches (everything is near-circular)
Query relevance: Critical for pass prediction — eccentric orbits have variable ground speed )} {i === 4 && ( <> Range: 0°–360°
Stability: Precesses due to J2, rate depends on inclination and eccentricity
Adaptive range: 2–6 bins, often compressed away entirely
Patricia compression: Most aggressively compressed level — rarely needed for spatial queries
Primary use: Discriminating within dense clusters (e.g., Starlink shells at same a/i/Ω) )}
))}
Patricia Path Compression
When a subtree has a single child at levels 2–4 (common in LEO), compress the path:
Before: L0(a) → L1(i) → L2(Ω) → L3(e) → L4(ω) → leaf — 5 page reads
After: L0(a) → L1(i) → COMPRESSED[Ω,e,ω stored in header] → leaf — 3 page reads
Savings: 40% fewer I/O ops for typical LEO queries. Decompresses on split when population grows.
)}
); }