Просмотр исходного кода

Merge pull request #814 from i/iml.rlock

Use RWMutex in prepared statement cache
Chris Bannister 9 лет назад
Родитель
Сommit
3d6a7fbdbd
2 измененных файлов с 31 добавлено и 4 удалено
  1. 9 4
      prepared_cache.go
  2. 22 0
      prepared_cache_test.go

+ 9 - 4
prepared_cache.go

@@ -9,7 +9,7 @@ const defaultMaxPreparedStmts = 1000
 
 // preparedLRU is the prepared statement cache
 type preparedLRU struct {
-	mu  sync.Mutex
+	mu  sync.RWMutex
 	lru *lru.Cache
 }
 
@@ -47,14 +47,19 @@ func (p *preparedLRU) remove(key string) bool {
 }
 
 func (p *preparedLRU) execIfMissing(key string, fn func(lru *lru.Cache) *inflightPrepare) (*inflightPrepare, bool) {
-	p.mu.Lock()
-	defer p.mu.Unlock()
-
+	p.mu.RLock()
 	val, ok := p.lru.Get(key)
+	p.mu.RUnlock()
+
 	if ok {
 		return val.(*inflightPrepare), true
 	}
 
+	p.mu.Lock()
+	defer p.mu.Unlock()
+	if val, ok := p.lru.Get(key); ok {
+		return val.(*inflightPrepare), true
+	}
 	return fn(p.lru), false
 }
 

+ 22 - 0
prepared_cache_test.go

@@ -0,0 +1,22 @@
+package gocql
+
+import (
+	"testing"
+
+	"github.com/gocql/gocql/internal/lru"
+)
+
+func BenchmarkLRU(b *testing.B) {
+	pl := preparedLRU{
+		lru: lru.New(10),
+	}
+
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			pl.execIfMissing("foo", func(c *lru.Cache) *inflightPrepare {
+				c.Add("foo", (*inflightPrepare)(nil))
+				return nil
+			})
+		}
+	})
+}