added query cache

This commit is contained in:
ston1th 2017-11-12 16:53:09 +01:00
commit a2e54b1f0e
2 changed files with 82 additions and 0 deletions

66
cache.go Normal file
View 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)
}

View file

@ -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)