Skip to content

part: allocate watch channels lazily - #178

Merged
joamaki merged 4 commits into
mainfrom
pr/joamaki/lazy-watches
Aug 25, 2026
Merged

part: allocate watch channels lazily#178
joamaki merged 4 commits into
mainfrom
pr/joamaki/lazy-watches

Conversation

@joamaki

@joamaki joamaki commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Only allocate the watch channels when requested.

Split Tree and Txn Get/Prefix into no-watch defaults and explicit GetWatch/PrefixWatch methods, and route ordinary StateDB index operations through no-watch paths while preserving existing watch invalidation semantics.

StateDB benchmarks:

goos: linux
goarch: arm64
pkg: github.com/cilium/statedb
                           │    a.txt     │               b.txt                │
                           │    sec/op    │    sec/op     vs base              │
DB_Modify-6                  570.2µ ± ∞ ¹   528.1µ ± ∞ ¹       ~ (p=0.095 n=5)
DB_GetInsert-6               633.9µ ± ∞ ¹   586.5µ ± ∞ ¹       ~ (p=0.095 n=5)
DB_RandomInsert-6            613.6µ ± ∞ ¹   515.3µ ± ∞ ¹       ~ (p=0.095 n=5)
DB_SequentialInsert-6        564.4µ ± ∞ ¹   501.2µ ± ∞ ¹       ~ (p=0.151 n=5)
DB_RandomLookup-6            34.62µ ± ∞ ¹   33.48µ ± ∞ ¹  -3.30% (p=0.016 n=5)
DB_SequentialLookup-6        27.89µ ± ∞ ¹   26.04µ ± ∞ ¹  -6.63% (p=0.008 n=5)
DB_Prefix_SecondaryIndex-6   112.2µ ± ∞ ¹   111.2µ ± ∞ ¹       ~ (p=0.151 n=5)
geomean                      201.7µ         186.2µ        -7.66%
¹ need >= 6 samples for confidence interval at level 0.95

                           │     a.txt     │                 b.txt                  │
                           │     B/op      │     B/op       vs base                 │
DB_Modify-6                  533.5Ki ± ∞ ¹   431.1Ki ± ∞ ¹  -19.18% (p=0.008 n=5)
DB_GetInsert-6               517.8Ki ± ∞ ¹   415.5Ki ± ∞ ¹  -19.76% (p=0.008 n=5)
DB_RandomInsert-6            509.9Ki ± ∞ ¹   407.7Ki ± ∞ ¹  -20.06% (p=0.008 n=5)
DB_SequentialInsert-6        509.9Ki ± ∞ ¹   407.7Ki ± ∞ ¹  -20.06% (p=0.008 n=5)
DB_RandomLookup-6              0.000 ± ∞ ¹     0.000 ± ∞ ¹        ~ (p=1.000 n=5) ²
DB_SequentialLookup-6          0.000 ± ∞ ¹     0.000 ± ∞ ¹        ~ (p=1.000 n=5) ²
DB_Prefix_SecondaryIndex-6   122.0Ki ± ∞ ¹   122.0Ki ± ∞ ¹   +0.03% (p=0.008 n=5)
geomean                                  ³                  -11.82%               ³
¹ need >= 6 samples for confidence interval at level 0.95
² all samples are equal
³ summaries must be >0 to compute geomean

Reconciler benchmark before (best of three runs):

1000000 objects reconciled in 1.35 seconds (batch size 1000) Throughput 740668.25 objects per second
888MB total allocated, 6015187 in-use objects, 338MB bytes in use 2.00user 0.21system 0:01.50elapsed 147%CPU (0avgtext+0avgdata 617884maxresident)k 152inputs+0outputs (1major+203587minor)pagefaults 0swaps

Reconciler benchmark after (best of three runs):

1000000 objects reconciled in 1.32 seconds (batch size 1000) Throughput 760075.67 objects per second
687MB total allocated, 6015138 in-use objects, 239MB bytes in use 2.17user 0.20system 0:01.45elapsed 162%CPU (0avgtext+0avgdata 475600maxresident)k 0inputs+0outputs (0major+136382minor)pagefaults 0swaps

AIL:3

@joamaki
joamaki requested a review from a team as a code owner August 21, 2026 15:25
@joamaki
joamaki requested review from derailed and removed request for a team August 21, 2026 15:25
@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown
$ make
go build ./...
go: downloading github.com/cilium/hive v1.0.4
go: downloading golang.org/x/time v0.15.0
go: downloading go.yaml.in/yaml/v3 v3.0.4
go: downloading github.com/spf13/cobra v1.10.2
go: downloading github.com/spf13/pflag v1.0.10
go: downloading github.com/cilium/stream v0.0.1
go: downloading github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de
go: downloading github.com/spf13/viper v1.18.2
go: downloading go.uber.org/dig v1.17.1
go: downloading golang.org/x/term v0.16.0
go: downloading github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
go: downloading github.com/mitchellh/mapstructure v1.5.0
go: downloading golang.org/x/sys v0.17.0
go: downloading golang.org/x/tools v0.17.0
go: downloading github.com/spf13/cast v1.6.0
go: downloading github.com/fsnotify/fsnotify v1.7.0
go: downloading github.com/sagikazarmark/slog-shim v0.1.0
go: downloading github.com/spf13/afero v1.11.0
go: downloading github.com/subosito/gotenv v1.6.0
go: downloading github.com/hashicorp/hcl v1.0.0
go: downloading gopkg.in/ini.v1 v1.67.0
go: downloading github.com/magiconair/properties v1.8.7
go: downloading github.com/pelletier/go-toml/v2 v2.1.0
go: downloading gopkg.in/yaml.v3 v3.0.1
go: downloading golang.org/x/text v0.14.0
STATEDB_VALIDATE=1 go test ./... -cover -vet=all -test.count 1
go: downloading github.com/stretchr/testify v1.11.1
go: downloading go.uber.org/goleak v1.3.0
go: downloading golang.org/x/exp v0.0.0-20240119083558-1b970713d09a
go: downloading github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2
ok  	github.com/cilium/statedb	318.891s	coverage: 79.3% of statements
ok  	github.com/cilium/statedb/index	0.004s	coverage: 33.7% of statements
ok  	github.com/cilium/statedb/internal	0.036s	coverage: 42.9% of statements
ok  	github.com/cilium/statedb/lpm	3.056s	coverage: 77.9% of statements
ok  	github.com/cilium/statedb/part	51.727s	coverage: 86.9% of statements
ok  	github.com/cilium/statedb/reconciler	0.270s	coverage: 93.1% of statements
	github.com/cilium/statedb/reconciler/benchmark		coverage: 0.0% of statements
	github.com/cilium/statedb/reconciler/example		coverage: 0.0% of statements
go test -race ./... -test.count 1
ok  	github.com/cilium/statedb	29.815s
ok  	github.com/cilium/statedb/index	1.012s
ok  	github.com/cilium/statedb/internal	1.021s
ok  	github.com/cilium/statedb/lpm	2.146s
ok  	github.com/cilium/statedb/part	28.438s
ok  	github.com/cilium/statedb/reconciler	1.380s
?   	github.com/cilium/statedb/reconciler/benchmark	[no test files]
?   	github.com/cilium/statedb/reconciler/example	[no test files]
go test ./... -bench . -benchmem -test.run xxx
goos: linux
goarch: amd64
pkg: github.com/cilium/statedb
cpu: AMD EPYC 9V74 80-Core Processor                
BenchmarkDB_WriteTxn_1-4                      	  984582	      1147 ns/op	    871472 objects/sec	     704 B/op	      17 allocs/op
BenchmarkDB_WriteTxn_10-4                     	 2654451	       447.8 ns/op	   2233178 objects/sec	     386 B/op	       8 allocs/op
BenchmarkDB_WriteTxn_100-4                    	 3432463	       347.6 ns/op	   2876977 objects/sec	     383 B/op	       7 allocs/op
BenchmarkDB_WriteTxn_1000-4                   	 3097887	       387.1 ns/op	   2583005 objects/sec	     342 B/op	       7 allocs/op
BenchmarkDB_WriteTxn_100_SecondaryIndex-4     	 1404951	       851.5 ns/op	   1174446 objects/sec	     792 B/op	      20 allocs/op
BenchmarkDB_WriteTxn_CommitOnly_100Tables-4   	 1238578	       968.6 ns/op	    1128 B/op	       6 allocs/op
BenchmarkDB_WriteTxn_CommitOnly_1Table-4      	 1912472	       637.0 ns/op	     240 B/op	       6 allocs/op
BenchmarkDB_NewWriteTxn-4                     	 1971141	       592.3 ns/op	     216 B/op	       5 allocs/op
BenchmarkDB_WriteTxnCommit100-4               	 1252765	       957.5 ns/op	    1112 B/op	       6 allocs/op
BenchmarkDB_NewReadTxn-4                      	732564398	         1.638 ns/op	       0 B/op	       0 allocs/op
BenchmarkDB_Modify-4                          	    2924	    405755 ns/op	   2464542 objects/sec	  366869 B/op	    8073 allocs/op
BenchmarkDB_GetInsert-4                       	    2565	    465347 ns/op	   2148933 objects/sec	  350867 B/op	    8073 allocs/op
BenchmarkDB_RandomInsert-4                    	    2882	    394204 ns/op	   2536760 objects/sec	  342863 B/op	    7073 allocs/op
BenchmarkDB_RandomReplace-4                   	     690	   1739141 ns/op	    574997 objects/sec	 1474369 B/op	   28103 allocs/op
BenchmarkDB_SequentialInsert-4                	    3115	    380249 ns/op	   2629853 objects/sec	  342863 B/op	    7073 allocs/op
BenchmarkDB_SequentialInsert_Prefix-4         	     714	   1644679 ns/op	    608021 objects/sec	 3245627 B/op	   45532 allocs/op
BenchmarkDB_Changes_Baseline-4                	    2608	    462360 ns/op	   2162815 objects/sec	  399795 B/op	    9165 allocs/op
BenchmarkDB_Changes-4                         	    1480	    811029 ns/op	   1233001 objects/sec	  600514 B/op	   12319 allocs/op
BenchmarkDB_RandomLookup-4                    	   35648	     33532 ns/op	  29822587 objects/sec	       0 B/op	       0 allocs/op
BenchmarkDB_SequentialLookup-4                	   35659	     33645 ns/op	  29722146 objects/sec	       0 B/op	       0 allocs/op
BenchmarkDB_Prefix_SecondaryIndex-4           	    9644	    114707 ns/op	   8717859 objects/sec	  124952 B/op	    1026 allocs/op
BenchmarkDB_FullIteration_All-4               	    1179	    936264 ns/op	 106807522 objects/sec	     104 B/op	       4 allocs/op
BenchmarkDB_FullIteration_Prefix-4            	    1082	   1011252 ns/op	  98887303 objects/sec	     136 B/op	       5 allocs/op
BenchmarkDB_FullIteration_Get-4               	     285	   4209520 ns/op	  23755677 objects/sec	       0 B/op	       0 allocs/op
BenchmarkDB_FullIteration_Get_Secondary-4     	     139	   8494376 ns/op	  11772495 objects/sec	       0 B/op	       0 allocs/op
BenchmarkDB_FullIteration_ReadTxnGet-4        	     280	   4240523 ns/op	  23581996 objects/sec	       0 B/op	       0 allocs/op
BenchmarkDB_PropagationDelay-4                	  955857	      1179 ns/op	        10.00 50th_µs	        13.00 90th_µs	        32.00 99th_µs	     877 B/op	      20 allocs/op
BenchmarkDB_WriteTxn_100_LPMIndex-4           	  681998	      1737 ns/op	    575635 objects/sec	    1671 B/op	      37 allocs/op
BenchmarkDB_WriteTxn_1_LPMIndex-4             	  173929	     12669 ns/op	     78930 objects/sec	   16010 B/op	      85 allocs/op
BenchmarkDB_LPMIndex_Get-4                    	     472	   2479459 ns/op	   4033139 objects/sec	       0 B/op	       0 allocs/op
BenchmarkWatchSet_4-4                         	 3192320	       370.8 ns/op	     296 B/op	       4 allocs/op
BenchmarkWatchSet_16-4                        	  899860	      1198 ns/op	    1096 B/op	       5 allocs/op
BenchmarkWatchSet_128-4                       	  111554	     10676 ns/op	    8904 B/op	       5 allocs/op
BenchmarkWatchSet_1024-4                      	    9987	    107926 ns/op	   73742 B/op	       5 allocs/op
PASS
ok  	github.com/cilium/statedb	43.655s
PASS
ok  	github.com/cilium/statedb/index	0.003s
goos: linux
goarch: amd64
pkg: github.com/cilium/statedb/internal
cpu: AMD EPYC 9V74 80-Core Processor                
Benchmark_SortableMutex-4   	 7449078	       161.2 ns/op	       0 B/op	       0 allocs/op
PASS
ok  	github.com/cilium/statedb/internal	1.204s
goos: linux
goarch: amd64
pkg: github.com/cilium/statedb/lpm
cpu: AMD EPYC 9V74 80-Core Processor                
Benchmark_txn_insert/batchSize=1-4         	    2556	    457484 ns/op	   2185869 objects/sec	  838425 B/op	   13975 allocs/op
Benchmark_txn_insert/batchSize=10-4        	    4333	    280074 ns/op	   3570490 objects/sec	  385202 B/op	    6668 allocs/op
Benchmark_txn_insert/batchSize=100-4       	    4627	    263176 ns/op	   3799741 objects/sec	  345619 B/op	    6027 allocs/op
Benchmark_txn_delete/batchSize=1-4         	    2041	    583285 ns/op	   1714427 objects/sec	 1286471 B/op	   13976 allocs/op
Benchmark_txn_delete/batchSize=10-4        	    4185	    296657 ns/op	   3370892 objects/sec	  372418 B/op	    5769 allocs/op
Benchmark_txn_delete/batchSize=100-4       	    4689	    254833 ns/op	   3924131 objects/sec	  286753 B/op	    5038 allocs/op
Benchmark_LPM_Lookup-4                     	    9981	    119122 ns/op	   8394780 objects/sec	       0 B/op	       0 allocs/op
Benchmark_LPM_All-4                        	  181165	      6611 ns/op	 151253084 objects/sec	      32 B/op	       1 allocs/op
Benchmark_LPM_Prefix-4                     	  172891	      6921 ns/op	 144484489 objects/sec	      32 B/op	       1 allocs/op
Benchmark_LPM_LowerBound-4                 	  321079	      3660 ns/op	 136613521 objects/sec	     288 B/op	       2 allocs/op
PASS
ok  	github.com/cilium/statedb/lpm	11.996s
goos: linux
goarch: amd64
pkg: github.com/cilium/statedb/part
cpu: AMD EPYC 9V74 80-Core Processor                
Benchmark_Uint64Map_Random-4                  	    2182	    553296 ns/op	   1807351 items/sec	 2424065 B/op	    6043 allocs/op
Benchmark_Uint64Map_Sequential-4              	    2610	    455972 ns/op	   2193119 items/sec	 2112690 B/op	    5753 allocs/op
Benchmark_Uint64Map_Sequential_Insert-4       	    2829	    420017 ns/op	   2380856 items/sec	 2104686 B/op	    4752 allocs/op
Benchmark_Uint64Map_Sequential_Txn_Insert-4   	   14948	     78653 ns/op	  12714023 items/sec	   86112 B/op	    2027 allocs/op
Benchmark_Uint64Map_Random_Insert-4           	    2188	    509897 ns/op	   1961179 items/sec	 2412209 B/op	    5030 allocs/op
Benchmark_Uint64Map_Random_Txn_Insert-4       	    9648	    123945 ns/op	   8068096 items/sec	  119964 B/op	    2420 allocs/op
Benchmark_Insert_RootOnlyWatch-4              	   15308	     78208 ns/op	  12786433 objects/sec	   71264 B/op	    2032 allocs/op
Benchmark_Insert-4                            	   12834	     93434 ns/op	  10702715 objects/sec	   79680 B/op	    3058 allocs/op
Benchmark_WatchReplace-4                      	   14048	     85508 ns/op	  11694872 objects/sec	   65345 B/op	    2011 allocs/op
Benchmark_Modify-4                            	   17642	     67968 ns/op	  14712764 objects/sec	   58120 B/op	    1007 allocs/op
Benchmark_GetInsert-4                         	   13785	     86969 ns/op	  11498301 objects/sec	   58120 B/op	    1007 allocs/op
Benchmark_Replace-4                           	44561740	        26.84 ns/op	  37261408 objects/sec	       0 B/op	       0 allocs/op
Benchmark_Replace_RootOnlyWatch-4             	44610747	        27.10 ns/op	  36898317 objects/sec	       0 B/op	       0 allocs/op
Benchmark_txn_1-4                             	 8928412	       133.6 ns/op	   7485641 objects/sec	      64 B/op	       3 allocs/op
Benchmark_txn_10-4                            	14962221	        79.57 ns/op	  12567865 objects/sec	      76 B/op	       2 allocs/op
Benchmark_txn_100-4                           	16871628	        70.18 ns/op	  14249830 objects/sec	      79 B/op	       2 allocs/op
Benchmark_txn_1000-4                          	14671488	        79.70 ns/op	  12547768 objects/sec	      65 B/op	       2 allocs/op
Benchmark_txn_delete_1-4                      	 7577736	       158.9 ns/op	   6291317 objects/sec	     632 B/op	       3 allocs/op
Benchmark_txn_delete_10-4                     	16349349	        72.51 ns/op	  13790563 objects/sec	     103 B/op	       1 allocs/op
Benchmark_txn_delete_100-4                    	17038371	        64.22 ns/op	  15571888 objects/sec	      47 B/op	       1 allocs/op
Benchmark_txn_delete_1000-4                   	20348007	        58.44 ns/op	  17112450 objects/sec	      24 B/op	       1 allocs/op
Benchmark_Get-4                               	   59886	     20164 ns/op	  49593639 objects/sec	       0 B/op	       0 allocs/op
Benchmark_GetWatch-4                          	   57576	     20859 ns/op	  47939952 objects/sec	       0 B/op	       0 allocs/op
Benchmark_All-4                               	  227210	      5550 ns/op	 180166195 objects/sec	       0 B/op	       0 allocs/op
Benchmark_Iterator_All-4                      	  205575	      5832 ns/op	 171481742 objects/sec	       0 B/op	       0 allocs/op
Benchmark_Iterator_Next-4                     	  196029	      6055 ns/op	 165152692 objects/sec	     896 B/op	       1 allocs/op
Benchmark_Hashmap_Insert-4                    	   22927	     52449 ns/op	  19066160 objects/sec	   74264 B/op	      20 allocs/op
Benchmark_Hashmap_Get_Uint64-4                	  198238	      6107 ns/op	 163740408 objects/sec	       0 B/op	       0 allocs/op
Benchmark_Hashmap_Get_Bytes-4                 	  162464	      7393 ns/op	 135256801 objects/sec	       0 B/op	       0 allocs/op
Benchmark_Delete_Random-4                     	     100	  10656220 ns/op	   9384190 objects/sec	 2111812 B/op	  102363 allocs/op
Benchmark_find16-4                            	292483246	         4.099 ns/op	       0 B/op	       0 allocs/op
Benchmark_findIndex16-4                       	100000000	        11.18 ns/op	       0 B/op	       0 allocs/op
Benchmark_find48-4                            	485319165	         2.461 ns/op	       0 B/op	       0 allocs/op
Benchmark_findIndex48_hit-4                   	549089155	         2.084 ns/op	       0 B/op	       0 allocs/op
Benchmark_findIndex48_miss-4                  	487581696	         2.461 ns/op	       0 B/op	       0 allocs/op
Benchmark_find4-4                             	545672948	         2.198 ns/op	       0 B/op	       0 allocs/op
Benchmark_findIndex4-4                        	399614042	         3.004 ns/op	       0 B/op	       0 allocs/op
PASS
ok  	github.com/cilium/statedb/part	44.810s
PASS
ok  	github.com/cilium/statedb/reconciler	0.004s
?   	github.com/cilium/statedb/reconciler/benchmark	[no test files]
?   	github.com/cilium/statedb/reconciler/example	[no test files]
go run ./reconciler/benchmark -quiet
1000000 objects reconciled in 1.44 seconds (batch size 1000)
Throughput 693928.90 objects per second
616MB total allocated, 6015096 in-use objects, 239MB bytes in use

Only allocate the watch channels when requested.

Split Tree and Txn Get/Prefix into no-watch defaults and
explicit GetWatch/PrefixWatch methods, and route ordinary StateDB
index operations through no-watch paths while preserving existing
watch invalidation semantics.

StateDB benchmarks:

goos: linux
goarch: arm64
pkg: github.com/cilium/statedb
                           │    a.txt     │               b.txt                │
                           │    sec/op    │    sec/op     vs base              │
DB_Modify-6                  570.2µ ± ∞ ¹   528.1µ ± ∞ ¹       ~ (p=0.095 n=5)
DB_GetInsert-6               633.9µ ± ∞ ¹   586.5µ ± ∞ ¹       ~ (p=0.095 n=5)
DB_RandomInsert-6            613.6µ ± ∞ ¹   515.3µ ± ∞ ¹       ~ (p=0.095 n=5)
DB_SequentialInsert-6        564.4µ ± ∞ ¹   501.2µ ± ∞ ¹       ~ (p=0.151 n=5)
DB_RandomLookup-6            34.62µ ± ∞ ¹   33.48µ ± ∞ ¹  -3.30% (p=0.016 n=5)
DB_SequentialLookup-6        27.89µ ± ∞ ¹   26.04µ ± ∞ ¹  -6.63% (p=0.008 n=5)
DB_Prefix_SecondaryIndex-6   112.2µ ± ∞ ¹   111.2µ ± ∞ ¹       ~ (p=0.151 n=5)
geomean                      201.7µ         186.2µ        -7.66%
¹ need >= 6 samples for confidence interval at level 0.95

                           │     a.txt     │                 b.txt                  │
                           │     B/op      │     B/op       vs base                 │
DB_Modify-6                  533.5Ki ± ∞ ¹   431.1Ki ± ∞ ¹  -19.18% (p=0.008 n=5)
DB_GetInsert-6               517.8Ki ± ∞ ¹   415.5Ki ± ∞ ¹  -19.76% (p=0.008 n=5)
DB_RandomInsert-6            509.9Ki ± ∞ ¹   407.7Ki ± ∞ ¹  -20.06% (p=0.008 n=5)
DB_SequentialInsert-6        509.9Ki ± ∞ ¹   407.7Ki ± ∞ ¹  -20.06% (p=0.008 n=5)
DB_RandomLookup-6              0.000 ± ∞ ¹     0.000 ± ∞ ¹        ~ (p=1.000 n=5) ²
DB_SequentialLookup-6          0.000 ± ∞ ¹     0.000 ± ∞ ¹        ~ (p=1.000 n=5) ²
DB_Prefix_SecondaryIndex-6   122.0Ki ± ∞ ¹   122.0Ki ± ∞ ¹   +0.03% (p=0.008 n=5)
geomean                                  ³                  -11.82%               ³
¹ need >= 6 samples for confidence interval at level 0.95
² all samples are equal
³ summaries must be >0 to compute geomean

Reconciler benchmark before (best of three runs):

1000000 objects reconciled in 1.35 seconds (batch size 1000)
Throughput 740668.25 objects per second
888MB total allocated, 6015187 in-use objects, 338MB bytes in use
2.00user 0.21system 0:01.50elapsed 147%CPU (0avgtext+0avgdata 617884maxresident)k
152inputs+0outputs (1major+203587minor)pagefaults 0swaps

Reconciler benchmark after (best of three runs):

1000000 objects reconciled in 1.32 seconds (batch size 1000)
Throughput 760075.67 objects per second
687MB total allocated, 6015138 in-use objects, 239MB bytes in use
2.17user 0.20system 0:01.45elapsed 162%CPU (0avgtext+0avgdata 475600maxresident)k
0inputs+0outputs (0major+136382minor)pagefaults 0swaps

AIL:3
Signed-off-by: Jussi Maki <jussi@isovalent.com>
Reconciliation status is committed before metrics are published, and
refresh jobs register their health nodes independently. Wait for both
states in the multi-reconciler test so it does not depend on goroutine
scheduling under the race detector.

AIL:3
Signed-off-by: Jussi Maki <jussi@isovalent.com>
Add a benchmark that replaces 1,000 values per committed transaction in a tree with per-node
watches. This exercises path cloning and watch notification collection.

AIL:3
Signed-off-by: Jussi Maki <jussi@isovalent.com>
Collect watch states in a slice instead of a map. Tree traversal visits
each cloned node once. Lazy watches may share a state across physical
nodes; closing a state is idempotent, so duplicates are safe. Clear
the slice before reuse so closed channels and their subtrees are
not retained.

goos: linux
goarch: arm64
pkg: github.com/cilium/statedb/part
                    │  before.txt  │              after.txt              │
                    │    sec/op    │   sec/op     vs base                │
_Insert-6              90.81µ ± 5%   87.97µ ± 2%        ~ (p=0.315 n=10)
PatchWatchReplace-6   142.30µ ± 8%   81.95µ ± 3%  -42.41% (p=0.000 n=10)

                    │ before.txt  │              after.txt               │
                    │ objects/sec │ objects/sec   vs base                │
_Insert-6             11.01M ± 5%    11.37M ± 2%        ~ (p=0.315 n=10)
PatchWatchReplace-6   7.030M ± 7%   12.202M ± 3%  +73.58% (p=0.000 n=10)

                    │  before.txt   │              after.txt               │
                    │     B/op      │     B/op      vs base                │
_Insert-6              78.66Ki ± 0%   77.81Ki ± 0%   -1.07% (p=0.000 n=10)
PatchWatchReplace-6   136.52Ki ± 0%   63.81Ki ± 0%  -53.26% (p=0.000 n=10)

                    │ before.txt  │             after.txt              │
                    │  allocs/op  │  allocs/op   vs base               │
_Insert-6             3.060k ± 0%   3.058k ± 0%  -0.07% (p=0.000 n=10)
PatchWatchReplace-6   2.033k ± 0%   2.011k ± 0%  -1.08% (p=0.000 n=10)

AIL:3
Signed-off-by: Jussi Maki <jussi@isovalent.com>
@joamaki
joamaki force-pushed the pr/joamaki/lazy-watches branch from 1084d0c to 8c26bd9 Compare August 25, 2026 09:59

@pippolo84 pippolo84 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✔️

@pippolo84
pippolo84 removed the request for review from derailed August 25, 2026 10:45
@joamaki
joamaki merged commit b597c01 into main Aug 25, 2026
1 check passed
@joamaki
joamaki deleted the pr/joamaki/lazy-watches branch August 25, 2026 11:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants