From 1ac8a617ae9c26bdf2214fef0b5d541e1159e13f Mon Sep 17 00:00:00 2001 From: tamirms Date: Fri, 25 Sep 2026 14:52:01 -0400 Subject: [PATCH] events, deps: memory-map the cold MPHF, and roaring v2.26.0 Each cold events read opened its chunk's index.hash by reading the whole file into memory. It now memory-maps the file instead. The pages come from the kernel's page cache, which every reader of the chunk shares, so an open costs a map plus the pages its lookups touch, rather than a copy of a file that grows with the chunk's term count. roaring moves from v2.18.2 to v2.26.0, which adds vectorized container kernels. Its serialized form is roaring's portable format, so existing artifacts read the same. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01QHnF5BhsuoxpWxGmatQzmt --- .../rpcv2/stores/event/cold_format.go | 25 +++++++------------ go.mod | 9 ++++--- go.sum | 8 +++--- 3 files changed, 18 insertions(+), 24 deletions(-) diff --git a/cmd/stellar-rpc/internal/rpcv2/stores/event/cold_format.go b/cmd/stellar-rpc/internal/rpcv2/stores/event/cold_format.go index 956b9ac90..1b646fe08 100644 --- a/cmd/stellar-rpc/internal/rpcv2/stores/event/cold_format.go +++ b/cmd/stellar-rpc/internal/rpcv2/stores/event/cold_format.go @@ -453,24 +453,17 @@ func buildMPHF( // /index.hash produced by an earlier buildMPHF) for // query-time lookups. // -// The file is read into memory up-front via os.ReadFile + -// streamhash.OpenBytes rather than mmapped. Rationale: a typical -// MPHF for a single Chunk is small (~hundreds of KB at production -// term counts), and on storage with expensive random IOPS (e.g. -// EBS, ~1 ms each) mmap page-faults on cold Lookups cost more than -// a single sequential read amortized across the index's lifetime. +// The file is mmapped rather than read whole. Pages fault in from the kernel +// page cache, which every reader of the same chunk shares regardless of its +// own lifetime, so a per-request open costs a map and unmap plus the pages +// its lookups touch, not a copy of a file whose size scales with the chunk's +// term count. // -// Close on the returned handle is a no-op for the OpenBytes path -// (streamhash holds no fd / mmap), but callers should still call it -// for symmetry with other open variants. +// Close unmaps; callers must call it. func openMPHF(path string) (*mphf, error) { - data, err := os.ReadFile(path) + idx, err := streamhash.Open(path) if err != nil { - return nil, fmt.Errorf("events: read %s: %w", path, err) - } - idx, err := streamhash.OpenBytes(data) - if err != nil { - return nil, fmt.Errorf("events: parse %s: %w", path, err) + return nil, fmt.Errorf("events: open %s: %w", path, err) } secret, merr := decodeEventsMeta(idx.UserMetadata()) if merr != nil { @@ -516,7 +509,7 @@ func (m *mphf) Lookup(key TermKey) (uint32, [IndexRecordFingerprintLen]byte, err return uint32(slot), fp, nil } -// Close releases the index; a no-op for the in-memory OpenBytes path. +// Close unmaps the index file; callers must call it (see openMPHF). func (m *mphf) Close() error { return m.idx.Close() } diff --git a/go.mod b/go.mod index 2869bfe87..0c99d8104 100644 --- a/go.mod +++ b/go.mod @@ -4,9 +4,10 @@ go 1.26.0 require ( github.com/Masterminds/squirrel v1.5.4 - // Minimum v2.18.2: first upstream release with the FastOr/runContainer16 - // fix (RoaringBitmap/roaring#527) that the fork previously carried. - github.com/RoaringBitmap/roaring/v2 v2.18.2 + // v2.18.2 is the minimum (the FastOr/runContainer16 fix, #527). + // v2.26.0 adds vectorized container kernels behind x/sys/cpu and + // GODEBUG gates; the aggregation layer is unchanged since v2.18. + github.com/RoaringBitmap/roaring/v2 v2.26.0 github.com/aws/aws-sdk-go-v2 v1.45.1 github.com/aws/aws-sdk-go-v2/config v1.31.16 github.com/aws/aws-sdk-go-v2/service/s3 v1.110.0 @@ -61,7 +62,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/sso v1.30.0 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.4 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.39.0 // indirect - github.com/bits-and-blooms/bitset v1.24.2 // indirect + github.com/bits-and-blooms/bitset v1.24.4 // indirect github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 // indirect github.com/edsrzf/mmap-go v1.2.0 // indirect github.com/envoyproxy/go-control-plane/envoy v1.37.0 // indirect diff --git a/go.sum b/go.sum index b8a522c92..a88e1b7de 100644 --- a/go.sum +++ b/go.sum @@ -42,8 +42,8 @@ github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8 github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/RoaringBitmap/roaring/v2 v2.18.2 h1:oPq3Cgx//iDuJQVp6xSInAKW34J9CEwE5GmLI2z+Eic= -github.com/RoaringBitmap/roaring/v2 v2.18.2/go.mod h1:eq4wdNXxtJIS/oikeCzdX1rBzek7ANzbth041hrU8Q4= +github.com/RoaringBitmap/roaring/v2 v2.26.0 h1:K30ZxF4vZcIKvJsbmgfiep2K64f+dILJqkYGoj4xnwU= +github.com/RoaringBitmap/roaring/v2 v2.26.0/go.mod h1:BZufmFbox589n3j5eOmyTaLSGXbRLc2LmQvjKjzSEGU= github.com/ajg/form v0.0.0-20160822230020-523a5da1a92f h1:zvClvFQwU++UpIUBGC8YmDlfhUrweEy1R1Fj1gu5iIM= github.com/ajg/form v0.0.0-20160822230020-523a5da1a92f/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= @@ -94,8 +94,8 @@ github.com/aws/smithy-go v1.28.1 h1:R/nXH00c8qcfCzQVELtRw+eLQWtzv+VAIEFJ1/xxXlQ= github.com/aws/smithy-go v1.28.1/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bits-and-blooms/bitset v1.24.2 h1:M7/NzVbsytmtfHbumG+K2bremQPMJuqv1JD3vOaFxp0= -github.com/bits-and-blooms/bitset v1.24.2/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bits-and-blooms/bitset v1.24.4 h1:95H15Og1clikBrKr/DuzMXkQzECs1M6hhoGXLwLQOZE= +github.com/bits-and-blooms/bitset v1.24.4/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/caarlos0/env/v11 v11.4.1 h1:fYwH0sWEsBSMPG7t4e/PEfTFzrWrpjyygXyUnWiSwEw= github.com/caarlos0/env/v11 v11.4.1/go.mod h1:qupehSf/Y0TUTsxKywqRt/vJjN5nz6vauiYEUUr8P4U= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=