Skip to content

Commit cdfb293

Browse files
authored
Small aggregation perf improvements (#1781)
* skip test on old * Cheaper error and collation checks * fixup test
1 parent 86e4e4a commit cdfb293

File tree

5 files changed

+32
-17
lines changed

5 files changed

+32
-17
lines changed

sql/cache.go

+4-5
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import (
2121
"github.com/cespare/xxhash"
2222

2323
lru "github.com/hashicorp/golang-lru"
24-
errors "gopkg.in/src-d/go-errors.v1"
2524
)
2625

2726
// HashOf returns a hash of the given value to be used as key in a cache.
@@ -37,7 +36,7 @@ func HashOf(v Row) (uint64, error) {
3736
}
3837

3938
// ErrKeyNotFound is returned when the key could not be found in the cache.
40-
var ErrKeyNotFound = errors.NewKind("memory: key %d not found in cache")
39+
var ErrKeyNotFound = fmt.Errorf("memory: key not found in cache")
4140

4241
type lruCache struct {
4342
memory Freeable
@@ -65,7 +64,7 @@ func (l *lruCache) Put(k uint64, v interface{}) error {
6564
func (l *lruCache) Get(k uint64) (interface{}, error) {
6665
v, ok := l.cache.Get(k)
6766
if !ok {
68-
return nil, ErrKeyNotFound.New(k)
67+
return nil, ErrKeyNotFound
6968
}
7069

7170
return v, nil
@@ -133,7 +132,7 @@ func (m mapCache) Put(u uint64, i interface{}) error {
133132
func (m mapCache) Get(u uint64) (interface{}, error) {
134133
v, ok := m.cache[u]
135134
if !ok {
136-
return nil, ErrKeyNotFound.New(u)
135+
return nil, ErrKeyNotFound
137136
}
138137
return v, nil
139138
}
@@ -173,7 +172,7 @@ func (h *historyCache) Put(k uint64, v interface{}) error {
173172
func (h *historyCache) Get(k uint64) (interface{}, error) {
174173
v, ok := h.cache[k]
175174
if !ok {
176-
return nil, ErrKeyNotFound.New(k)
175+
return nil, ErrKeyNotFound
177176
}
178177
return v, nil
179178
}

sql/cache_test.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package sql
1616

1717
import (
18+
"errors"
1819
"testing"
1920

2021
"github.com/stretchr/testify/require"
@@ -33,14 +34,14 @@ func TestLRUCache(t *testing.T) {
3334

3435
_, err = cache.Get(2)
3536
require.Error(err)
36-
require.True(ErrKeyNotFound.Is(err))
37+
require.True(errors.Is(err, ErrKeyNotFound))
3738

3839
// Free the cache and check previous entry disappeared.
3940
cache.Free()
4041

4142
_, err = cache.Get(1)
4243
require.Error(err)
43-
require.True(ErrKeyNotFound.Is(err))
44+
require.True(errors.Is(err, ErrKeyNotFound))
4445

4546
cache.Dispose()
4647
require.Panics(func() {
@@ -55,7 +56,7 @@ func TestLRUCache(t *testing.T) {
5556
require.NoError(cache.Put(1, "foo"))
5657
_, err := cache.Get(1)
5758
require.Error(err)
58-
require.True(ErrKeyNotFound.Is(err))
59+
require.True(errors.Is(err, ErrKeyNotFound))
5960
})
6061

6162
t.Run("free required to add entry", func(t *testing.T) {
@@ -94,7 +95,7 @@ func TestHistoryCache(t *testing.T) {
9495

9596
_, err = cache.Get(2)
9697
require.Error(err)
97-
require.True(ErrKeyNotFound.Is(err))
98+
require.True(errors.Is(err, ErrKeyNotFound))
9899

99100
cache.Dispose()
100101
require.Panics(func() {

sql/collations.go

+19-6
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"fmt"
1919
"io"
2020
"strings"
21+
"sync"
2122
"unicode/utf8"
2223

2324
"github.com/cespare/xxhash"
@@ -851,6 +852,12 @@ func (c CollationID) Collation() Collation {
851852
return collationArray[c]
852853
}
853854

855+
var weightBuffers = sync.Pool{
856+
New: func() interface{} {
857+
return new([]byte)
858+
},
859+
}
860+
854861
// WriteWeightString writes the weights of each codepoint in the string into the given io.Writer.
855862
// Two strings with technically different contents may generate the same WeightString to the same value, as the collation
856863
// considers them the same string.
@@ -863,24 +870,30 @@ func (c CollationID) WriteWeightString(hash io.Writer, str string) error {
863870
}
864871
} else {
865872
getRuneWeight := collationArray[c].Sorter
873+
i := 0
874+
buf := *weightBuffers.Get().(*[]byte)
875+
if cap(buf) < len(str)*4 {
876+
buf = make([]byte, len(str)*4)
877+
}
866878
for len(str) > 0 {
867879
// All strings (should) have been decoded at this point, so we can rely on Go's internal string encoding
868880
runeFromString, strRead := utf8.DecodeRuneInString(str)
869881
if strRead == 0 || strRead == utf8.RuneError {
870882
return ErrCollationMalformedString.New("hashing")
871883
}
872884
runeWeight := getRuneWeight(runeFromString)
873-
_, err := hash.Write([]byte{
874-
byte(runeWeight),
875-
byte(runeWeight >> 8),
876-
byte(runeWeight >> 16),
877-
byte(runeWeight >> 24),
878-
})
885+
buf[i*4] = byte(runeWeight)
886+
buf[i*4+1] = byte(runeWeight >> 8)
887+
buf[i*4+2] = byte(runeWeight >> 16)
888+
buf[i*4+3] = byte(runeWeight >> 24)
889+
_, err := hash.Write(buf[i*4 : i*4+4])
879890
if err != nil {
880891
return err
881892
}
882893
str = str[strRead:]
894+
i++
883895
}
896+
weightBuffers.Put(&buf)
884897
}
885898
return nil
886899
}

sql/rowexec/agg.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package rowexec
1616

1717
import (
18+
"errors"
1819
"fmt"
1920
"io"
2021

@@ -162,7 +163,7 @@ func (i *groupByGroupingIter) compute(ctx *sql.Context) error {
162163
}
163164

164165
b, err := i.get(key)
165-
if sql.ErrKeyNotFound.Is(err) {
166+
if errors.Is(err, sql.ErrKeyNotFound) {
166167
b = make([]sql.AggregationBuffer, len(i.selectedExprs))
167168
for j, a := range i.selectedExprs {
168169
b[j], err = newAggregationBuffer(a)

sql/rowexec/update.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package rowexec
1616

1717
import (
18+
"errors"
1819
"fmt"
1920

2021
"github.com/dolthub/go-mysql-server/sql"
@@ -209,7 +210,7 @@ func (u *updateJoinIter) Next(ctx *sql.Context) (sql.Row, error) {
209210
}
210211

211212
_, err = cache.Get(hash)
212-
if sql.ErrKeyNotFound.Is(err) {
213+
if errors.Is(err, sql.ErrKeyNotFound) {
213214
cache.Put(hash, struct{}{})
214215
continue
215216
} else if err != nil {

0 commit comments

Comments
 (0)