Skip to content

Decide decay from the ranks read out of the store - #49

Merged
wyne merged 1 commit into
mainfrom
codex/decay-threshold
Sep 6, 2026
Merged

wyne merged 1 commit into
mainfrom
codex/decay-threshold

Conversation

@wyne

@wyne wyne commented Sep 6, 2026

Copy link
Copy Markdown
Owner

Summary

writeFileStore totalled the final slice, so the paths being added and their rank + 1/rank increments counted toward the decay threshold. fasd accumulates count inside its $2 >= 1 block:

$2 >= 1 {
    if($1 in paths) { rank[$1] = $2 + 1 / $2; time[$1] = now }
    else            { rank[$1] = $2;          time[$1] = $3  }
    count += $2                                   # the rank as read, nothing else
}
END {
    if(count > max) for(i in rank) print i "|" 0.9*rank[i] "|" time[i]
    else            for(i in rank) print i "|" rank[i]     "|" time[i]
}

Three things follow from where that line sits, none of which held before:

  • New paths are not counted. They are created in BEGIN and never pass through the body.
  • Increments are not counted. count += $2 uses the value as read, not $2 + 1/$2.
  • Pruned lines contribute nothing. The accumulator is inside the $2 >= 1 guard.

Follow-up to #48, where this surfaced while fixing the batching bug.

Effect

Measured against binaries built from main at 05fd6c7 and this branch:

case main this PR / fasd
high|1999 + -A p1 p2 high|1799.1 p1|0.9 p2|0.9 high|1999 p1|1 p2|1
high|2001 + -A p1 p2 high|1800.9 p1|0.9 p2|0.9 unchanged
high|2000 + -A high high|1800.00045 high|2000.0005

Row 1 is the practical one: a store sitting just under the threshold got aged early simply because two new paths were added in the same operation. Row 3 shows the same effect from an increment alone — 2000 is not over 2000, but 2000.0005 is.

Row 2 confirms genuine decay still fires, so this narrows when aging happens rather than disabling it.

Validation

  • go test ./..., -shuffle=on x3, go vet ./..., gofmt clean
  • 3 new tests, one per rule above, verified against two mutations: restoring the final-slice total fails all 3, and moving the total to before the prune fails the pruned-lines case
  • TestAddPathsAppliesDecayOnceForTheWholeArgumentList from Drop entries whose rank has decayed below 1 #48 still passes, pinning row 2

Touches filestore.go only.

🤖 Generated with Claude Code

writeFileStore totalled the final slice, so the paths being added and
their rank + 1/rank increments counted toward the decay threshold. fasd
accumulates `count += $2` inside its `$2 >= 1` block, summing only the
ranks of the lines it read: new paths are not counted, increments are
not counted, and pruned lines contribute nothing.

The gap shows on a store just under the threshold. With high|1999 and
`-A p1 p2`, fasder reached 2001 and aged everything to 1799.1/0.9/0.9,
where fasd counts 1999 and writes 1999/1/1 untouched.

Total the ranks in AddToStore, after the prune and before any increment,
and pass that to writeFileStore.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@wyne
wyne merged commit 03796a0 into main Sep 6, 2026
1 check passed
@wyne
wyne deleted the codex/decay-threshold branch September 6, 2026 18:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant