prepared_cache.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. package gocql
  2. import (
  3. "github.com/gocql/gocql/internal/lru"
  4. "sync"
  5. )
  6. const defaultMaxPreparedStmts = 1000
  7. // preparedLRU is the prepared statement cache
  8. type preparedLRU struct {
  9. mu sync.RWMutex
  10. lru *lru.Cache
  11. }
  12. // Max adjusts the maximum size of the cache and cleans up the oldest records if
  13. // the new max is lower than the previous value. Not concurrency safe.
  14. func (p *preparedLRU) max(max int) {
  15. p.mu.Lock()
  16. defer p.mu.Unlock()
  17. for p.lru.Len() > max {
  18. p.lru.RemoveOldest()
  19. }
  20. p.lru.MaxEntries = max
  21. }
  22. func (p *preparedLRU) clear() {
  23. p.mu.Lock()
  24. defer p.mu.Unlock()
  25. for p.lru.Len() > 0 {
  26. p.lru.RemoveOldest()
  27. }
  28. }
  29. func (p *preparedLRU) add(key string, val *inflightPrepare) {
  30. p.mu.Lock()
  31. defer p.mu.Unlock()
  32. p.lru.Add(key, val)
  33. }
  34. func (p *preparedLRU) remove(key string) bool {
  35. p.mu.Lock()
  36. defer p.mu.Unlock()
  37. return p.lru.Remove(key)
  38. }
  39. func (p *preparedLRU) execIfMissing(key string, fn func(lru *lru.Cache) *inflightPrepare) (*inflightPrepare, bool) {
  40. p.mu.RLock()
  41. val, ok := p.lru.Get(key)
  42. p.mu.RUnlock()
  43. if ok {
  44. return val.(*inflightPrepare), true
  45. }
  46. p.mu.Lock()
  47. defer p.mu.Unlock()
  48. if val, ok := p.lru.Get(key); ok {
  49. return val.(*inflightPrepare), true
  50. }
  51. return fn(p.lru), false
  52. }
  53. func (p *preparedLRU) keyFor(addr, keyspace, statement string) string {
  54. // TODO: maybe use []byte for keys?
  55. return addr + keyspace + statement
  56. }