added query cache
This commit is contained in:
parent
0e2b25e788
commit
a2e54b1f0e
2 changed files with 82 additions and 0 deletions
66
cache.go
Normal file
66
cache.go
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
// Copyright (C) 2017 Marius Schellenberger
|
||||
|
||||
package filter
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// QueryCache can be used to cache queries
|
||||
type QueryCache struct {
|
||||
// protects m
|
||||
sync.RWMutex
|
||||
|
||||
m map[string]Query
|
||||
max int
|
||||
}
|
||||
|
||||
// NewQueryCache returns a new QueryCache
|
||||
func NewQueryCache(max int) *QueryCache {
|
||||
return &QueryCache{
|
||||
m: make(map[string]Query),
|
||||
max: max,
|
||||
}
|
||||
}
|
||||
|
||||
// NewQuery looks for the given query in the cache and returns it.
|
||||
// If the query is not found it will be generated and inserted in the cache..
|
||||
func (qc *QueryCache) NewQuery(s string) (q *Query, err error) {
|
||||
q = qc.lookup(s)
|
||||
if q != nil {
|
||||
return
|
||||
}
|
||||
q, err = NewQuery(s)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
qc.Lock()
|
||||
defer qc.Unlock()
|
||||
if len(qc.m) == qc.max {
|
||||
qc.clean()
|
||||
}
|
||||
qc.m[s] = *q
|
||||
return
|
||||
}
|
||||
|
||||
func (qc *QueryCache) lookup(s string) *Query {
|
||||
qc.RLock()
|
||||
defer qc.RUnlock()
|
||||
if q, ok := qc.m[s]; ok {
|
||||
return &q
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (qc *QueryCache) clean() {
|
||||
i := rand.Intn(len(qc.m))
|
||||
var k string
|
||||
for k = range qc.m {
|
||||
if i == 0 {
|
||||
break
|
||||
}
|
||||
i--
|
||||
}
|
||||
delete(qc.m, k)
|
||||
}
|
||||
|
|
@ -275,6 +275,14 @@ func BenchmarkNewQueryComplexOr(b *testing.B) {
|
|||
}
|
||||
}
|
||||
|
||||
func BenchmarkNewQueryCacheComplexOr(b *testing.B) {
|
||||
c := NewQueryCache(1)
|
||||
b.ReportAllocs()
|
||||
for i := 0; i < b.N; i++ {
|
||||
c.NewQuery(compOr)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkNewQuerySort(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
for i := 0; i < b.N; i++ {
|
||||
|
|
@ -303,6 +311,14 @@ func BenchmarkNewQuerySortComplexOr(b *testing.B) {
|
|||
}
|
||||
}
|
||||
|
||||
func BenchmarkNewQueryCacheSortComplexOr(b *testing.B) {
|
||||
c := NewQueryCache(1)
|
||||
b.ReportAllocs()
|
||||
for i := 0; i < b.N; i++ {
|
||||
c.NewQuery(compOrSort)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFilterSimple(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
q, err := NewQuery(simple)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue