Skip to content

Commit 1f0931c

Browse files
authored
Drop pool (#39)
1 parent ebf9b7a commit 1f0931c

File tree

3 files changed

+22
-72
lines changed

3 files changed

+22
-72
lines changed

api.go

+6-37
Original file line numberDiff line numberDiff line change
@@ -21,29 +21,6 @@ type Issue struct {
2121
DuplicatePos token.Position
2222
}
2323

24-
// IssuePool provides a pool of Issue slices to reduce allocations
25-
var IssuePool = sync.Pool{
26-
New: func() interface{} {
27-
return make([]Issue, 0, 100)
28-
},
29-
}
30-
31-
// GetIssueBuffer retrieves an Issue slice from the pool
32-
func GetIssueBuffer() []Issue {
33-
return IssuePool.Get().([]Issue)[:0] // Reset length but keep capacity
34-
}
35-
36-
// PutIssueBuffer returns an Issue slice to the pool
37-
func PutIssueBuffer(issues []Issue) {
38-
// Make sure to clear references before returning to pool
39-
for i := range issues {
40-
issues[i].MatchingConst = ""
41-
issues[i].Str = ""
42-
}
43-
// Return the slice to the pool
44-
IssuePool.Put(make([]Issue, 0, cap(issues))) //nolint:staticcheck
45-
}
46-
4724
// Config contains all configuration options for the goconst analyzer.
4825
type Config struct {
4926
// IgnoreStrings is a list of regular expressions to filter strings
@@ -137,13 +114,8 @@ func RunWithConfig(files []*ast.File, fset *token.FileSet, typeInfo *types.Info,
137114
expectedIssues = 1000 // Cap at reasonable maximum
138115
}
139116

140-
// Get issue buffer from pool instead of allocating
141-
issueBuffer := GetIssueBuffer()
142-
if cap(issueBuffer) < expectedIssues {
143-
// Only allocate new buffer if existing one is too small
144-
PutIssueBuffer(issueBuffer)
145-
issueBuffer = make([]Issue, 0, expectedIssues)
146-
}
117+
// Allocate a new buffer
118+
issueBuffer := make([]Issue, 0, expectedIssues)
147119

148120
// Process files concurrently
149121
var wg sync.WaitGroup
@@ -195,8 +167,8 @@ func RunWithConfig(files []*ast.File, fset *token.FileSet, typeInfo *types.Info,
195167
p.stringMutex.RLock()
196168
p.stringCountMutex.RLock()
197169

198-
// Get a string buffer from pool instead of allocating
199-
stringKeys := GetStringBuffer()
170+
// Create a slice to hold the string keys
171+
stringKeys := make([]string, 0, len(p.strs))
200172

201173
// Create an array of strings to sort for stable output
202174
for str := range p.strs {
@@ -243,8 +215,8 @@ func RunWithConfig(files []*ast.File, fset *token.FileSet, typeInfo *types.Info,
243215
// process duplicate constants
244216
p.constMutex.RLock()
245217

246-
// reuse string buffer for const keys
247-
stringKeys = stringKeys[:0]
218+
// Create a new slice for const keys
219+
stringKeys = make([]string, 0, len(p.consts))
248220

249221
// Create an array of strings and sort for stable output
250222
for str := range p.consts {
@@ -271,9 +243,6 @@ func RunWithConfig(files []*ast.File, fset *token.FileSet, typeInfo *types.Info,
271243

272244
p.constMutex.RUnlock()
273245

274-
// Return string buffer to pool
275-
PutStringBuffer(stringKeys)
276-
277246
// Don't return the buffer to pool as the caller now owns it
278247
return issueBuffer, nil
279248
}

api_test.go

-5
Original file line numberDiff line numberDiff line change
@@ -562,8 +562,3 @@ func checker(fset *token.FileSet) (*types.Checker, *types.Info) {
562562
}
563563
return types.NewChecker(cfg, fset, types.NewPackage("", "example"), info), info
564564
}
565-
566-
func Test_IssuePool(t *testing.T) {
567-
PutIssueBuffer([]Issue{})
568-
GetIssueBuffer()
569-
}

parser.go

+16-30
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,6 @@ var ByteBufferPool = sync.Pool{
4646
},
4747
}
4848

49-
// StringBufferPool is a pool for string slices
50-
var StringBufferPool = sync.Pool{
51-
New: func() interface{} {
52-
slice := make([]string, 0, 32)
53-
return &slice
54-
},
55-
}
56-
5749
// ExtendedPosPool is a pool for slices of ExtendedPos
5850
var ExtendedPosPool = sync.Pool{
5951
New: func() interface{} {
@@ -103,17 +95,6 @@ func PutByteBuffer(buf []byte) {
10395
ByteBufferPool.Put(&bufCopy)
10496
}
10597

106-
// GetStringBuffer retrieves a string slice from the pool
107-
func GetStringBuffer() []string {
108-
return (*StringBufferPool.Get().(*[]string))[:0] // Reset length but keep capacity
109-
}
110-
111-
// PutStringBuffer returns a string slice to the pool
112-
func PutStringBuffer(slice []string) {
113-
sliceCopy := make([]string, 0, cap(slice))
114-
StringBufferPool.Put(&sliceCopy)
115-
}
116-
11798
// GetExtendedPosBuffer retrieves an ExtendedPos slice from the pool
11899
func GetExtendedPosBuffer() []ExtendedPos {
119100
return (*ExtendedPosPool.Get().(*[]ExtendedPos))[:0] // Reset length but keep capacity
@@ -466,16 +447,19 @@ func (p *Parser) parseConcurrently(filesChan <-chan string) (*token.FileSet, map
466447

467448
parsedFilesChan := make(chan parsedFile, chanSize)
468449

450+
// Add all workers to the WaitGroup before starting any goroutines
451+
// This prevents a race condition with the goroutine that waits
452+
parserWg.Add(p.maxConcurrency)
453+
454+
// Start a separate goroutine to close the channel after all parsers are done
455+
go func() {
456+
parserWg.Wait()
457+
close(parsedFilesChan)
458+
}()
459+
469460
for i := 0; i < p.maxConcurrency; i++ {
470-
parserWg.Add(1)
471-
go func(id int) {
472-
defer func() {
473-
parserWg.Done()
474-
if id == 0 { // first worker waits and closes the sending channel
475-
parserWg.Wait()
476-
close(parsedFilesChan)
477-
}
478-
}()
461+
go func() {
462+
defer parserWg.Done()
479463

480464
for filePath := range filesChan {
481465
// Parse a single file
@@ -495,7 +479,7 @@ func (p *Parser) parseConcurrently(filesChan <-chan string) (*token.FileSet, map
495479
pkgName := f.Name.Name
496480
parsedFilesChan <- parsedFile{pkgName, f}
497481
}
498-
}(i)
482+
}()
499483
}
500484

501485
// Read all parsed files into packgageFiles map. All packages must be parsed prior to type-checking.
@@ -526,8 +510,10 @@ func (p *Parser) visitConcurrently(fset *token.FileSet, info *types.Info, filesB
526510

527511
parsedFilesChan := make(chan parsedFile, chanSize)
528512

513+
// Add all workers to the WaitGroup before starting any goroutines
514+
visitorWg.Add(p.maxConcurrency)
515+
529516
for i := 0; i < p.maxConcurrency; i++ {
530-
visitorWg.Add(1)
531517
go func() {
532518
defer visitorWg.Done()
533519
for pf := range parsedFilesChan {

0 commit comments

Comments
 (0)