Skip to content

outlet/routing: read from RIB without any locks#2244

Closed
vincentbernat wants to merge 11 commits into
mainfrom
fix/bmp-lockless3
Closed

outlet/routing: read from RIB without any locks#2244
vincentbernat wants to merge 11 commits into
mainfrom
fix/bmp-lockless3

Conversation

@vincentbernat

Copy link
Copy Markdown
Member

This series modifies the BMP provider for the routing component by removing locks.

The intern package is replaced by Go's unique package. This is more efficient than trying to make the intern package thread-safe. Lookup is not impacted by the change, insertion is slower, but routes take less space and flushing is faster (compared to the thread-safe version of the intern package).

bart's persist tables are used to make the RIB thread-safe. This has a huge performance impact on insertion performance (×10), as well as space (×2). Impact on lookup is small (~ 7%).

The next step is to make paths thread-safe by using some kind of sync.Map. The last commit swith to xsync.Map which seems the most efficient for our use case.

At the end, 42% increase in space, 1000% increase in insertion time, 12% lookup. The benchmarks do not test performance of multiple routines updating/looking up the RIB, but the idea is that it should behave better without locks, even if it is slower during updates. So, hopefully, someone could test the result for real.

Fix #2092.

@vincentbernat vincentbernat added the service::outlet Impact the outlet service label Feb 17, 2026
@codecov

codecov Bot commented Feb 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 99.46237% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 84.93%. Comparing base (ed54b28) to head (3a736ab).
⚠️ Report is 28 commits behind head on main.

Files with missing lines Patch % Lines
outlet/routing/provider/bmp/events.go 98.18% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2244      +/-   ##
==========================================
+ Coverage   84.83%   84.93%   +0.09%     
==========================================
  Files         231      229       -2     
  Lines       14029    13909     -120     
==========================================
- Hits        11902    11813      -89     
+ Misses       1421     1397      -24     
+ Partials      706      699       -7     
Flag Coverage Δ
e2e 42.91% <50.67%> (+0.02%) ⬆️
unittests 84.38% <99.46%> (+0.37%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

vincentbernat added a commit that referenced this pull request Feb 17, 2026
When flushing RIBs or receiving a big update, some BMP receivers may not
process the packets in a timely fashion and may be flagged as stuck,
closing the connection. The workaround was to increase the kernel
buffer.

Instead, we separate BMP message processing into a goroutine for I/O
processing and a goroutine for handling received messages, with a
configurable buffered channels between them.

Fix #2092

This may be better than #2244 as performance may be better (but no
benchmark for that).
vincentbernat added a commit that referenced this pull request Feb 17, 2026
When flushing RIBs or receiving a big update, some BMP receivers may not
process the packets in a timely fashion and may be flagged as stuck,
closing the connection. The workaround was to increase the kernel
buffer.

Instead, we separate BMP message processing into a goroutine for I/O
processing and a goroutine for handling received messages, with a
configurable buffered channels between them.

Fix #2092

This may be better than #2244 as performance may be better (but no
benchmark for that).
vincentbernat added a commit that referenced this pull request Feb 18, 2026
When flushing RIBs or receiving a big update, some BMP receivers may not
process the packets in a timely fashion and may be flagged as stuck,
closing the connection. The workaround was to increase the kernel
buffer.

Instead, we separate BMP message processing into a goroutine for I/O
processing and a goroutine for handling received messages, with a
configurable buffered channels between them.

Fix #2092

This may be better than #2244 as performance may be better (but no
benchmark for that).
vincentbernat added a commit that referenced this pull request Feb 20, 2026
When flushing RIBs or receiving a big update, some BMP receivers may not
process the packets in a timely fashion and may be flagged as stuck,
closing the connection. The workaround was to increase the kernel
buffer.

Instead, we separate BMP message processing into a goroutine for I/O
processing and a goroutine for handling received messages, with a
configurable buffered channels between them.

Fix #2092

This may be better than #2244 as performance may be better (but no
benchmark for that).
vincentbernat added a commit that referenced this pull request Feb 21, 2026
When flushing RIBs or receiving a big update, some BMP receivers may not
process the packets in a timely fashion and may be flagged as stuck,
closing the connection. The workaround was to increase the kernel
buffer.

Instead, we separate BMP message processing into a goroutine for I/O
processing and a goroutine for handling received messages, with a
configurable buffered channels between them.

Fix #2092

This may be better than #2244 as performance may be better (but no
benchmark for that).
```
goos: linux
goarch: amd64
pkg: akvorado/outlet/routing/provider/bmp
cpu: Intel(R) Xeon(R) W-2295 CPU @ 3.00GHz
                                       │ bench-step0.txt │          bench-step1.txt           │
                                       │   bytes/route   │ bytes/route  vs base               │
RIBInsertion/1000_routes,_1_peers-36          345.5 ± 4%    533.4 ± 3%  +54.35% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36          360.0 ± 3%    544.9 ± 4%  +51.35% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36          323.5 ± 0%    514.0 ± 0%  +58.89% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36         322.8 ± 0%    516.8 ± 0%  +60.11% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36         317.9 ± 0%    504.7 ± 0%  +58.76% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36         269.8 ± 0%    452.4 ± 0%  +67.68% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36        265.0 ± 0%    450.1 ± 0%  +69.85% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36        251.0 ± 0%    430.6 ± 0%  +71.55% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36        207.1 ± 1%    364.0 ± 0%  +75.76% (p=0.002 n=6)
geomean                                       291.8         475.5       +62.95%

                                       │ bench-step0.txt │           bench-step1.txt           │
                                       │    sec/route    │  sec/route    vs base               │
RIBInsertion/1000_routes,_1_peers-36        1.135µ ±  9%   1.508µ ±  3%  +32.82% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36        1.133µ ±  5%   1.548µ ±  5%  +36.64% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36        1.112µ ±  5%   1.567µ ± 11%  +40.87% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36       1.189µ ±  8%   1.585µ ±  7%  +33.32% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36       1.242µ ± 12%   1.559µ ±  4%  +25.57% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36       1.205µ ±  7%   1.577µ ± 13%  +30.93% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36      1.086µ ±  8%   1.501µ ± 10%  +38.28% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36      1.037µ ±  7%   1.445µ ±  7%  +39.41% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36      1.154µ ±  6%   1.345µ ±  7%  +16.56% (p=0.002 n=6)
geomean                                     1.142µ         1.513µ        +32.50%

                                       │ bench-step0.txt │            bench-step1.txt             │
                                       │    allocs/op    │  allocs/op    vs base                  │
RIBInsertion/1000_routes,_1_peers-36       2.069k ± 0%      4.804k ± 0%  +132.19% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36       3.376k ± 0%      9.066k ± 0%  +168.54% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36       6.900k ± 0%     21.722k ± 0%  +214.81% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36      13.23k ± 0%      43.45k ± 0%  +228.46% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36      27.52k ± 0%      87.29k ± 0%  +217.21% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36      81.70k ± 0%     228.76k ± 0%  +180.01% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36     183.0k ± 0%      475.3k ± 0%  +159.80% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36     354.7k ± 0%      918.2k ± 0%  +158.87% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36     690.1k ± 0%     1947.4k ± 0%  +182.18% (p=0.002 n=6)
RIBLookup/1000_routes,_1_peers-36           0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
RIBLookup/1000_routes,_2_peers-36           0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
RIBLookup/1000_routes,_5_peers-36           0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_1_peers-36          0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_2_peers-36          0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_5_peers-36          0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_1_peers-36         0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_2_peers-36         0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_5_peers-36         0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_1_peers-36        0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_2_peers-36        0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_5_peers-36        0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
RIBFlush/1000_routes,_1_peers-36           2.055k ± 0%      2.055k ± 0%         ~ (p=1.000 n=6) ¹
RIBFlush/1000_routes,_2_peers-36           3.363k ± 0%      3.363k ± 0%         ~ (p=1.000 n=6) ¹
RIBFlush/1000_routes,_5_peers-36           6.834k ± 0%      6.834k ± 0%         ~ (p=1.000 n=6) ¹
RIBFlush/10000_routes,_1_peers-36          13.01k ± 0%      13.01k ± 0%         ~ (p=1.000 n=6) ¹
RIBFlush/10000_routes,_2_peers-36          27.13k ± 0%      27.13k ± 0%         ~ (p=1.000 n=6) ¹
RIBFlush/10000_routes,_5_peers-36          81.30k ± 0%      81.30k ± 0%         ~ (p=1.000 n=6) ¹
RIBFlush/100000_routes,_1_peers-36         181.4k ± 0%      181.4k ± 0%         ~ (p=1.000 n=6) ¹
RIBFlush/100000_routes,_2_peers-36         352.1k ± 0%      352.1k ± 0%         ~ (p=1.000 n=6) ¹
RIBFlush/100000_routes,_5_peers-36         685.2k ± 0%      685.2k ± 0%         ~ (p=1.000 n=6) ¹
RTAHash-36                                  0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
RTAEqual-36                                 0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
geomean                                                ²                  +33.70%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                     │ bench-step0.txt │           bench-step1.txt           │
                                     │     sec/op      │    sec/op     vs base               │
RIBLookup/1000_routes,_1_peers-36         30.39n ±  5%   29.78n ±  3%        ~ (p=0.180 n=6)
RIBLookup/1000_routes,_2_peers-36         30.30n ±  4%   30.51n ±  4%        ~ (p=0.937 n=6)
RIBLookup/1000_routes,_5_peers-36         32.59n ± 21%   31.74n ±  6%        ~ (p=0.195 n=6)
RIBLookup/10000_routes,_1_peers-36        33.58n ± 13%   33.85n ±  8%        ~ (p=0.818 n=6)
RIBLookup/10000_routes,_2_peers-36        37.09n ±  5%   35.28n ± 15%        ~ (p=0.589 n=6)
RIBLookup/10000_routes,_5_peers-36        44.42n ± 12%   40.30n ±  6%   -9.29% (p=0.009 n=6)
RIBLookup/100000_routes,_1_peers-36       88.08n ± 15%   87.19n ± 13%        ~ (p=0.937 n=6)
RIBLookup/100000_routes,_2_peers-36       96.64n ±  6%   95.36n ±  8%        ~ (p=0.589 n=6)
RIBLookup/100000_routes,_5_peers-36      102.50n ±  9%   96.85n ±  2%   -5.51% (p=0.015 n=6)
RIBLookup/1000000_routes,_1_peers-36      159.0n ±  8%   145.9n ± 22%        ~ (p=0.065 n=6)
RIBLookup/1000000_routes,_2_peers-36      157.9n ± 10%   142.4n ± 23%        ~ (p=0.065 n=6)
RIBLookup/1000000_routes,_5_peers-36      181.2n ± 17%   154.5n ±  8%  -14.76% (p=0.004 n=6)
RTAHash-36                                19.30n ±  4%   18.68n ±  3%   -3.21% (p=0.037 n=6)
RTAEqual-36                               8.700n ±  9%   6.985n ±  4%  -19.71% (p=0.002 n=6)
geomean                                   52.17n         49.06n         -5.97%

                                   │ bench-step0.txt │           bench-step1.txt            │
                                   │      ms/op      │     ms/op      vs base               │
RIBFlush/1000_routes,_1_peers-36        578.6m ±  8%    607.2m ±  2%   +4.95% (p=0.015 n=6)
RIBFlush/1000_routes,_2_peers-36        922.9m ±  8%   1023.5m ±  5%  +10.90% (p=0.015 n=6)
RIBFlush/1000_routes,_5_peers-36         1.825 ±  4%     1.949 ±  5%   +6.77% (p=0.002 n=6)
RIBFlush/10000_routes,_1_peers-36        5.619 ±  8%     6.077 ±  6%   +8.15% (p=0.041 n=6)
RIBFlush/10000_routes,_2_peers-36        9.527 ±  4%    10.735 ±  8%  +12.68% (p=0.002 n=6)
RIBFlush/10000_routes,_5_peers-36        20.67 ±  4%     20.75 ± 11%        ~ (p=0.699 n=6)
RIBFlush/100000_routes,_1_peers-36       76.62 ± 12%     69.47 ±  7%   -9.33% (p=0.002 n=6)
RIBFlush/100000_routes,_2_peers-36       114.3 ±  5%     119.2 ±  8%   +4.29% (p=0.026 n=6)
RIBFlush/100000_routes,_5_peers-36       218.8 ± 10%     221.4 ± 11%        ~ (p=0.589 n=6)
geomean                                  10.84           11.30         +4.25%
```
sync.Map does not have generic and therefore, there is a performance
hit. Use a third-party map instead.

```
goos: linux
goarch: amd64
pkg: akvorado/outlet/routing/provider/bmp
cpu: Intel(R) Xeon(R) W-2295 CPU @ 3.00GHz
                                       │ bench-step0.txt │          bench-step3.txt           │
                                       │   bytes/route   │ bytes/route  vs base               │
RIBInsertion/1000_routes,_1_peers-36          345.5 ± 4%    549.4 ± 2%  +58.99% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36          360.0 ± 3%    533.0 ± 2%  +48.04% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36          323.5 ± 0%    486.8 ± 0%  +50.46% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36         322.8 ± 0%    502.9 ± 0%  +55.82% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36         317.9 ± 0%    481.5 ± 0%  +51.46% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36         269.8 ± 0%    394.5 ± 0%  +46.22% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36        265.0 ± 0%    389.2 ± 0%  +46.87% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36        251.0 ± 0%    375.3 ± 0%  +49.52% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36        207.1 ± 1%    307.4 ± 0%  +48.41% (p=0.002 n=6)
geomean                                       291.8         439.5       +50.59%

                                       │ bench-step0.txt │           bench-step3.txt           │
                                       │    sec/route    │  sec/route    vs base               │
RIBInsertion/1000_routes,_1_peers-36        1.135µ ±  9%   1.516µ ±  3%  +33.57% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36        1.133µ ±  5%   1.530µ ±  5%  +35.06% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36        1.112µ ±  5%   1.459µ ±  6%  +31.21% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36       1.189µ ±  8%   1.584µ ±  9%  +33.28% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36       1.242µ ± 12%   1.527µ ±  6%  +22.96% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36       1.205µ ±  7%   1.391µ ±  2%  +15.48% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36      1.086µ ±  8%   1.265µ ±  6%  +16.54% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36      1.037µ ±  7%   1.290µ ± 12%  +24.46% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36      1.154µ ±  6%   1.238µ ±  7%        ~ (p=0.065 n=6)
geomean                                     1.142µ         1.417µ        +24.08%

                                       │ bench-step0.txt │           bench-step3.txt            │
                                       │    allocs/op    │  allocs/op   vs base                 │
RIBInsertion/1000_routes,_1_peers-36       2.069k ± 0%     2.556k ± 0%  +23.54% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36       3.376k ± 0%     3.927k ± 0%  +16.32% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36       6.900k ± 0%     7.547k ± 0%   +9.38% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36      13.23k ± 0%     13.94k ± 0%   +5.40% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36      27.52k ± 0%     28.30k ± 0%   +2.83% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36      81.70k ± 0%     82.54k ± 0%   +1.03% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36     183.0k ± 0%     183.9k ± 0%   +0.50% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36     354.7k ± 0%     355.6k ± 0%   +0.27% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36     690.1k ± 0%     691.1k ± 0%   +0.15% (p=0.002 n=6)
RIBLookup/1000_routes,_1_peers-36           0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
RIBLookup/1000_routes,_2_peers-36           0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
RIBLookup/1000_routes,_5_peers-36           0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_1_peers-36          0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_2_peers-36          0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_5_peers-36          0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_1_peers-36         0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_2_peers-36         0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_5_peers-36         0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_1_peers-36        0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_2_peers-36        0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_5_peers-36        0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
RIBFlush/1000_routes,_1_peers-36           2.055k ± 0%     2.055k ± 0%        ~ (p=1.000 n=6) ¹
RIBFlush/1000_routes,_2_peers-36           3.363k ± 0%     3.364k ± 0%   +0.03% (p=0.002 n=6)
RIBFlush/1000_routes,_5_peers-36           6.834k ± 0%     6.835k ± 0%   +0.01% (p=0.002 n=6)
RIBFlush/10000_routes,_1_peers-36          13.01k ± 0%     13.01k ± 0%   -0.02% (p=0.002 n=6)
RIBFlush/10000_routes,_2_peers-36          27.13k ± 0%     27.13k ± 0%   -0.00% (p=0.002 n=6)
RIBFlush/10000_routes,_5_peers-36          81.30k ± 0%     81.29k ± 0%   -0.00% (p=0.002 n=6)
RIBFlush/100000_routes,_1_peers-36         181.4k ± 0%     181.4k ± 0%   -0.00% (p=0.002 n=6)
RIBFlush/100000_routes,_2_peers-36         352.1k ± 0%     352.1k ± 0%   -0.00% (p=0.002 n=6)
RIBFlush/100000_routes,_5_peers-36         685.2k ± 0%     685.2k ± 0%   -0.00% (p=0.002 n=6)
RTAHash-36                                  0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
RTAEqual-36                                 0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
geomean                                                ²                 +1.74%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                     │ bench-step0.txt │           bench-step3.txt           │
                                     │     sec/op      │    sec/op     vs base               │
RIBLookup/1000_routes,_1_peers-36         30.39n ±  5%   29.55n ±  3%        ~ (p=0.065 n=6)
RIBLookup/1000_routes,_2_peers-36         30.30n ±  4%   29.53n ±  2%   -2.56% (p=0.017 n=6)
RIBLookup/1000_routes,_5_peers-36         32.59n ± 21%   30.55n ±  8%   -6.26% (p=0.015 n=6)
RIBLookup/10000_routes,_1_peers-36        33.58n ± 13%   33.19n ±  5%        ~ (p=0.240 n=6)
RIBLookup/10000_routes,_2_peers-36        37.09n ±  5%   38.77n ± 13%        ~ (p=0.310 n=6)
RIBLookup/10000_routes,_5_peers-36        44.42n ± 12%   41.77n ±  3%   -5.97% (p=0.004 n=6)
RIBLookup/100000_routes,_1_peers-36       88.08n ± 15%   85.46n ±  5%        ~ (p=0.240 n=6)
RIBLookup/100000_routes,_2_peers-36       96.64n ±  6%   96.53n ±  3%        ~ (p=0.818 n=6)
RIBLookup/100000_routes,_5_peers-36      102.50n ±  9%   97.91n ±  6%        ~ (p=0.240 n=6)
RIBLookup/1000000_routes,_1_peers-36      159.0n ±  8%   131.8n ± 13%  -17.05% (p=0.002 n=6)
RIBLookup/1000000_routes,_2_peers-36      157.9n ± 10%   141.5n ±  8%  -10.41% (p=0.009 n=6)
RIBLookup/1000000_routes,_5_peers-36      181.2n ± 17%   156.2n ±  3%  -13.85% (p=0.009 n=6)
RTAHash-36                                19.30n ±  4%   18.80n ±  4%        ~ (p=0.123 n=6)
RTAEqual-36                               8.700n ±  9%   6.913n ±  6%  -20.54% (p=0.002 n=6)
geomean                                   52.17n         48.83n         -6.41%

                                   │ bench-step0.txt │           bench-step3.txt            │
                                   │      ms/op      │     ms/op      vs base               │
RIBFlush/1000_routes,_1_peers-36        578.6m ±  8%    633.0m ± 10%   +9.39% (p=0.002 n=6)
RIBFlush/1000_routes,_2_peers-36        922.9m ±  8%   1083.0m ±  9%  +17.35% (p=0.004 n=6)
RIBFlush/1000_routes,_5_peers-36         1.825 ±  4%     1.917 ±  4%   +5.04% (p=0.002 n=6)
RIBFlush/10000_routes,_1_peers-36        5.619 ±  8%     5.899 ±  7%        ~ (p=0.093 n=6)
RIBFlush/10000_routes,_2_peers-36        9.527 ±  4%    10.405 ±  3%   +9.22% (p=0.002 n=6)
RIBFlush/10000_routes,_5_peers-36        20.67 ±  4%     20.09 ±  6%        ~ (p=0.093 n=6)
RIBFlush/100000_routes,_1_peers-36       76.62 ± 12%     66.96 ± 12%  -12.61% (p=0.009 n=6)
RIBFlush/100000_routes,_2_peers-36       114.3 ±  5%     112.5 ±  8%        ~ (p=0.937 n=6)
RIBFlush/100000_routes,_5_peers-36       218.8 ± 10%     219.8 ±  4%        ~ (p=1.000 n=6)
geomean                                  10.84           11.16         +2.94%
```
This is only a first step to compare performance of both. Next step
would be to use bart's persist tables to remove more locking.

```
goos: linux
goarch: amd64
pkg: akvorado/outlet/routing/provider/bmp
cpu: Intel(R) Xeon(R) W-2295 CPU @ 3.00GHz
                                       │ bench-step0.txt │          bench-step4.txt           │
                                       │   bytes/route   │ bytes/route  vs base               │
RIBInsertion/1000_routes,_1_peers-36          345.5 ± 4%    441.4 ± 8%  +27.74% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36          360.0 ± 3%    455.4 ± 7%  +26.50% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36          323.5 ± 0%    458.5 ± 0%  +41.73% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36         322.8 ± 0%    462.1 ± 0%  +43.18% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36         317.9 ± 0%    449.1 ± 0%  +41.29% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36         269.8 ± 0%    423.1 ± 0%  +56.82% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36        265.0 ± 0%    418.1 ± 0%  +57.79% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36        251.0 ± 0%    395.6 ± 0%  +57.61% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36        207.1 ± 1%    349.4 ± 0%  +68.71% (p=0.002 n=6)
geomean                                       291.8         426.6       +46.18%

                                       │ bench-step0.txt │           bench-step4.txt            │
                                       │    sec/route    │  sec/route    vs base                │
RIBInsertion/1000_routes,_1_peers-36       1135.0n ±  9%   808.4n ±  3%   -28.78% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36       1132.5n ±  5%   854.7n ±  8%   -24.53% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36       1112.0n ±  5%   930.2n ± 10%   -16.34% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36       1.189µ ±  8%   1.752µ ± 11%   +47.37% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36       1.242µ ± 12%   2.576µ ± 14%  +107.45% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36       1.205µ ±  7%   1.959µ ± 35%   +62.60% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36      1.086µ ±  8%   3.137µ ±  9%  +188.99% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36      1.037µ ±  7%   2.904µ ± 11%  +180.13% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36      1.154µ ±  6%   2.557µ ±  8%  +121.67% (p=0.002 n=6)
geomean                                     1.142µ         1.721µ         +50.71%

                                       │ bench-step0.txt │              bench-step4.txt              │
                                       │    allocs/op    │   allocs/op    vs base                    │
RIBInsertion/1000_routes,_1_peers-36       2.069k ± 0%      2.039k ±  1%    -1.45% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36       3.376k ± 0%      3.526k ±  2%    +4.44% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36       6.900k ± 0%      8.043k ±  7%   +16.56% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36      13.23k ± 0%      34.11k ± 19%  +157.83% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36      27.52k ± 0%      93.81k ± 14%  +240.91% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36      81.70k ± 0%     181.67k ± 58%  +122.37% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36     183.0k ± 0%      866.0k ±  0%  +373.33% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36     354.7k ± 0%     1673.8k ±  0%  +371.94% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36     690.1k ± 0%     3688.4k ±  0%  +434.47% (p=0.002 n=6)
RIBLookup/1000_routes,_1_peers-36           0.000 ± 0%       0.000 ±  0%         ~ (p=1.000 n=6) ¹
RIBLookup/1000_routes,_2_peers-36           0.000 ± 0%       0.000 ±  0%         ~ (p=1.000 n=6) ¹
RIBLookup/1000_routes,_5_peers-36           0.000 ± 0%       0.000 ±  0%         ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_1_peers-36          0.000 ± 0%       0.000 ±  0%         ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_2_peers-36          0.000 ± 0%       0.000 ±  0%         ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_5_peers-36          0.000 ± 0%       0.000 ±  0%         ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_1_peers-36         0.000 ± 0%       0.000 ±  0%         ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_2_peers-36         0.000 ± 0%       0.000 ±  0%         ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_5_peers-36         0.000 ± 0%       0.000 ±  0%         ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_1_peers-36        0.000 ± 0%       0.000 ±  0%         ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_2_peers-36        0.000 ± 0%       0.000 ±  0%         ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_5_peers-36        0.000 ± 0%       0.000 ±  0%         ~ (p=1.000 n=6) ¹
RIBFlush/1000_routes,_1_peers-36           2.055k ± 0%      2.042k ±  0%    -0.63% (p=0.002 n=6)
RIBFlush/1000_routes,_2_peers-36           3.363k ± 0%      3.351k ±  0%    -0.36% (p=0.002 n=6)
RIBFlush/1000_routes,_5_peers-36           6.834k ± 0%      6.822k ±  0%    -0.18% (p=0.002 n=6)
RIBFlush/10000_routes,_1_peers-36          13.01k ± 0%      12.99k ±  0%    -0.14% (p=0.002 n=6)
RIBFlush/10000_routes,_2_peers-36          27.13k ± 0%      27.12k ±  0%    -0.06% (p=0.002 n=6)
RIBFlush/10000_routes,_5_peers-36          81.30k ± 0%      81.28k ±  0%    -0.02% (p=0.002 n=6)
RIBFlush/100000_routes,_1_peers-36         181.4k ± 0%      181.4k ±  0%    -0.01% (p=0.002 n=6)
RIBFlush/100000_routes,_2_peers-36         352.1k ± 0%      352.1k ±  0%    -0.01% (p=0.002 n=6)
RIBFlush/100000_routes,_5_peers-36         685.2k ± 0%      685.1k ±  0%    -0.00% (p=0.002 n=6)
RTAHash-36                                  0.000 ± 0%
RTAEqual-36                                 0.000 ± 0%
geomean                                                ²                   +30.23%               ³ ²
¹ all samples are equal
² summaries must be >0 to compute geomean
³ benchmark set differs from baseline; geomeans may not be comparable

                                     │ bench-step0.txt │            bench-step4.txt             │
                                     │     sec/op      │    sec/op      vs base                 │
RIBLookup/1000_routes,_1_peers-36         30.39n ±  5%    30.30n ±  4%        ~ (p=0.818 n=6)
RIBLookup/1000_routes,_2_peers-36         30.30n ±  4%    30.50n ± 23%        ~ (p=0.937 n=6)
RIBLookup/1000_routes,_5_peers-36         32.59n ± 21%    31.24n ±  3%   -4.13% (p=0.009 n=6)
RIBLookup/10000_routes,_1_peers-36        33.58n ± 13%    34.85n ±  5%        ~ (p=0.589 n=6)
RIBLookup/10000_routes,_2_peers-36        37.09n ±  5%    35.53n ±  3%        ~ (p=0.093 n=6)
RIBLookup/10000_routes,_5_peers-36        44.42n ± 12%    39.40n ±  5%  -11.32% (p=0.002 n=6)
RIBLookup/100000_routes,_1_peers-36       88.08n ± 15%    93.84n ±  2%        ~ (p=0.145 n=6)
RIBLookup/100000_routes,_2_peers-36       96.64n ±  6%   103.10n ±  8%   +6.68% (p=0.041 n=6)
RIBLookup/100000_routes,_5_peers-36       102.5n ±  9%    109.2n ±  7%        ~ (p=0.132 n=6)
RIBLookup/1000000_routes,_1_peers-36      159.0n ±  8%    134.2n ± 13%  -15.54% (p=0.002 n=6)
RIBLookup/1000000_routes,_2_peers-36      157.9n ± 10%    146.1n ±  8%   -7.47% (p=0.009 n=6)
RIBLookup/1000000_routes,_5_peers-36      181.2n ± 17%    168.2n ± 12%        ~ (p=0.093 n=6)
RTAHash-36                                19.30n ±  4%
RTAEqual-36                               8.700n ±  9%
geomean                                   52.17n          64.21n         -2.43%               ¹
¹ benchmark set differs from baseline; geomeans may not be comparable

                                   │ bench-step0.txt │          bench-step4.txt           │
                                   │      ms/op      │    ms/op     vs base               │
RIBFlush/1000_routes,_1_peers-36        578.6m ±  8%   360.7m ± 7%  -37.67% (p=0.002 n=6)
RIBFlush/1000_routes,_2_peers-36        922.9m ±  8%   650.1m ± 4%  -29.56% (p=0.002 n=6)
RIBFlush/1000_routes,_5_peers-36         1.825 ±  4%    1.375 ± 7%  -24.71% (p=0.002 n=6)
RIBFlush/10000_routes,_1_peers-36        5.619 ±  8%    2.708 ± 5%  -51.79% (p=0.002 n=6)
RIBFlush/10000_routes,_2_peers-36        9.527 ±  4%    5.314 ± 4%  -44.22% (p=0.002 n=6)
RIBFlush/10000_routes,_5_peers-36        20.67 ±  4%    16.62 ± 8%  -19.59% (p=0.002 n=6)
RIBFlush/100000_routes,_1_peers-36       76.62 ± 12%    44.00 ± 9%  -42.58% (p=0.002 n=6)
RIBFlush/100000_routes,_2_peers-36      114.35 ±  5%    88.05 ± 6%  -23.00% (p=0.002 n=6)
RIBFlush/100000_routes,_5_peers-36       218.8 ± 10%    199.9 ± 7%   -8.62% (p=0.015 n=6)
geomean                                  10.84          7.312       -32.55%
```
Remove global locking when using the RIB tree by using bart's persist
tables and some atomic pointers. Lock is not used anymore when reading.

```
goos: linux
goarch: amd64
pkg: akvorado/outlet/routing/provider/bmp
cpu: Intel(R) Xeon(R) W-2295 CPU @ 3.00GHz
                                       │ bench-step0.txt │          bench-step5.txt           │
                                       │   bytes/route   │ bytes/route  vs base               │
RIBInsertion/1000_routes,_1_peers-36          345.5 ± 4%    437.7 ± 8%  +26.67% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36          360.0 ± 3%    448.4 ± 6%  +24.57% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36          323.5 ± 0%    451.9 ± 0%  +39.68% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36         322.8 ± 0%    450.8 ± 0%  +39.67% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36         317.9 ± 0%    441.8 ± 0%  +38.97% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36         269.8 ± 0%    415.7 ± 0%  +54.08% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36        265.0 ± 0%    408.2 ± 0%  +54.04% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36        251.0 ± 0%    386.7 ± 0%  +54.06% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36        207.1 ± 1%    340.1 ± 0%  +64.22% (p=0.002 n=6)
geomean                                       291.8         418.6       +43.43%

                                       │ bench-step0.txt │            bench-step5.txt             │
                                       │    sec/route    │   sec/route    vs base                 │
RIBInsertion/1000_routes,_1_peers-36        1.135µ ±  9%   10.229µ ±  7%   +801.19% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36        1.133µ ±  5%    9.068µ ±  5%   +700.66% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36        1.112µ ±  5%    9.625µ ±  4%   +765.56% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36       1.189µ ±  8%   11.386µ ±  7%   +858.06% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36       1.242µ ± 12%   12.474µ ± 10%   +904.75% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36       1.205µ ±  7%   15.233µ ±  9%  +1164.67% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36      1.086µ ±  8%   15.196µ ±  6%  +1299.91% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36      1.037µ ±  7%   14.242µ ±  5%  +1274.00% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36      1.154µ ±  6%   11.111µ ±  7%   +863.20% (p=0.002 n=6)
geomean                                     1.142µ          11.86µ         +938.80%

                                       │ bench-step0.txt │              bench-step5.txt               │
                                       │    allocs/op    │   allocs/op    vs base                     │
RIBInsertion/1000_routes,_1_peers-36       2.069k ± 0%      57.416k ± 0%  +2675.08% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36       3.376k ± 0%      76.677k ± 0%  +2171.24% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36       6.900k ± 0%     150.166k ± 1%  +2076.32% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36      13.23k ± 0%      340.04k ± 1%  +2470.38% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36      27.52k ± 0%      902.70k ± 0%  +3180.38% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36      81.70k ± 0%     3486.34k ± 0%  +4167.41% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36     183.0k ± 0%      8419.7k ± 0%  +4502.17% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36     354.7k ± 0%     15275.3k ± 0%  +4206.86% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36     690.1k ± 0%     23215.0k ± 0%  +3263.96% (p=0.002 n=6)
RIBLookup/1000_routes,_1_peers-36           0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000_routes,_2_peers-36           0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000_routes,_5_peers-36           0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_1_peers-36          0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_2_peers-36          0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_5_peers-36          0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_1_peers-36         0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_2_peers-36         0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_5_peers-36         0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_1_peers-36        0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_2_peers-36        0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_5_peers-36        0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBFlush/1000_routes,_1_peers-36          2055.00 ± 0%        32.00 ± 0%    -98.44% (p=0.002 n=6)
RIBFlush/1000_routes,_2_peers-36           3.363k ± 0%       2.046k ± 0%    -39.16% (p=0.002 n=6)
RIBFlush/1000_routes,_5_peers-36           6.834k ± 0%       5.650k ± 0%    -17.33% (p=0.002 n=6)
RIBFlush/10000_routes,_1_peers-36        13011.00 ± 0%        97.00 ± 0%    -99.25% (p=0.002 n=6)
RIBFlush/10000_routes,_2_peers-36          27.13k ± 0%       12.97k ± 0%    -52.18% (p=0.002 n=6)
RIBFlush/10000_routes,_5_peers-36          81.30k ± 0%       62.18k ± 0%    -23.51% (p=0.002 n=6)
RIBFlush/100000_routes,_1_peers-36       181413.0 ± 0%        557.0 ± 0%    -99.69% (p=0.002 n=6)
RIBFlush/100000_routes,_2_peers-36         352.1k ± 0%       181.8k ± 0%    -48.37% (p=0.002 n=6)
RIBFlush/100000_routes,_5_peers-36         685.2k ± 0%       590.5k ± 0%    -13.81% (p=0.002 n=6)
RTAHash-36                                  0.000 ± 0%
RTAEqual-36                                 0.000 ± 0%
geomean                                                ²                    +58.28%               ³ ²
¹ all samples are equal
² summaries must be >0 to compute geomean
³ benchmark set differs from baseline; geomeans may not be comparable

                                     │ bench-step0.txt │            bench-step5.txt             │
                                     │     sec/op      │    sec/op      vs base                 │
RIBLookup/1000_routes,_1_peers-36         30.39n ±  5%    29.45n ±  2%   -3.11% (p=0.009 n=6)
RIBLookup/1000_routes,_2_peers-36         30.30n ±  4%    30.03n ±  6%        ~ (p=0.589 n=6)
RIBLookup/1000_routes,_5_peers-36         32.59n ± 21%    31.57n ±  2%   -3.15% (p=0.041 n=6)
RIBLookup/10000_routes,_1_peers-36        33.58n ± 13%    35.15n ±  4%        ~ (p=0.180 n=6)
RIBLookup/10000_routes,_2_peers-36        37.09n ±  5%    37.06n ±  3%        ~ (p=0.937 n=6)
RIBLookup/10000_routes,_5_peers-36        44.42n ± 12%    43.22n ±  2%        ~ (p=0.310 n=6)
RIBLookup/100000_routes,_1_peers-36       88.08n ± 15%    99.44n ±  3%        ~ (p=0.065 n=6)
RIBLookup/100000_routes,_2_peers-36       96.64n ±  6%   110.70n ±  3%  +14.55% (p=0.002 n=6)
RIBLookup/100000_routes,_5_peers-36       102.5n ±  9%    118.6n ±  1%  +15.71% (p=0.002 n=6)
RIBLookup/1000000_routes,_1_peers-36      159.0n ±  8%    173.3n ± 13%        ~ (p=0.126 n=6)
RIBLookup/1000000_routes,_2_peers-36      157.9n ± 10%    194.1n ± 16%  +22.86% (p=0.009 n=6)
RIBLookup/1000000_routes,_5_peers-36      181.2n ± 17%    233.1n ± 21%  +28.63% (p=0.015 n=6)
RTAHash-36                                19.30n ±  4%
RTAEqual-36                               8.700n ±  9%
geomean                                   52.17n          70.89n         +7.72%               ¹
¹ benchmark set differs from baseline; geomeans may not be comparable

                                   │ bench-step0.txt │           bench-step5.txt            │
                                   │      ms/op      │     ms/op      vs base               │
RIBFlush/1000_routes,_1_peers-36        578.6m ±  8%    515.0m ±  2%  -10.99% (p=0.002 n=6)
RIBFlush/1000_routes,_2_peers-36        922.9m ±  8%   1131.0m ±  3%  +22.55% (p=0.002 n=6)
RIBFlush/1000_routes,_5_peers-36         1.825 ±  4%     2.067 ±  1%  +13.20% (p=0.002 n=6)
RIBFlush/10000_routes,_1_peers-36        5.619 ±  8%     4.821 ±  3%  -14.19% (p=0.002 n=6)
RIBFlush/10000_routes,_2_peers-36        9.527 ±  4%     9.193 ±  4%        ~ (p=0.065 n=6)
RIBFlush/10000_routes,_5_peers-36        20.67 ±  4%     25.31 ± 13%  +22.42% (p=0.002 n=6)
RIBFlush/100000_routes,_1_peers-36       76.62 ± 12%     48.98 ±  5%  -36.08% (p=0.002 n=6)
RIBFlush/100000_routes,_2_peers-36      114.35 ±  5%     99.05 ±  8%  -13.38% (p=0.002 n=6)
RIBFlush/100000_routes,_5_peers-36       218.8 ± 10%     203.6 ±  7%   -6.95% (p=0.015 n=6)
geomean                                  10.84           10.32         -4.76%
```
We only keep a lock when writing (mostly to find a free slot and to
modifies peers). Readers are not using locks.

```
goos: linux
goarch: amd64
pkg: akvorado/outlet/routing/provider/bmp
cpu: Intel(R) Xeon(R) W-2295 CPU @ 3.00GHz
                                       │ bench-step0.txt │           bench-step6.txt           │
                                       │   bytes/route   │ bytes/route  vs base                │
RIBInsertion/1000_routes,_1_peers-36          345.5 ± 4%    531.8 ± 5%   +53.90% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36          360.0 ± 3%    508.1 ± 1%   +41.13% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36          323.5 ± 0%    513.8 ± 0%   +58.81% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36         322.8 ± 0%    516.2 ± 0%   +59.94% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36         317.9 ± 0%    501.1 ± 0%   +57.64% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36         269.8 ± 0%    490.8 ± 0%   +81.89% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36        265.0 ± 0%    490.6 ± 0%   +85.15% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36        251.0 ± 0%    469.9 ± 0%   +87.19% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36        207.1 ± 1%    415.6 ± 0%  +100.68% (p=0.002 n=6)
geomean                                       291.8         492.0        +68.59%

                                       │ bench-step0.txt │            bench-step6.txt             │
                                       │    sec/route    │   sec/route    vs base                 │
RIBInsertion/1000_routes,_1_peers-36        1.135µ ±  9%   10.067µ ±  6%   +786.92% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36        1.133µ ±  5%    9.056µ ±  4%   +699.60% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36        1.112µ ±  5%    9.803µ ±  4%   +781.56% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36       1.189µ ±  8%   11.467µ ± 10%   +864.79% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36       1.242µ ± 12%   12.938µ ± 13%   +942.13% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36       1.205µ ±  7%   15.343µ ±  4%  +1173.81% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36      1.086µ ±  8%   14.382µ ± 11%  +1224.92% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36      1.037µ ±  7%   13.902µ ±  3%  +1241.24% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36      1.154µ ±  6%   11.242µ ±  4%   +874.56% (p=0.002 n=6)
geomean                                     1.142µ          11.84µ         +936.99%

                                       │ bench-step0.txt │              bench-step6.txt               │
                                       │    allocs/op    │   allocs/op    vs base                     │
RIBInsertion/1000_routes,_1_peers-36       2.069k ± 0%      60.337k ± 0%  +2816.24% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36       3.376k ± 0%      82.416k ± 0%  +2341.23% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36       6.900k ± 0%     165.111k ± 0%  +2292.91% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36      13.23k ± 0%      368.91k ± 2%  +2688.63% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36      27.52k ± 0%      959.28k ± 1%  +3386.02% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36      81.70k ± 0%     3651.68k ± 0%  +4369.79% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36     183.0k ± 0%      8724.2k ± 0%  +4668.61% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36     354.7k ± 0%     15883.7k ± 0%  +4378.40% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36     690.1k ± 0%     24711.9k ± 0%  +3480.87% (p=0.002 n=6)
RIBLookup/1000_routes,_1_peers-36           0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000_routes,_2_peers-36           0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000_routes,_5_peers-36           0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_1_peers-36          0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_2_peers-36          0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_5_peers-36          0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_1_peers-36         0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_2_peers-36         0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_5_peers-36         0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_1_peers-36        0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_2_peers-36        0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_5_peers-36        0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBFlush/1000_routes,_1_peers-36          2055.00 ± 0%        32.00 ± 0%    -98.44% (p=0.002 n=6)
RIBFlush/1000_routes,_2_peers-36           3.363k ± 0%       2.049k ± 0%    -39.07% (p=0.002 n=6)
RIBFlush/1000_routes,_5_peers-36           6.834k ± 0%       5.653k ± 0%    -17.28% (p=0.002 n=6)
RIBFlush/10000_routes,_1_peers-36        13011.00 ± 0%        97.00 ± 0%    -99.25% (p=0.002 n=6)
RIBFlush/10000_routes,_2_peers-36          27.13k ± 0%       12.99k ± 0%    -52.14% (p=0.002 n=6)
RIBFlush/10000_routes,_5_peers-36          81.30k ± 0%       62.22k ± 0%    -23.47% (p=0.002 n=6)
RIBFlush/100000_routes,_1_peers-36       181413.0 ± 0%        557.0 ± 0%    -99.69% (p=0.002 n=6)
RIBFlush/100000_routes,_2_peers-36         352.1k ± 0%       182.8k ± 0%    -48.08% (p=0.002 n=6)
RIBFlush/100000_routes,_5_peers-36         685.2k ± 0%       594.4k ± 0%    -13.24% (p=0.002 n=6)
RTAHash-36                                  0.000 ± 0%
RTAEqual-36                                 0.000 ± 0%
geomean                                                ²                    +61.25%               ³ ²
¹ all samples are equal
² summaries must be >0 to compute geomean
³ benchmark set differs from baseline; geomeans may not be comparable

                                     │ bench-step0.txt │            bench-step6.txt             │
                                     │     sec/op      │    sec/op      vs base                 │
RIBLookup/1000_routes,_1_peers-36         30.39n ±  5%    31.07n ±  7%        ~ (p=0.240 n=6)
RIBLookup/1000_routes,_2_peers-36         30.30n ±  4%    30.91n ±  3%        ~ (p=0.180 n=6)
RIBLookup/1000_routes,_5_peers-36         32.59n ± 21%    32.56n ±  5%        ~ (p=0.937 n=6)
RIBLookup/10000_routes,_1_peers-36        33.58n ± 13%    34.82n ±  4%        ~ (p=0.310 n=6)
RIBLookup/10000_routes,_2_peers-36        37.09n ±  5%    37.34n ±  2%        ~ (p=0.818 n=6)
RIBLookup/10000_routes,_5_peers-36        44.42n ± 12%    44.30n ±  4%        ~ (p=1.000 n=6)
RIBLookup/100000_routes,_1_peers-36       88.08n ± 15%    99.11n ±  7%        ~ (p=0.093 n=6)
RIBLookup/100000_routes,_2_peers-36       96.64n ±  6%   112.75n ±  8%  +16.67% (p=0.002 n=6)
RIBLookup/100000_routes,_5_peers-36       102.5n ±  9%    122.2n ±  3%  +19.22% (p=0.002 n=6)
RIBLookup/1000000_routes,_1_peers-36      159.0n ±  8%    172.9n ± 15%        ~ (p=0.132 n=6)
RIBLookup/1000000_routes,_2_peers-36      157.9n ± 10%    198.8n ± 21%  +25.83% (p=0.026 n=6)
RIBLookup/1000000_routes,_5_peers-36      181.2n ± 17%    232.2n ± 20%  +28.11% (p=0.004 n=6)
RTAHash-36                                19.30n ±  4%
RTAEqual-36                               8.700n ±  9%
geomean                                   52.17n          72.07n         +9.51%               ¹
¹ benchmark set differs from baseline; geomeans may not be comparable

                                   │ bench-step0.txt │           bench-step6.txt            │
                                   │      ms/op      │     ms/op      vs base               │
RIBFlush/1000_routes,_1_peers-36        578.6m ±  8%    774.4m ±  1%  +33.83% (p=0.002 n=6)
RIBFlush/1000_routes,_2_peers-36        922.9m ±  8%   1522.0m ±  3%  +64.91% (p=0.002 n=6)
RIBFlush/1000_routes,_5_peers-36         1.825 ±  4%     3.127 ±  3%  +71.27% (p=0.002 n=6)
RIBFlush/10000_routes,_1_peers-36        5.619 ±  8%     7.637 ±  3%  +35.93% (p=0.002 n=6)
RIBFlush/10000_routes,_2_peers-36        9.527 ±  4%    14.060 ±  5%  +47.58% (p=0.002 n=6)
RIBFlush/10000_routes,_5_peers-36        20.67 ±  4%     35.38 ±  9%  +71.12% (p=0.002 n=6)
RIBFlush/100000_routes,_1_peers-36       76.62 ± 12%     75.82 ±  5%        ~ (p=0.589 n=6)
RIBFlush/100000_routes,_2_peers-36       114.3 ±  5%     158.3 ± 15%  +38.43% (p=0.002 n=6)
RIBFlush/100000_routes,_5_peers-36       218.8 ± 10%     373.8 ±  3%  +70.84% (p=0.002 n=6)
geomean                                  10.84           15.84        +46.12%
```
sync.Map is using "any" and therefore, there is a performance hit.
Instead, use xsync.Map that is mostly a dropin replacement without this
issue. I did not bench it against concurrent swiss maps that were tested
in an earlier commit. The benchmarks are a bit artificial, I don't think
this is worth it.

```
goos: linux
goarch: amd64
pkg: akvorado/outlet/routing/provider/bmp
cpu: Intel(R) Xeon(R) W-2295 CPU @ 3.00GHz
                                       │ bench-step0.txt │          bench-step7.txt           │
                                       │   bytes/route   │ bytes/route  vs base               │
RIBInsertion/1000_routes,_1_peers-36          345.5 ± 4%    452.4 ± 7%  +30.92% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36          360.0 ± 3%    433.2 ± 0%  +20.33% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36          323.5 ± 0%    441.1 ± 0%  +36.37% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36         322.8 ± 0%    441.4 ± 0%  +36.76% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36         317.9 ± 0%    432.9 ± 0%  +36.17% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36         269.8 ± 0%    418.6 ± 0%  +55.17% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36        265.0 ± 0%    411.2 ± 0%  +55.17% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36        251.0 ± 0%    389.4 ± 0%  +55.14% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36        207.1 ± 1%    338.4 ± 0%  +63.42% (p=0.002 n=6)
geomean                                       291.8         416.2       +42.63%

                                       │ bench-step0.txt │            bench-step7.txt             │
                                       │    sec/route    │   sec/route    vs base                 │
RIBInsertion/1000_routes,_1_peers-36        1.135µ ±  9%    9.984µ ±  4%   +779.65% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36        1.133µ ±  5%    8.827µ ±  4%   +679.38% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36        1.112µ ±  5%    9.790µ ±  9%   +780.35% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36       1.189µ ±  8%   11.927µ ±  6%   +903.49% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36       1.242µ ± 12%   12.903µ ± 10%   +939.27% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36       1.205µ ±  7%   15.608µ ± 12%  +1195.81% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36      1.086µ ±  8%   15.154µ ±  9%  +1296.04% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36      1.037µ ±  7%   14.102µ ±  4%  +1260.54% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36      1.154µ ±  6%   11.469µ ±  5%   +894.23% (p=0.002 n=6)
geomean                                     1.142µ          11.98µ         +949.16%

                                       │ bench-step0.txt │              bench-step7.txt               │
                                       │    allocs/op    │   allocs/op    vs base                     │
RIBInsertion/1000_routes,_1_peers-36       2.069k ± 0%      58.341k ± 0%  +2719.77% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36       3.376k ± 0%      78.516k ± 1%  +2225.70% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36       6.900k ± 0%     154.131k ± 1%  +2133.79% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36      13.23k ± 0%      351.93k ± 1%  +2560.31% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36      27.52k ± 0%      920.91k ± 0%  +3246.56% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36      81.70k ± 0%     3548.12k ± 1%  +4243.02% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36     183.0k ± 0%      8517.4k ± 0%  +4555.57% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36     354.7k ± 0%     15470.1k ± 0%  +4261.78% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36     690.1k ± 0%     23703.6k ± 0%  +3334.77% (p=0.002 n=6)
RIBLookup/1000_routes,_1_peers-36           0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000_routes,_2_peers-36           0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000_routes,_5_peers-36           0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_1_peers-36          0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_2_peers-36          0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_5_peers-36          0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_1_peers-36         0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_2_peers-36         0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_5_peers-36         0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_1_peers-36        0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_2_peers-36        0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_5_peers-36        0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBFlush/1000_routes,_1_peers-36          2055.00 ± 0%        41.00 ± 0%    -98.00% (p=0.002 n=6)
RIBFlush/1000_routes,_2_peers-36           3.363k ± 0%       2.047k ± 0%    -39.13% (p=0.002 n=6)
RIBFlush/1000_routes,_5_peers-36           6.834k ± 0%       5.651k ± 0%    -17.31% (p=0.002 n=6)
RIBFlush/10000_routes,_1_peers-36         13011.0 ± 0%        118.0 ± 0%    -99.09% (p=0.002 n=6)
RIBFlush/10000_routes,_2_peers-36          27.13k ± 0%       12.98k ± 0%    -52.17% (p=0.002 n=6)
RIBFlush/10000_routes,_5_peers-36          81.30k ± 0%       62.19k ± 0%    -23.50% (p=0.002 n=6)
RIBFlush/100000_routes,_1_peers-36       181413.0 ± 0%        587.0 ± 0%    -99.68% (p=0.002 n=6)
RIBFlush/100000_routes,_2_peers-36         352.1k ± 0%       182.1k ± 0%    -48.28% (p=0.002 n=6)
RIBFlush/100000_routes,_5_peers-36         685.2k ± 0%       591.8k ± 0%    -13.62% (p=0.002 n=6)
RTAHash-36                                  0.000 ± 0%
RTAEqual-36                                 0.000 ± 0%
geomean                                                ²                    +61.93%               ³ ²
¹ all samples are equal
² summaries must be >0 to compute geomean
³ benchmark set differs from baseline; geomeans may not be comparable

                                     │ bench-step0.txt │            bench-step7.txt             │
                                     │     sec/op      │    sec/op      vs base                 │
RIBLookup/1000_routes,_1_peers-36         30.39n ±  5%    30.03n ±  2%        ~ (p=0.563 n=6)
RIBLookup/1000_routes,_2_peers-36         30.30n ±  4%    30.83n ±  4%        ~ (p=0.180 n=6)
RIBLookup/1000_routes,_5_peers-36         32.59n ± 21%    32.25n ±  9%        ~ (p=0.818 n=6)
RIBLookup/10000_routes,_1_peers-36        33.58n ± 13%    34.56n ±  3%        ~ (p=0.310 n=6)
RIBLookup/10000_routes,_2_peers-36        37.09n ±  5%    36.45n ±  3%        ~ (p=0.589 n=6)
RIBLookup/10000_routes,_5_peers-36        44.42n ± 12%    43.58n ±  9%        ~ (p=0.937 n=6)
RIBLookup/100000_routes,_1_peers-36       88.08n ± 15%    96.90n ±  7%  +10.01% (p=0.026 n=6)
RIBLookup/100000_routes,_2_peers-36       96.64n ±  6%   111.05n ±  2%  +14.91% (p=0.002 n=6)
RIBLookup/100000_routes,_5_peers-36       102.5n ±  9%    120.0n ±  4%  +17.07% (p=0.002 n=6)
RIBLookup/1000000_routes,_1_peers-36      159.0n ±  8%    170.1n ± 12%        ~ (p=0.221 n=6)
RIBLookup/1000000_routes,_2_peers-36      157.9n ± 10%    196.3n ± 12%  +24.25% (p=0.002 n=6)
RIBLookup/1000000_routes,_5_peers-36      181.2n ± 17%    228.9n ± 19%  +26.26% (p=0.015 n=6)
RTAHash-36                                19.30n ±  4%
RTAEqual-36                               8.700n ±  9%
geomean                                   52.17n          70.91n         +7.76%               ¹
¹ benchmark set differs from baseline; geomeans may not be comparable

                                   │ bench-step0.txt │           bench-step7.txt           │
                                   │      ms/op      │    ms/op      vs base               │
RIBFlush/1000_routes,_1_peers-36        578.6m ±  8%    737.3m ± 1%  +27.44% (p=0.002 n=6)
RIBFlush/1000_routes,_2_peers-36        922.9m ±  8%   1373.5m ± 3%  +48.82% (p=0.002 n=6)
RIBFlush/1000_routes,_5_peers-36         1.825 ±  4%     2.542 ± 3%  +39.22% (p=0.002 n=6)
RIBFlush/10000_routes,_1_peers-36        5.619 ±  8%     6.957 ± 2%  +23.82% (p=0.002 n=6)
RIBFlush/10000_routes,_2_peers-36        9.527 ±  4%    10.670 ± 4%  +12.00% (p=0.002 n=6)
RIBFlush/10000_routes,_5_peers-36        20.67 ±  4%     27.73 ± 9%  +34.15% (p=0.002 n=6)
RIBFlush/100000_routes,_1_peers-36       76.62 ± 12%     58.81 ± 8%  -23.25% (p=0.002 n=6)
RIBFlush/100000_routes,_2_peers-36       114.3 ±  5%     105.5 ± 5%   -7.78% (p=0.009 n=6)
RIBFlush/100000_routes,_5_peers-36       218.8 ± 10%     227.0 ± 6%        ~ (p=0.485 n=6)
geomean                                  10.84           12.50       +15.32%
```
They are not modified anymore and can be stored directly.

```
goos: linux
goarch: amd64
pkg: akvorado/outlet/routing/provider/bmp
cpu: Intel(R) Xeon(R) W-2295 CPU @ 3.00GHz
                                       │ bench-step0.txt │          bench-step8.txt           │
                                       │   bytes/route   │ bytes/route  vs base               │
RIBInsertion/1000_routes,_1_peers-36          345.5 ± 4%    454.5 ± 7%  +31.53% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36          360.0 ± 3%    433.6 ± 0%  +20.46% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36          323.5 ± 0%    442.3 ± 1%  +36.72% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36         322.8 ± 0%    442.0 ± 0%  +36.95% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36         317.9 ± 0%    433.1 ± 0%  +36.22% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36         269.8 ± 0%    418.6 ± 0%  +55.15% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36        265.0 ± 0%    411.3 ± 0%  +55.21% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36        251.0 ± 0%    389.4 ± 0%  +55.14% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36        207.1 ± 1%    338.6 ± 0%  +63.50% (p=0.002 n=6)
geomean                                       291.8         416.7       +42.79%

                                       │ bench-step0.txt │            bench-step8.txt            │
                                       │    sec/route    │  sec/route    vs base                 │
RIBInsertion/1000_routes,_1_peers-36        1.135µ ±  9%   10.123µ ± 4%   +791.85% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36        1.133µ ±  5%    8.864µ ± 6%   +682.74% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36        1.112µ ±  5%    9.658µ ± 6%   +768.48% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36       1.189µ ±  8%   11.451µ ± 6%   +863.48% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36       1.242µ ± 12%   13.130µ ± 2%   +957.55% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36       1.205µ ±  7%   16.346µ ± 7%  +1257.08% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36      1.086µ ±  8%   15.022µ ± 5%  +1283.83% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36      1.037µ ±  7%   14.529µ ± 7%  +1301.74% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36      1.154µ ±  6%   11.591µ ± 5%   +904.85% (p=0.002 n=6)
geomean                                     1.142µ          12.06µ        +956.08%

                                       │ bench-step0.txt │              bench-step8.txt               │
                                       │    allocs/op    │   allocs/op    vs base                     │
RIBInsertion/1000_routes,_1_peers-36       2.069k ± 0%      58.406k ± 0%  +2722.89% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36       3.376k ± 0%      78.456k ± 0%  +2223.92% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36       6.900k ± 0%     154.810k ± 1%  +2143.62% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36      13.23k ± 0%      349.60k ± 1%  +2542.69% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36      27.52k ± 0%      921.70k ± 0%  +3249.45% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36      81.70k ± 0%     3545.51k ± 0%  +4239.82% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36     183.0k ± 0%      8517.4k ± 0%  +4555.55% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36     354.7k ± 0%     15470.1k ± 0%  +4261.78% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36     690.1k ± 0%     23703.9k ± 0%  +3334.80% (p=0.002 n=6)
RIBLookup/1000_routes,_1_peers-36           0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000_routes,_2_peers-36           0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000_routes,_5_peers-36           0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_1_peers-36          0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_2_peers-36          0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_5_peers-36          0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_1_peers-36         0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_2_peers-36         0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_5_peers-36         0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_1_peers-36        0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_2_peers-36        0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_5_peers-36        0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBFlush/1000_routes,_1_peers-36          2055.00 ± 0%        41.00 ± 0%    -98.00% (p=0.002 n=6)
RIBFlush/1000_routes,_2_peers-36           3.363k ± 0%       2.047k ± 0%    -39.13% (p=0.002 n=6)
RIBFlush/1000_routes,_5_peers-36           6.834k ± 0%       5.651k ± 0%    -17.31% (p=0.002 n=6)
RIBFlush/10000_routes,_1_peers-36         13011.0 ± 0%        118.0 ± 0%    -99.09% (p=0.002 n=6)
RIBFlush/10000_routes,_2_peers-36          27.13k ± 0%       12.98k ± 0%    -52.17% (p=0.002 n=6)
RIBFlush/10000_routes,_5_peers-36          81.30k ± 0%       62.19k ± 0%    -23.50% (p=0.002 n=6)
RIBFlush/100000_routes,_1_peers-36       181413.0 ± 0%        587.0 ± 0%    -99.68% (p=0.002 n=6)
RIBFlush/100000_routes,_2_peers-36         352.1k ± 0%       182.1k ± 0%    -48.28% (p=0.002 n=6)
RIBFlush/100000_routes,_5_peers-36         685.2k ± 0%       591.8k ± 0%    -13.62% (p=0.002 n=6)
RTAHash-36                                  0.000 ± 0%
RTAEqual-36                                 0.000 ± 0%
geomean                                                ²                    +61.92%               ³ ²
¹ all samples are equal
² summaries must be >0 to compute geomean
³ benchmark set differs from baseline; geomeans may not be comparable

                                     │ bench-step0.txt │            bench-step8.txt             │
                                     │     sec/op      │    sec/op      vs base                 │
RIBLookup/1000_routes,_1_peers-36         30.39n ±  5%    30.32n ±  3%        ~ (p=0.589 n=6)
RIBLookup/1000_routes,_2_peers-36         30.30n ±  4%    29.72n ± 21%        ~ (p=0.180 n=6)
RIBLookup/1000_routes,_5_peers-36         32.59n ± 21%    31.79n ±  3%        ~ (p=0.193 n=6)
RIBLookup/10000_routes,_1_peers-36        33.58n ± 13%    34.92n ±  5%        ~ (p=0.240 n=6)
RIBLookup/10000_routes,_2_peers-36        37.09n ±  5%    38.45n ±  5%        ~ (p=0.132 n=6)
RIBLookup/10000_routes,_5_peers-36        44.42n ± 12%    44.34n ±  5%        ~ (p=0.818 n=6)
RIBLookup/100000_routes,_1_peers-36       88.08n ± 15%    99.03n ±  4%        ~ (p=0.065 n=6)
RIBLookup/100000_routes,_2_peers-36       96.64n ±  6%   112.60n ±  6%  +16.51% (p=0.002 n=6)
RIBLookup/100000_routes,_5_peers-36       102.5n ±  9%    119.6n ±  3%  +16.68% (p=0.002 n=6)
RIBLookup/1000000_routes,_1_peers-36      159.0n ±  8%    174.7n ± 17%        ~ (p=0.065 n=6)
RIBLookup/1000000_routes,_2_peers-36      157.9n ± 10%    195.8n ± 15%  +23.99% (p=0.002 n=6)
RIBLookup/1000000_routes,_5_peers-36      181.2n ± 17%    230.0n ± 18%  +26.90% (p=0.009 n=6)
RTAHash-36                                19.30n ±  4%
RTAEqual-36                               8.700n ±  9%
geomean                                   52.17n          71.51n         +8.67%               ¹
¹ benchmark set differs from baseline; geomeans may not be comparable

                                   │ bench-step0.txt │           bench-step8.txt            │
                                   │      ms/op      │     ms/op      vs base               │
RIBFlush/1000_routes,_1_peers-36        578.6m ±  8%    739.0m ±  1%  +27.73% (p=0.002 n=6)
RIBFlush/1000_routes,_2_peers-36        922.9m ±  8%   1355.0m ±  2%  +46.82% (p=0.002 n=6)
RIBFlush/1000_routes,_5_peers-36         1.825 ±  4%     2.593 ±  4%  +42.02% (p=0.002 n=6)
RIBFlush/10000_routes,_1_peers-36        5.619 ±  8%     7.162 ±  6%  +27.47% (p=0.002 n=6)
RIBFlush/10000_routes,_2_peers-36        9.527 ±  4%    11.260 ±  3%  +18.19% (p=0.002 n=6)
RIBFlush/10000_routes,_5_peers-36        20.67 ±  4%     29.70 ±  6%  +43.65% (p=0.002 n=6)
RIBFlush/100000_routes,_1_peers-36       76.62 ± 12%     63.95 ±  6%  -16.55% (p=0.002 n=6)
RIBFlush/100000_routes,_2_peers-36       114.3 ±  5%     117.8 ± 14%        ~ (p=0.180 n=6)
RIBFlush/100000_routes,_5_peers-36       218.8 ± 10%     254.0 ±  8%  +16.11% (p=0.015 n=6)
geomean                                  10.84           13.17        +21.47%
```
```
goos: linux
goarch: amd64
pkg: akvorado/outlet/routing/provider/bmp
cpu: Intel(R) Xeon(R) W-2295 CPU @ 3.00GHz
                                       │ bench-step0.txt │          bench-step9.txt           │
                                       │   bytes/route   │ bytes/route  vs base               │
RIBInsertion/1000_routes,_1_peers-36          345.5 ± 4%    453.4 ± 7%  +31.23% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36          360.0 ± 3%    432.4 ± 1%  +20.12% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36          323.5 ± 0%    441.6 ± 1%  +36.51% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36         322.8 ± 0%    441.2 ± 0%  +36.72% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36         317.9 ± 0%    432.3 ± 0%  +35.99% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36         269.8 ± 0%    418.6 ± 0%  +55.15% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36        265.0 ± 0%    411.4 ± 0%  +55.25% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36        251.0 ± 0%    389.5 ± 0%  +55.18% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36        207.1 ± 1%    338.5 ± 0%  +63.45% (p=0.002 n=6)
geomean                                       291.8         416.2       +42.64%

                                       │ bench-step0.txt │            bench-step9.txt             │
                                       │    sec/route    │   sec/route    vs base                 │
RIBInsertion/1000_routes,_1_peers-36        1.135µ ±  9%   10.434µ ±  4%   +819.25% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36        1.133µ ±  5%    8.652µ ±  3%   +663.97% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36        1.112µ ±  5%    9.967µ ±  7%   +796.31% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36       1.189µ ±  8%   12.380µ ± 14%   +941.65% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36       1.242µ ± 12%   13.539µ ± 13%   +990.50% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36       1.205µ ±  7%   15.933µ ±  6%  +1222.75% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36      1.086µ ±  8%   15.746µ ± 14%  +1350.58% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36      1.037µ ±  7%   14.591µ ±  9%  +1307.67% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36      1.154µ ±  6%   11.803µ ±  4%   +923.19% (p=0.002 n=6)
geomean                                     1.142µ          12.31µ         +978.61%

                                       │ bench-step0.txt │              bench-step9.txt               │
                                       │    allocs/op    │   allocs/op    vs base                     │
RIBInsertion/1000_routes,_1_peers-36       2.069k ± 0%      58.440k ± 0%  +2724.55% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36       3.376k ± 0%      78.376k ± 1%  +2221.55% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36       6.900k ± 0%     155.882k ± 1%  +2159.16% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36      13.23k ± 0%      351.68k ± 1%  +2558.43% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36      27.52k ± 0%      921.89k ± 0%  +3250.15% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36      81.70k ± 0%     3553.72k ± 0%  +4249.87% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36     183.0k ± 0%      8533.5k ± 0%  +4564.36% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36     354.7k ± 0%     15520.3k ± 0%  +4275.95% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36     690.1k ± 0%     23824.0k ± 0%  +3352.21% (p=0.002 n=6)
RIBLookup/1000_routes,_1_peers-36           0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000_routes,_2_peers-36           0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000_routes,_5_peers-36           0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_1_peers-36          0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_2_peers-36          0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_5_peers-36          0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_1_peers-36         0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_2_peers-36         0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_5_peers-36         0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_1_peers-36        0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_2_peers-36        0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_5_peers-36        0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBFlush/1000_routes,_1_peers-36          2055.00 ± 0%        41.00 ± 0%    -98.00% (p=0.002 n=6)
RIBFlush/1000_routes,_2_peers-36           3.363k ± 0%       2.047k ± 0%    -39.13% (p=0.002 n=6)
RIBFlush/1000_routes,_5_peers-36           6.834k ± 0%       5.651k ± 0%    -17.31% (p=0.002 n=6)
RIBFlush/10000_routes,_1_peers-36         13011.0 ± 0%        118.0 ± 0%    -99.09% (p=0.002 n=6)
RIBFlush/10000_routes,_2_peers-36          27.13k ± 0%       12.98k ± 0%    -52.17% (p=0.002 n=6)
RIBFlush/10000_routes,_5_peers-36          81.30k ± 0%       62.19k ± 0%    -23.50% (p=0.002 n=6)
RIBFlush/100000_routes,_1_peers-36       181413.0 ± 0%        587.0 ± 0%    -99.68% (p=0.002 n=6)
RIBFlush/100000_routes,_2_peers-36         352.1k ± 0%       182.1k ± 0%    -48.28% (p=0.002 n=6)
RIBFlush/100000_routes,_5_peers-36         685.2k ± 0%       591.8k ± 0%    -13.62% (p=0.002 n=6)
RTAHash-36                                  0.000 ± 0%
RTAEqual-36                                 0.000 ± 0%
geomean                                                ²                    +62.05%               ³ ²
¹ all samples are equal
² summaries must be >0 to compute geomean
³ benchmark set differs from baseline; geomeans may not be comparable

                                     │ bench-step0.txt │            bench-step9.txt             │
                                     │     sec/op      │    sec/op      vs base                 │
RIBLookup/1000_routes,_1_peers-36         30.39n ±  5%    29.83n ±  4%        ~ (p=0.310 n=6)
RIBLookup/1000_routes,_2_peers-36         30.30n ±  4%    32.22n ±  3%   +6.34% (p=0.004 n=6)
RIBLookup/1000_routes,_5_peers-36         32.59n ± 21%    33.41n ±  4%        ~ (p=0.699 n=6)
RIBLookup/10000_routes,_1_peers-36        33.58n ± 13%    35.77n ±  4%        ~ (p=0.093 n=6)
RIBLookup/10000_routes,_2_peers-36        37.09n ±  5%    38.65n ±  6%   +4.19% (p=0.009 n=6)
RIBLookup/10000_routes,_5_peers-36        44.42n ± 12%    45.89n ±  7%        ~ (p=0.485 n=6)
RIBLookup/100000_routes,_1_peers-36       88.08n ± 15%   103.34n ±  9%  +17.33% (p=0.015 n=6)
RIBLookup/100000_routes,_2_peers-36       96.64n ±  6%   113.75n ±  8%  +17.70% (p=0.002 n=6)
RIBLookup/100000_routes,_5_peers-36       102.5n ±  9%    121.5n ±  9%  +18.54% (p=0.004 n=6)
RIBLookup/1000000_routes,_1_peers-36      159.0n ±  8%    171.6n ±  9%   +7.96% (p=0.026 n=6)
RIBLookup/1000000_routes,_2_peers-36      157.9n ± 10%    200.3n ± 17%  +26.84% (p=0.004 n=6)
RIBLookup/1000000_routes,_5_peers-36      181.2n ± 17%    227.6n ± 15%  +25.57% (p=0.009 n=6)
RTAHash-36                                19.30n ±  4%
RTAEqual-36                               8.700n ±  9%
geomean                                   52.17n          72.97n        +10.88%               ¹
¹ benchmark set differs from baseline; geomeans may not be comparable

                                   │ bench-step0.txt │           bench-step9.txt            │
                                   │      ms/op      │     ms/op      vs base               │
RIBFlush/1000_routes,_1_peers-36        578.6m ±  8%    726.5m ±  2%  +25.55% (p=0.002 n=6)
RIBFlush/1000_routes,_2_peers-36        922.9m ±  8%   1349.0m ±  2%  +46.17% (p=0.002 n=6)
RIBFlush/1000_routes,_5_peers-36         1.825 ±  4%     2.498 ±  3%  +36.84% (p=0.002 n=6)
RIBFlush/10000_routes,_1_peers-36        5.619 ±  8%     7.110 ±  4%  +26.55% (p=0.002 n=6)
RIBFlush/10000_routes,_2_peers-36        9.527 ±  4%    10.705 ±  4%  +12.36% (p=0.002 n=6)
RIBFlush/10000_routes,_5_peers-36        20.67 ±  4%     26.76 ±  8%  +29.43% (p=0.002 n=6)
RIBFlush/100000_routes,_1_peers-36       76.62 ± 12%     57.59 ±  7%  -24.85% (p=0.002 n=6)
RIBFlush/100000_routes,_2_peers-36       114.3 ±  5%     107.1 ±  5%        ~ (p=0.065 n=6)
RIBFlush/100000_routes,_5_peers-36       218.8 ± 10%     221.4 ± 11%        ~ (p=0.818 n=6)
geomean                                  10.84           12.37        +14.15%
```
It looks like the second one is more optimized on the paper, but the
insertion rate is terrible.

```
goos: linux
goarch: amd64
pkg: akvorado/outlet/routing/provider/bmp
cpu: Intel(R) Xeon(R) W-2295 CPU @ 3.00GHz
                                       │ bench-step0.txt │          bench-step10.txt          │
                                       │   bytes/route   │ bytes/route  vs base               │
RIBInsertion/1000_routes,_1_peers-36          345.5 ± 4%    462.2 ± 9%  +33.76% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36          360.0 ± 3%    440.8 ± 1%  +22.43% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36          323.5 ± 0%    436.0 ± 0%  +34.78% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36         322.8 ± 0%    437.4 ± 0%  +35.51% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36         317.9 ± 0%    428.8 ± 0%  +34.87% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36         269.8 ± 0%    427.5 ± 0%  +58.45% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36        265.0 ± 0%    420.5 ± 0%  +58.68% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36        251.0 ± 0%    398.8 ± 0%  +58.88% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36        207.1 ± 1%    346.8 ± 0%  +67.46% (p=0.002 n=6)
geomean                                       291.8         420.8       +44.21%

                                       │ bench-step0.txt │             bench-step10.txt             │
                                       │    sec/route    │   sec/route     vs base                  │
RIBInsertion/1000_routes,_1_peers-36        1.135µ ±  9%    10.740µ ±  6%    +846.26% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36        1.133µ ±  5%    10.124µ ±  6%    +793.95% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36        1.112µ ±  5%    11.789µ ±  6%    +960.12% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36       1.189µ ±  8%    18.016µ ± 13%   +1415.82% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36       1.242µ ± 12%    26.777µ ±  9%   +2056.87% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36       1.205µ ±  7%    50.710µ ±  6%   +4110.05% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36      1.086µ ±  8%    86.169µ ±  3%   +7838.23% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36      1.037µ ±  7%   164.565µ ±  4%  +15776.94% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36      1.154µ ±  6%   651.863µ ±  3%  +56411.75% (p=0.002 n=6)
geomean                                     1.142µ           40.45µ         +3442.75%

                                       │ bench-step0.txt │              bench-step10.txt              │
                                       │    allocs/op    │   allocs/op    vs base                     │
RIBInsertion/1000_routes,_1_peers-36       2.069k ± 0%      58.643k ± 0%  +2734.36% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36       3.376k ± 0%      79.115k ± 0%  +2243.47% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36       6.900k ± 0%     155.886k ± 1%  +2159.22% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36      13.23k ± 0%      352.27k ± 1%  +2562.90% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36      27.52k ± 0%      923.95k ± 2%  +3257.61% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36      81.70k ± 0%     3572.06k ± 0%  +4272.32% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36     183.0k ± 0%      8565.2k ± 0%  +4581.69% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36     354.7k ± 0%     15583.8k ± 0%  +4293.85% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36     690.1k ± 0%     23956.4k ± 0%  +3371.40% (p=0.002 n=6)
RIBLookup/1000_routes,_1_peers-36           0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000_routes,_2_peers-36           0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000_routes,_5_peers-36           0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_1_peers-36          0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_2_peers-36          0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_5_peers-36          0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_1_peers-36         0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_2_peers-36         0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_5_peers-36         0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_1_peers-36        0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_2_peers-36        0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_5_peers-36        0.000 ± 0%
RIBFlush/1000_routes,_1_peers-36           2.055k ± 0%
RIBFlush/1000_routes,_2_peers-36           3.363k ± 0%
RIBFlush/1000_routes,_5_peers-36           6.834k ± 0%
RIBFlush/10000_routes,_1_peers-36          13.01k ± 0%
RIBFlush/10000_routes,_2_peers-36          27.13k ± 0%
RIBFlush/10000_routes,_5_peers-36          81.30k ± 0%
RIBFlush/100000_routes,_1_peers-36         181.4k ± 0%
RIBFlush/100000_routes,_2_peers-36         352.1k ± 0%
RIBFlush/100000_routes,_5_peers-36         685.2k ± 0%
RTAHash-36                                  0.000 ± 0%
RTAEqual-36                                 0.000 ± 0%
geomean                                                ²                   +379.85%               ³ ²
¹ all samples are equal
² summaries must be >0 to compute geomean
³ benchmark set differs from baseline; geomeans may not be comparable

                                     │ bench-step0.txt │            bench-step10.txt            │
                                     │     sec/op      │    sec/op      vs base                 │
RIBLookup/1000_routes,_1_peers-36         30.39n ±  5%    29.89n ±  3%        ~ (p=0.485 n=6)
RIBLookup/1000_routes,_2_peers-36         30.30n ±  4%    30.72n ±  2%        ~ (p=0.180 n=6)
RIBLookup/1000_routes,_5_peers-36         32.59n ± 21%    32.66n ±  3%        ~ (p=1.000 n=6)
RIBLookup/10000_routes,_1_peers-36        33.58n ± 13%    35.03n ±  5%        ~ (p=0.240 n=6)
RIBLookup/10000_routes,_2_peers-36        37.09n ±  5%    37.12n ±  4%        ~ (p=0.851 n=6)
RIBLookup/10000_routes,_5_peers-36        44.42n ± 12%    42.56n ±  5%        ~ (p=0.180 n=6)
RIBLookup/100000_routes,_1_peers-36       88.08n ± 15%    97.26n ±  2%        ~ (p=0.065 n=6)
RIBLookup/100000_routes,_2_peers-36       96.64n ±  6%   111.25n ±  2%  +15.12% (p=0.002 n=6)
RIBLookup/100000_routes,_5_peers-36       102.5n ±  9%    121.2n ±  4%  +18.29% (p=0.002 n=6)
RIBLookup/1000000_routes,_1_peers-36      159.0n ±  8%    177.3n ± 33%  +11.51% (p=0.002 n=6)
RIBLookup/1000000_routes,_2_peers-36      157.9n ± 10%    174.1n ±  8%  +10.22% (p=0.015 n=6)
RIBLookup/1000000_routes,_5_peers-36      181.2n ± 17%
RTAHash-36                                19.30n ±  4%
RTAEqual-36                               8.700n ±  9%
geomean                                   52.17n          63.46n         +5.73%               ¹
¹ benchmark set differs from baseline; geomeans may not be comparable

                                   │ bench-step0.txt │
                                   │      ms/op      │
RIBFlush/1000_routes,_1_peers-36        578.6m ±  8%
RIBFlush/1000_routes,_2_peers-36        922.9m ±  8%
RIBFlush/1000_routes,_5_peers-36         1.825 ±  4%
RIBFlush/10000_routes,_1_peers-36        5.619 ±  8%
RIBFlush/10000_routes,_2_peers-36        9.527 ±  4%
RIBFlush/10000_routes,_5_peers-36        20.67 ±  4%
RIBFlush/100000_routes,_1_peers-36       76.62 ± 12%
RIBFlush/100000_routes,_2_peers-36       114.3 ±  5%
RIBFlush/100000_routes,_5_peers-36       218.8 ± 10%
geomean                                  10.84
```
Insertion is far too slow with pb.MapOf. Keep some of the improvements:

- use RangeRelaxed() instead of Range() as we already have a writer lock
- keep LoadAndDelete()
- keep Compute()

This is the final commit of this series. 42% increase in space, 1000%
increase in insertion time, 12% lookup. The benchmarks do not test
performance of multiple routines updating/looking up the RIB, but the
idea is that it should behave better without locks, even if it is slower
during updates.

```
goos: linux
goarch: amd64
pkg: akvorado/outlet/routing/provider/bmp
cpu: Intel(R) Xeon(R) W-2295 CPU @ 3.00GHz
                                       │ bench-step0.txt │          bench-step11.txt          │
                                       │   bytes/route   │ bytes/route  vs base               │
RIBInsertion/1000_routes,_1_peers-36          345.5 ± 4%    453.9 ± 6%  +31.37% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36          360.0 ± 3%    434.4 ± 1%  +20.68% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36          323.5 ± 0%    442.4 ± 0%  +36.77% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36         322.8 ± 0%    440.6 ± 0%  +36.51% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36         317.9 ± 0%    432.5 ± 0%  +36.05% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36         269.8 ± 0%    418.1 ± 0%  +54.99% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36        265.0 ± 0%    411.3 ± 0%  +55.21% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36        251.0 ± 0%    389.5 ± 0%  +55.18% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36        207.1 ± 1%    338.5 ± 0%  +63.45% (p=0.002 n=6)
geomean                                       291.8         416.5       +42.72%

                                       │ bench-step0.txt │            bench-step11.txt            │
                                       │    sec/route    │   sec/route    vs base                 │
RIBInsertion/1000_routes,_1_peers-36        1.135µ ±  9%    9.961µ ±  6%   +777.62% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36        1.133µ ±  5%    8.840µ ±  6%   +680.57% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36        1.112µ ±  5%    9.631µ ± 11%   +766.05% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36       1.189µ ±  8%   11.728µ ± 14%   +886.79% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36       1.242µ ± 12%   13.114µ ± 11%   +956.26% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36       1.205µ ±  7%   15.885µ ±  7%  +1218.80% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36      1.086µ ±  8%   14.773µ ±  6%  +1260.89% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36      1.037µ ±  7%   14.493µ ±  6%  +1298.22% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36      1.154µ ±  6%   11.614µ ±  6%   +906.81% (p=0.002 n=6)
geomean                                     1.142µ          12.00µ         +950.83%

                                       │ bench-step0.txt │              bench-step11.txt              │
                                       │    allocs/op    │   allocs/op    vs base                     │
RIBInsertion/1000_routes,_1_peers-36       2.069k ± 0%      58.389k ± 0%  +2722.06% (p=0.002 n=6)
RIBInsertion/1000_routes,_2_peers-36       3.376k ± 0%      78.648k ± 0%  +2229.62% (p=0.002 n=6)
RIBInsertion/1000_routes,_5_peers-36       6.900k ± 0%     155.323k ± 1%  +2151.06% (p=0.002 n=6)
RIBInsertion/10000_routes,_1_peers-36      13.23k ± 0%      349.77k ± 1%  +2543.95% (p=0.002 n=6)
RIBInsertion/10000_routes,_2_peers-36      27.52k ± 0%      923.58k ± 1%  +3256.27% (p=0.002 n=6)
RIBInsertion/10000_routes,_5_peers-36      81.70k ± 0%     3554.40k ± 1%  +4250.71% (p=0.002 n=6)
RIBInsertion/100000_routes,_1_peers-36     183.0k ± 0%      8533.5k ± 0%  +4564.36% (p=0.002 n=6)
RIBInsertion/100000_routes,_2_peers-36     354.7k ± 0%     15520.3k ± 0%  +4275.96% (p=0.002 n=6)
RIBInsertion/100000_routes,_5_peers-36     690.1k ± 0%     23823.9k ± 0%  +3352.20% (p=0.002 n=6)
RIBLookup/1000_routes,_1_peers-36           0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000_routes,_2_peers-36           0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000_routes,_5_peers-36           0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_1_peers-36          0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_2_peers-36          0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/10000_routes,_5_peers-36          0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_1_peers-36         0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_2_peers-36         0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/100000_routes,_5_peers-36         0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_1_peers-36        0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_2_peers-36        0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBLookup/1000000_routes,_5_peers-36        0.000 ± 0%        0.000 ± 0%          ~ (p=1.000 n=6) ¹
RIBFlush/1000_routes,_1_peers-36          2055.00 ± 0%        41.00 ± 0%    -98.00% (p=0.002 n=6)
RIBFlush/1000_routes,_2_peers-36           3.363k ± 0%       2.047k ± 0%    -39.13% (p=0.002 n=6)
RIBFlush/1000_routes,_5_peers-36           6.834k ± 0%       5.651k ± 0%    -17.31% (p=0.002 n=6)
RIBFlush/10000_routes,_1_peers-36         13011.0 ± 0%        118.0 ± 0%    -99.09% (p=0.002 n=6)
RIBFlush/10000_routes,_2_peers-36          27.13k ± 0%       12.98k ± 0%    -52.17% (p=0.002 n=6)
RIBFlush/10000_routes,_5_peers-36          81.30k ± 0%       62.19k ± 0%    -23.50% (p=0.002 n=6)
RIBFlush/100000_routes,_1_peers-36       181413.0 ± 0%        587.0 ± 0%    -99.68% (p=0.002 n=6)
RIBFlush/100000_routes,_2_peers-36         352.1k ± 0%       182.1k ± 0%    -48.28% (p=0.002 n=6)
RIBFlush/100000_routes,_5_peers-36         685.2k ± 0%       591.8k ± 0%    -13.62% (p=0.002 n=6)
RTAHash-36                                  0.000 ± 0%
RTAEqual-36                                 0.000 ± 0%
geomean                                                ²                    +62.03%               ³ ²
¹ all samples are equal
² summaries must be >0 to compute geomean
³ benchmark set differs from baseline; geomeans may not be comparable

                                     │ bench-step0.txt │            bench-step11.txt            │
                                     │     sec/op      │    sec/op      vs base                 │
RIBLookup/1000_routes,_1_peers-36         30.39n ±  5%    31.13n ±  6%        ~ (p=0.818 n=6)
RIBLookup/1000_routes,_2_peers-36         30.30n ±  4%    28.74n ±  7%   -5.16% (p=0.026 n=6)
RIBLookup/1000_routes,_5_peers-36         32.59n ± 21%    31.65n ±  4%        ~ (p=0.093 n=6)
RIBLookup/10000_routes,_1_peers-36        33.58n ± 13%    35.00n ±  2%        ~ (p=0.240 n=6)
RIBLookup/10000_routes,_2_peers-36        37.09n ±  5%    38.62n ±  3%   +4.12% (p=0.041 n=6)
RIBLookup/10000_routes,_5_peers-36        44.42n ± 12%    43.37n ±  6%        ~ (p=0.818 n=6)
RIBLookup/100000_routes,_1_peers-36       88.08n ± 15%    98.21n ±  3%        ~ (p=0.065 n=6)
RIBLookup/100000_routes,_2_peers-36       96.64n ±  6%   111.75n ±  3%  +15.64% (p=0.002 n=6)
RIBLookup/100000_routes,_5_peers-36       102.5n ±  9%    122.6n ±  4%  +19.56% (p=0.002 n=6)
RIBLookup/1000000_routes,_1_peers-36      159.0n ±  8%    173.5n ± 20%        ~ (p=0.132 n=6)
RIBLookup/1000000_routes,_2_peers-36      157.9n ± 10%    234.5n ± 24%  +48.46% (p=0.002 n=6)
RIBLookup/1000000_routes,_5_peers-36      181.2n ± 17%    294.4n ± 34%  +62.46% (p=0.009 n=6)
RTAHash-36                                19.30n ±  4%
RTAEqual-36                               8.700n ±  9%
geomean                                   52.17n          73.95n        +12.38%               ¹
¹ benchmark set differs from baseline; geomeans may not be comparable

                                   │ bench-step0.txt │          bench-step11.txt           │
                                   │      ms/op      │    ms/op      vs base               │
RIBFlush/1000_routes,_1_peers-36        578.6m ±  8%    728.7m ± 2%  +25.94% (p=0.002 n=6)
RIBFlush/1000_routes,_2_peers-36        922.9m ±  8%   1331.0m ± 3%  +44.22% (p=0.002 n=6)
RIBFlush/1000_routes,_5_peers-36         1.825 ±  4%     2.481 ± 3%  +35.88% (p=0.002 n=6)
RIBFlush/10000_routes,_1_peers-36        5.619 ±  8%     6.906 ± 3%  +22.92% (p=0.002 n=6)
RIBFlush/10000_routes,_2_peers-36        9.527 ±  4%    11.630 ± 8%  +22.07% (p=0.002 n=6)
RIBFlush/10000_routes,_5_peers-36        20.67 ±  4%     28.56 ± 5%  +38.16% (p=0.002 n=6)
RIBFlush/100000_routes,_1_peers-36       76.62 ± 12%     66.82 ± 9%  -12.79% (p=0.002 n=6)
RIBFlush/100000_routes,_2_peers-36       114.3 ±  5%     125.2 ± 9%   +9.49% (p=0.009 n=6)
RIBFlush/100000_routes,_5_peers-36       218.8 ± 10%     256.9 ± 4%  +17.44% (p=0.002 n=6)
geomean                                  10.84           13.16       +21.42%
```
This commit will be reverted at some point.
@vincentbernat

Copy link
Copy Markdown
Member Author

See tests in #2092. This does not help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

service::outlet Impact the outlet service

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reduce lock contention when receiving a lot of BMP messages

1 participant