Skip to content

Commit ed45a45

Browse files
committed
refactor(stacktrace): remove unnecessary locking from segmentPrefixTrie
The segmentPrefixTrie follows a write-once-read-many pattern where all writes occur during package initialization before any concurrent access. After initialization, the trie is effectively immutable and can be safely read by multiple goroutines without synchronization overhead.
1 parent 19fa72c commit ed45a45

File tree

1 file changed

+15
-20
lines changed

1 file changed

+15
-20
lines changed

internal/stacktrace/trie.go

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,14 @@ func (t *prefixTrie) Clear() {
145145
// segmentPrefixTrie is a path segment-based trie optimized for "/" delimited paths.
146146
// It stores path segments (e.g., "github.com", "DataDog") as nodes instead of individual characters,
147147
// providing better memory efficiency and potentially faster lookups for module paths.
148+
//
149+
// Concurrency: This trie follows a write-once-read-many (WORM) pattern where all writes
150+
// occur during package initialization (init function) before any concurrent access begins.
151+
// After initialization, the trie is effectively immutable and can be safely read by multiple
152+
// goroutines without synchronization.
148153
type segmentPrefixTrie struct {
149154
root *segmentTrieNode
150-
mu sync.RWMutex
155+
// No mutex needed - structure is immutable after init()
151156
}
152157

153158
// segmentTrieNode represents a single path segment node in the trie
@@ -165,15 +170,13 @@ func newSegmentPrefixTrie() *segmentPrefixTrie {
165170
}
166171
}
167172

168-
// Insert adds a prefix to the segment trie
173+
// Insert adds a prefix to the segment trie.
174+
// This method should only be called during initialization before any concurrent access.
169175
func (t *segmentPrefixTrie) Insert(prefix string) {
170176
if prefix == "" {
171177
return
172178
}
173179

174-
t.mu.Lock()
175-
defer t.mu.Unlock()
176-
177180
node := t.root
178181
start := 0
179182

@@ -197,14 +200,12 @@ func (t *segmentPrefixTrie) Insert(prefix string) {
197200
}
198201

199202
// HasPrefix checks if the given string has any of the prefixes stored in the segment trie.
203+
// Safe for concurrent use after initialization.
200204
func (t *segmentPrefixTrie) HasPrefix(s string) (found bool) {
201205
if s == "" {
202206
return false
203207
}
204208

205-
t.mu.RLock()
206-
defer t.mu.RUnlock()
207-
208209
node := t.root
209210
start := 0
210211

@@ -230,11 +231,9 @@ func (t *segmentPrefixTrie) HasPrefix(s string) (found bool) {
230231
return node.isEnd
231232
}
232233

233-
// InsertAll adds multiple prefixes to the segment trie in a single operation
234+
// InsertAll adds multiple prefixes to the segment trie in a single operation.
235+
// This method should only be called during initialization before any concurrent access.
234236
func (t *segmentPrefixTrie) InsertAll(prefixes []string) {
235-
t.mu.Lock()
236-
defer t.mu.Unlock()
237-
238237
for _, prefix := range prefixes {
239238
if prefix == "" {
240239
continue
@@ -263,11 +262,9 @@ func (t *segmentPrefixTrie) InsertAll(prefixes []string) {
263262
}
264263
}
265264

266-
// Size returns the number of prefixes stored in the segment trie
265+
// Size returns the number of prefixes stored in the segment trie.
266+
// Safe for concurrent use after initialization.
267267
func (t *segmentPrefixTrie) Size() int {
268-
t.mu.RLock()
269-
defer t.mu.RUnlock()
270-
271268
return t.countSegmentPrefixes(t.root)
272269
}
273270

@@ -289,11 +286,9 @@ func (t *segmentPrefixTrie) countSegmentPrefixes(node *segmentTrieNode) int {
289286
return count
290287
}
291288

292-
// Clear removes all prefixes from the segment trie
289+
// Clear removes all prefixes from the segment trie.
290+
// This method should only be called during initialization before any concurrent access.
293291
func (t *segmentPrefixTrie) Clear() {
294-
t.mu.Lock()
295-
defer t.mu.Unlock()
296-
297292
t.root = &segmentTrieNode{
298293
children: make(map[string]*segmentTrieNode),
299294
}

0 commit comments

Comments
 (0)