Merge pull request #745 from linhvo/none-type-cache

None type cache
This commit is contained in:
Linh Vo 2017-07-25 08:44:00 -05:00 committed by GitHub
commit 3c9ca6c2c4
6 changed files with 72 additions and 7 deletions

View file

@ -54,7 +54,7 @@ type Cache interface {
SetStats(s StatsClient)
}
// LRUCache represents a least recently used Cache implemenation.
// LRUCache represents a least recently used Cache implementation.
type LRUCache struct {
cache *lru.Cache
counts map[uint64]uint64
@ -483,3 +483,35 @@ func (s *SimpleCache) Fetch(id uint64) (*Bitmap, bool) {
func (s *SimpleCache) Add(id uint64, b *Bitmap) {
s.cache[id] = b
}
// NopCache represents a no-op Cache implementation.
type NopCache struct {
stats StatsClient
}
// Ensure NopCache implements Cache.
var _ Cache = &NopCache{}
// NewNopCache returns a new instance of NopCache.
func NewNopCache() *NopCache {
return &NopCache{
stats: NopStatsClient,
}
}
func (c *NopCache) Add(id uint64, n uint64) {}
func (c *NopCache) BulkAdd(id uint64, n uint64) {}
func (c *NopCache) Get(id uint64) uint64 { return 0 }
func (c *NopCache) IDs() []uint64 { return make([]uint64, 0, 0) }
func (c *NopCache) Invalidate() {}
func (c *NopCache) Len() int { return 0 }
func (c *NopCache) Recalculate() {
}
func (c *NopCache) SetStats(s StatsClient) {
c.stats = s
}
func (c *NopCache) Top() []BitmapPair {
return []BitmapPair{}
}

View file

@ -249,6 +249,8 @@ func (f *Fragment) openCache() error {
f.cache = NewRankCache(f.CacheSize)
case CacheTypeLRU:
f.cache = NewLRUCache(f.CacheSize)
case CacheTypeNone:
f.cache = NewNopCache()
default:
return ErrInvalidCacheType
}
@ -702,6 +704,10 @@ func (f *Fragment) Top(opt TopOptions) ([]Pair, error) {
}
func (f *Fragment) topBitmapPairs(rowIDs []uint64) []BitmapPair {
// Don't retrieve from storage if CacheTypeNone.
if f.CacheType == CacheTypeNone {
return f.cache.Top()
}
// If no specific rows are requested, retrieve top rows.
if len(rowIDs) == 0 {
f.mu.Lock()

View file

@ -415,6 +415,24 @@ func TestFragment_TopN_IDs(t *testing.T) {
}
}
// Ensure a fragment return none if CacheTypeNone is set
func TestFragment_TopN_NopCache(t *testing.T) {
f := test.MustOpenFragment("i", "f", pilosa.ViewStandard, 0, pilosa.CacheTypeNone)
defer f.Close()
// Set bits on various rows.
f.MustSetBits(100, 1, 2, 3)
f.MustSetBits(101, 4, 5, 6, 7)
f.MustSetBits(102, 8, 9, 10, 11, 12)
// Retrieve top rows.
if pairs, err := f.Top(pilosa.TopOptions{RowIDs: []uint64{100, 101, 200}}); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual(pairs, []pilosa.Pair{}) {
t.Fatalf("unexpected pairs: %s", spew.Sdump(pairs))
}
}
// Ensure the fragment cache limit works
func TestFragment_TopN_CacheSize(t *testing.T) {
slice := uint64(0)

View file

@ -905,12 +905,13 @@ func (p importBitSet) Less(i, j int) bool { return p.rowIDs[i] < p.rowIDs[j] }
const (
CacheTypeLRU = "lru"
CacheTypeRanked = "ranked"
CacheTypeNone = "none"
)
// IsValidCacheType returns true if v is a valid cache type.
func IsValidCacheType(v string) bool {
switch v {
case CacheTypeLRU, CacheTypeRanked:
case CacheTypeLRU, CacheTypeRanked, CacheTypeNone:
return true
default:
return false

View file

@ -388,16 +388,12 @@ func (i *Index) createFrame(name string, opt FrameOptions) (*Frame, error) {
}
// Validate mutually exclusive options if ranges are enabled.
//
// NOTE(https://github.com/pilosa/pilosa/issues/399):
// Cache type should be validated as "none" once it is allowed.
if opt.RangeEnabled {
if opt.InverseEnabled {
return nil, ErrInverseRangeNotAllowed
} else if opt.CacheType != "" && opt.CacheType != CacheTypeLRU {
} else if opt.CacheType != "" && opt.CacheType != CacheTypeNone {
return nil, ErrRangeCacheNotAllowed
}
opt.CacheSize = 0
} else {
if len(opt.Fields) > 0 {
return nil, ErrFrameFieldsNotAllowed

View file

@ -149,6 +149,18 @@ func TestIndex_CreateFrame(t *testing.T) {
}
})
t.Run("RangeEnabledWithCacheTypeNone", func(t *testing.T) {
index := test.MustOpenIndex()
defer index.Close()
if _, err := index.CreateFrame("f", pilosa.FrameOptions{
RangeEnabled: true,
CacheType: pilosa.CacheTypeNone,
CacheSize: uint32(5),
}); err != nil {
t.Fatal(err)
}
})
t.Run("ErrFrameFieldsNotAllowed", func(t *testing.T) {
index := test.MustOpenIndex()
defer index.Close()