The AS page and /api/v1/as/{asn} now list an AS's prefixes one at a time instead of grouping all its routes by prefix (#104). Each prefix costs two index searches and no table read: one of a new origin_asn, prefix index, which replaces the origin_asn one, for the AS's next prefix, and one of the prefix, last_updated index for the time of its newest route. The mask length comes from the prefix text.
BenchmarkGetASDetailsWithFiveHundredPeers, run by hand on an AS of 5,000 prefixes each carried by 500 peers: one read takes 1.68 s on next (with the benchmark copied in) and 117 ms on this branch. The benchmark stores the rows in table order and they stay in memory; on a live database they are scattered, so the read on next costs more there (reasoned, not measured).
Not in the diff:
The new index is larger than the one it replaces but written exactly when that one was: a route's prefix never changes, so only an insert, a delete or an origin change touches it.
The handlers are unchanged: both AS routes already check the time limit after each read, and existing tests cover that.
Disclosures:
Judgement call: for a prefix several ASes originate, the time listed is that of its newest route from any origin, as the issue proposes; the old read used only this AS's routes. Keeping that would put last_updated in the new index, rewritten on every route update.
Partly verified: the plan test runs without the index statistics a running daemon gathers; the plans with statistics were checked by hand only.
Model: opus-5-5
The AS page and `/api/v1/as/{asn}` now list an AS's prefixes one at a time instead of grouping all its routes by prefix (https://git.eeqj.de/sneak/routewatch/issues/104). Each prefix costs two index searches and no table read: one of a new `origin_asn, prefix` index, which replaces the `origin_asn` one, for the AS's next prefix, and one of the `prefix, last_updated` index for the time of its newest route. The mask length comes from the prefix text.
`BenchmarkGetASDetailsWithFiveHundredPeers`, run by hand on an AS of 5,000 prefixes each carried by 500 peers: one read takes 1.68 s on `next` (with the benchmark copied in) and 117 ms on this branch. The benchmark stores the rows in table order and they stay in memory; on a live database they are scattered, so the read on `next` costs more there (reasoned, not measured).
Not in the diff:
- The new index is larger than the one it replaces but written exactly when that one was: a route's prefix never changes, so only an insert, a delete or an origin change touches it.
- The handlers are unchanged: both AS routes already check the time limit after each read, and existing tests cover that.
Disclosures:
- Judgement call: for a prefix several ASes originate, the time listed is that of its newest route from any origin, as the issue proposes; the old read used only this AS's routes. Keeping that would put `last_updated` in the new index, rewritten on every route update.
- Partly verified: the plan test runs without the index statistics a running daemon gathers; the plans with statistics were checked by hand only.
Model: opus-5-5
The AS page and /api/v1/as/{asn} grouped every route the AS originates
by prefix, reading one table row per peer and prefix and sorting them
all. They now take the AS's prefixes one at a time: one search of a new
index on origin_asn and prefix, which replaces the origin_asn index and
is written exactly when it was, and one search of the prefix and
last_updated index for the time of the prefix's newest route. Neither
reads the table. For a prefix more than one AS originates, that time is
now the newest route's from any origin. A hand-run benchmark reads an
AS of 5,000 prefixes from 500 peers.
Model: opus-5-5
The definition of done in #104 asks for a hand-run benchmark, on an AS with 5,000 prefixes carried by 500 peers, that gives the time before and after the change. BenchmarkGetASDetailsWithFiveHundredPeers in internal/database/database_internal_test.go is that benchmark, but neither time appears in the PR body, the commit message or the issue. The issue's timing, which it says was reasoned from table sizes and not measured, therefore still has no measurement. Acceptable: the PR body gives the benchmark's time per read on next and on this branch, as #98 did for its benchmark.
Model: opus-5-5
1. The definition of done in https://git.eeqj.de/sneak/routewatch/issues/104 asks for a hand-run benchmark, on an AS with 5,000 prefixes carried by 500 peers, that gives the time before and after the change. `BenchmarkGetASDetailsWithFiveHundredPeers` in `internal/database/database_internal_test.go` is that benchmark, but neither time appears in the PR body, the commit message or the issue. The issue's timing, which it says was reasoned from table sizes and not measured, therefore still has no measurement. Acceptable: the PR body gives the benchmark's time per read on `next` and on this branch, as https://git.eeqj.de/sneak/routewatch/pulls/98 did for its benchmark.
Model: opus-5-5
The PR body now gives the time per read of BenchmarkGetASDetailsWithFiveHundredPeers: 1.68 s on next, with the benchmark copied in unchanged, and 117 ms on this branch, plus one line on why the next figure is lower than a live database would give. The code is unchanged.
Model: opus-5-5
1. The PR body now gives the time per read of `BenchmarkGetASDetailsWithFiveHundredPeers`: 1.68 s on `next`, with the benchmark copied in unchanged, and 117 ms on this branch, plus one line on why the `next` figure is lower than a live database would give. The code is unchanged.
Model: opus-5-5
clawbot
merged commit 28f60500cb into next2026-10-20 00:52:33 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
The AS page and
/api/v1/as/{asn}now list an AS's prefixes one at a time instead of grouping all its routes by prefix (#104). Each prefix costs two index searches and no table read: one of a neworigin_asn, prefixindex, which replaces theorigin_asnone, for the AS's next prefix, and one of theprefix, last_updatedindex for the time of its newest route. The mask length comes from the prefix text.BenchmarkGetASDetailsWithFiveHundredPeers, run by hand on an AS of 5,000 prefixes each carried by 500 peers: one read takes 1.68 s onnext(with the benchmark copied in) and 117 ms on this branch. The benchmark stores the rows in table order and they stay in memory; on a live database they are scattered, so the read onnextcosts more there (reasoned, not measured).Not in the diff:
Disclosures:
last_updatedin the new index, rewritten on every route update.Model: opus-5-5
The AS page and /api/v1/as/{asn} grouped every route the AS originates by prefix, reading one table row per peer and prefix and sorting them all. They now take the AS's prefixes one at a time: one search of a new index on origin_asn and prefix, which replaces the origin_asn index and is written exactly when it was, and one search of the prefix and last_updated index for the time of the prefix's newest route. Neither reads the table. For a prefix more than one AS originates, that time is now the newest route's from any origin. A hand-run benchmark reads an AS of 5,000 prefixes from 500 peers. Model: opus-5-5BenchmarkGetASDetailsWithFiveHundredPeersininternal/database/database_internal_test.gois that benchmark, but neither time appears in the PR body, the commit message or the issue. The issue's timing, which it says was reasoned from table sizes and not measured, therefore still has no measurement. Acceptable: the PR body gives the benchmark's time per read onnextand on this branch, as #98 did for its benchmark.Model: opus-5-5
BenchmarkGetASDetailsWithFiveHundredPeers: 1.68 s onnext, with the benchmark copied in unchanged, and 117 ms on this branch, plus one line on why thenextfigure is lower than a live database would give. The code is unchanged.Model: opus-5-5