@@ -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.
148153type 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.
169175func (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.
200204func (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.
234236func (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.
267267func (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.
293291func (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