mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-05-19 01:25:20 +00:00
bench(#1199): baseline BenchmarkBuildAggregateHopContextPubkeys
Item 3/6. Aggregate path was uncovered; only the per-tx builder had a bench. Fixture: 50-node pool, 5k txs with 6-hop paths and varied sender/observer pubkeys. No assertion threshold (yet) — purpose is a baseline so future regressions surface. Local arm64 baseline: ~72ms/op, 130k allocs at 5k txs.
This commit is contained in:
@@ -43,3 +43,81 @@ func BenchmarkBuildHopContextPubkeys(b *testing.B) {
|
||||
_ = buildHopContextPubkeys(tx, pm)
|
||||
}
|
||||
}
|
||||
|
||||
// BenchmarkBuildAggregateHopContextPubkeys exercises the aggregate context
|
||||
// builder at the hot scale called out by #1197 (subpath/topology bulk
|
||||
// aggregations): ~5k txs sharing a node pool of ~50 prefixes. The aggregate
|
||||
// builder unions per-tx contexts with its own dedupe map; this benchmark
|
||||
// gives us a baseline so a future regression (e.g. accidental O(n²) dedupe)
|
||||
// shows up immediately. No assertion threshold yet — see #1199 item 3.
|
||||
func BenchmarkBuildAggregateHopContextPubkeys(b *testing.B) {
|
||||
const numNodes = 50
|
||||
const numTxs = 5000
|
||||
|
||||
nodes := make([]nodeInfo, 0, numNodes)
|
||||
for i := 0; i < numNodes; i++ {
|
||||
nodes = append(nodes, nodeInfo{
|
||||
PublicKey: fmt.Sprintf("%012x", i*0x101010101),
|
||||
Role: "repeater",
|
||||
Name: fmt.Sprintf("N%d", i),
|
||||
ObservationCount: i * 3,
|
||||
Lat: 37.0 + float64(i)*0.01,
|
||||
Lon: -122.0 - float64(i)*0.01,
|
||||
HasGPS: true,
|
||||
})
|
||||
}
|
||||
pm := buildPrefixMap(nodes)
|
||||
|
||||
txs := make([]*StoreTx, 0, numTxs)
|
||||
for i := 0; i < numTxs; i++ {
|
||||
hops := []string{
|
||||
nodes[(i+1)%numNodes].PublicKey[:6],
|
||||
nodes[(i+3)%numNodes].PublicKey[:6],
|
||||
nodes[(i+5)%numNodes].PublicKey[:6],
|
||||
nodes[(i+7)%numNodes].PublicKey[:6],
|
||||
nodes[(i+9)%numNodes].PublicKey[:6],
|
||||
nodes[(i+11)%numNodes].PublicKey[:6],
|
||||
}
|
||||
pathJSON, _ := json.Marshal(hops)
|
||||
decoded, _ := json.Marshal(map[string]interface{}{
|
||||
"pubKey": fmt.Sprintf("cc%010x", i),
|
||||
})
|
||||
txs = append(txs, &StoreTx{
|
||||
PathJSON: string(pathJSON),
|
||||
DecodedJSON: string(decoded),
|
||||
ObserverID: fmt.Sprintf("dd%010x", i%32),
|
||||
})
|
||||
}
|
||||
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = buildAggregateHopContextPubkeys(txs, pm)
|
||||
}
|
||||
}
|
||||
|
||||
// TestBuildAggregateHopContextPubkeysSmoke is a tiny correctness anchor for
|
||||
// the aggregate helper: union over per-tx contexts, deduped. Lives next to
|
||||
// the benchmark so the file ships an assertion (preflight gate). See #1199
|
||||
// item 3.
|
||||
func TestBuildAggregateHopContextPubkeysSmoke(t *testing.T) {
|
||||
pm := buildPrefixMap([]nodeInfo{{PublicKey: "aabbccddeeff"}})
|
||||
d1, _ := json.Marshal(map[string]interface{}{"pubKey": "1111111111"})
|
||||
d2, _ := json.Marshal(map[string]interface{}{"pubKey": "2222222222"})
|
||||
d3, _ := json.Marshal(map[string]interface{}{"pubKey": "1111111111"}) // dup
|
||||
txs := []*StoreTx{
|
||||
{DecodedJSON: string(d1)},
|
||||
{DecodedJSON: string(d2)},
|
||||
{DecodedJSON: string(d3)},
|
||||
}
|
||||
got := buildAggregateHopContextPubkeys(txs, pm)
|
||||
if len(got) != 2 {
|
||||
t.Fatalf("expected 2 deduped pubkeys, got %d (%v)", len(got), got)
|
||||
}
|
||||
if buildAggregateHopContextPubkeys(nil, pm) != nil {
|
||||
t.Fatalf("nil tx slice must yield nil")
|
||||
}
|
||||
if buildAggregateHopContextPubkeys(txs, nil) != nil {
|
||||
t.Fatalf("nil prefix map must yield nil")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user