This starts adding flow tracking stats, without exposing them anywhere
yet. Flow structs are created as needed and metrics are bumped, and
benchmarks show no change in performance.
Updates #3560
Change-Id: I376187a8452ec92d49effcbf48a6fb4f4d787b8a
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Fixestailscale/corp#14747
Signed-off-by: David Anderson <danderson@tailscale.com>
Co-authored-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Signed-off-by: David Anderson <danderson@tailscale.com>
For use in tsweb debug handlers, so that we can easily inspect cache
and limiter state when troubleshooting.
Updates tailscale/corp#3601
Signed-off-by: David Anderson <danderson@tailscale.com>
pre-generics container/list is quite unpleasant to use, and the pointer
manipulation operations for an LRU are simple enough to implement directly
now that we have generic types.
With this change, the LRU uses a ring (aka circularly linked list) rather
than a simple doubly-linked list as its internals, because the ring makes
list manipulation edge cases more regular: the only remaining edge case is
the transition between 0 and 1 elements, rather than also having to deal
specially with manipulating the first and last members of the list.
While the primary purpose was improved readability of the code, as it
turns out removing the indirection through an interface box also speeds
up the LRU:
│ before.txt │ after.txt │
│ sec/op │ sec/op vs base │
LRU-32 67.05n ± 2% 59.73n ± 2% -10.90% (p=0.000 n=20)
│ before.txt │ after.txt │
│ B/op │ B/op vs base │
LRU-32 21.00 ± 0% 10.00 ± 0% -52.38% (p=0.000 n=20)
│ before.txt │ after.txt │
│ allocs/op │ allocs/op vs base │
LRU-32 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=20) ¹
Updates #cleanup
Signed-off-by: David Anderson <danderson@tailscale.com>
The benchmark simulates an LRU being queries with uniformly random
inputs, in a set that's too large for the LRU, which should stress
the eviction codepath.
Signed-off-by: David Anderson <danderson@tailscale.com>