Skip to content

Commit 14ca72f

Browse files
committed
avoid memory leak; add test for zero allocations for Compare calls
1 parent 7e21e25 commit 14ca72f

File tree

2 files changed

+37
-6
lines changed

2 files changed

+37
-6
lines changed

collate/collate.go

+10-6
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,12 @@ func (b *Buffer) Reset() {
108108
// a new buffer will be allocated for each call.
109109
func (c *Collator) Compare(a, b []byte) int {
110110
var (
111-
kA = c.Key(&c.buf, a)
112-
kB = c.Key(&c.buf, b)
111+
kA = c.Key(&c.buf, a)
112+
kB = c.Key(&c.buf, b)
113+
ret = bytes.Compare(kA, kB)
113114
)
114-
return bytes.Compare(kA, kB)
115+
c.buf.Reset()
116+
return ret
115117
}
116118

117119
// CompareString returns an integer comparing the two strings.
@@ -120,10 +122,12 @@ func (c *Collator) Compare(a, b []byte) int {
120122
// a new buffer will be allocated for each call.
121123
func (c *Collator) CompareString(a, b string) int {
122124
var (
123-
kA = c.KeyFromString(&c.buf, a)
124-
kB = c.KeyFromString(&c.buf, b)
125+
kA = c.KeyFromString(&c.buf, a)
126+
kB = c.KeyFromString(&c.buf, b)
127+
ret = bytes.Compare(kA, kB)
125128
)
126-
return bytes.Compare(kA, kB)
129+
c.buf.Reset()
130+
return ret
127131
}
128132

129133
// Key returns the collation key for str.

collate/collate_test.go

+27
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package collate
66

77
import (
88
"bytes"
9+
"runtime"
910
"testing"
1011

1112
"golang.org/x/text/internal/colltab"
@@ -470,6 +471,32 @@ func TestKeyFromStringCompareForShiftTrimmed(t *testing.T) {
470471
}
471472
}
472473

474+
func totalAllocs() uint64 {
475+
var mem runtime.MemStats
476+
runtime.ReadMemStats(&mem)
477+
return mem.TotalAlloc
478+
}
479+
480+
func TestNoAllocationsForCompares(t *testing.T) {
481+
var a = []byte("foo")
482+
var b = []byte("bar")
483+
var c = New(language.MustParse("en-us-u-ka-posix-ks-level4"))
484+
var before = totalAllocs()
485+
486+
for i := 0; i < 100; i++ {
487+
c.CompareString("foo", "bar")
488+
c.Compare(a, b)
489+
}
490+
491+
var bytesAllocated = totalAllocs() - before
492+
493+
// We should allocate zero additional bytes b/c the Buffer has 4k of memory pre-allocated that
494+
// we should re-use for each/every key we generate for the comparisons.
495+
if bytesAllocated != 0 {
496+
t.Errorf("Expected CompareStrings to not allocate memory but it allocated %v", bytesAllocated)
497+
}
498+
}
499+
473500
func TestNumeric(t *testing.T) {
474501
c := New(language.English, Loose, Numeric)
475502

0 commit comments

Comments
 (0)