diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-27 08:10:40 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-27 08:10:40 +0300 |
| commit | 987ba21a5ff69b82bd56012866634cabf6670194 (patch) | |
| tree | 7d4259ac5a18da44b32819736f16c902cd5ef760 /internal | |
| parent | 9b6be4cf0fcaf6426886c2a0ecf55f06965f1a3f (diff) | |
flamegraph: reduce AddRecord lock contention (6p)
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/flamegraph/livetrie.go | 52 |
1 files changed, 34 insertions, 18 deletions
diff --git a/internal/flamegraph/livetrie.go b/internal/flamegraph/livetrie.go index 4554780..188ba6a 100644 --- a/internal/flamegraph/livetrie.go +++ b/internal/flamegraph/livetrie.go @@ -100,28 +100,44 @@ func (lt *LiveTrie) Ingest(ep *event.Pair) { lt.AddRecord(record) } +func (lt *LiveTrie) addRecordConfig() ([]string, string, string) { + lt.mu.RLock() + fields := slices.Clone(lt.fields) + countField := lt.countField + heightField := lt.heightField + lt.mu.RUnlock() + return fields, countField, heightField +} + // AddRecord adds one already-decoded flamegraph record into the live trie. func (lt *LiveTrie) AddRecord(record IterRecord) { - lt.mu.Lock() + for { + fields, countField, heightField := lt.addRecordConfig() - value, err := record.Cnt.ValueByName(lt.countField) - if err != nil { - lt.mu.Unlock() - return - } - heightValue := uint64(0) - if lt.heightField != "" { - heightValue, err = record.Cnt.ValueByName(lt.heightField) + value, err := record.Cnt.ValueByName(countField) if err != nil { - lt.mu.Unlock() return } - } + heightValue := uint64(0) + if heightField != "" { + heightValue, err = record.Cnt.ValueByName(heightField) + if err != nil { + return + } + } - frames := lt.buildFrames(record) - lt.addLocked(frames, value, heightValue) - lt.version.Add(1) - lt.mu.Unlock() + frames := buildFrames(record, fields) + + lt.mu.Lock() + if countField != lt.countField || heightField != lt.heightField || !slices.Equal(fields, lt.fields) { + lt.mu.Unlock() + continue + } + lt.addLocked(frames, value, heightValue) + lt.version.Add(1) + lt.mu.Unlock() + return + } } // Reset clears the trie so live snapshots start from a new baseline. @@ -292,9 +308,9 @@ func eventPairToRecord(ep *event.Pair) IterRecord { } } -func (lt *LiveTrie) buildFrames(record IterRecord) []string { - frames := make([]string, 0, len(lt.fields)) - for _, fieldName := range lt.fields { +func buildFrames(record IterRecord, fields []string) []string { + frames := make([]string, 0, len(fields)) + for _, fieldName := range fields { value, err := record.StringByName(fieldName) if err != nil { continue |
