chadtmiller.com/knotless
git that lives in your Atmosphere account
1
10
Profiles answer at once: badges read pulls by index, and down is a table
Merged Approved
This pull does two things. pulls_where now reads the pulls first and then what is about each by forge_subject, in a UNION ALL, so it no longer joins on an OR. down becomes a keyed table that triggers on takedown, inactive and label keep, refilled when the index opens. A new Index::lapse, run by the ten-minute sweep, puts back labels that have lapsed.
I read the diff and found nothing that must change.
- Triggers: the insert and delete triggers keep
downcorrect.INSERT OR REPLACEontakedownandlabelfires only the insert trigger. That is harmless, because the row stays down, andlapsecovers a replacement that has lapsed. The new test exercises that case. pulls_where: the rewrite returns the same rows. Ordering within a repository doesn't matter to the grouping, which only needs the rows ordered byr.uri.- Checks:
checkpasses.testwas still running when I looked, so the coverage gate and the plan check are not yet confirmed.
Two small things, neither blocking:
- A lapsed label now keeps its subject out of reads for up to one sweep interval.
docs/design/serve.md:492still says labels hold "until they expire". A sentence there would keep the docs true. lapsedrops its error withlet _ =insweep. A failure there would be silent, so a log line would help.
Merged as 87495fc
What changes
A profile's badges read an account's pulls by index. The query behind them (
pulls_where, for the pulls an account opened, commented on, or sent from forks) joined each pull to the records of its repository that were it or about it. ThatORread every record of the repository once for each pull. It is now two statements in aUNION ALL: the pulls, then what is about each byforge_subject, in that order (CROSS JOIN).What is taken down is a table, not a view.
down, which nearly every read filters on (uri NOT IN down), was a temporary view overtakedown,inactiveandlabel. SQLite built the whole list of it for eachNOT IN downof each statement.inactiveholds every account the network said is deactivated, taken down or throttled, 17,248 on prod and growing with all of atproto, none of which wrote anything here.downis now a table with the subject as its key, so eachNOT IN downis a lookup in its index (USING INDEX … FOR IN-OPERATOR):takedown,inactiveandlabelkeep it. A subject leaves only when none of the three keeps it down.labelgains an index onurifor that.label.Index::lapse), which also clears what pages kept of it. Before, a lapsed label was left out of reads at once, but pages kept what they had drawn until something else cleared them.Why
The profile page took about 2 s to answer, and every tab of it pays that, since each loads
getProfile. On prod,getProfilefor chadtmiller.com took 1,425 ms. The newsqllog put 1,014 ms of it in the one statement. An account with no pulls answered in about 40 ms.On a copy of prod's index (1,992 forge records, 462 of them this account's pulls):
badges_ofas a whole: about 1.3 s. With the query fixed, a release build on that copy took 330 ms. 200 ms of that was 28 lookups of a batch's states, each one index search plus buildingdownfor itsNOT IN down.forge, behindgetForgeand others, logged at ~105 ms on prod): 28 ms → 12 ms warm.Making
inactivehold only accounts known here would also shrink the list. It would hide a taken-down account that a later backfill finds, though, and it still grows; a key lookup stays the same at any size.How it was checked
labeltest gains a hide label replaced by one that lapsed: it hides untillapseputs it back.badges_of; that test was not kept.Shortcomings
down, so it should drop some, but finding the rest is its own pull.ORjoin. It was a search by repository for each pull, not a scan, and only a scan or a sort fails it.Changeset: none
🤖 Generated with Claude Code