Fix ranked cache logic to support reducing cached values below

the threshold.

Prior to this commit, if a cache value was reduced to a value
that fell below the threshold, the operation would be ignored
and the cached value would remain at the old, higher value.

This commit also fixes logic which reduces a cached value within
the framework of uint64 values by subracting the absolute value
of the negative value (since adding a negitive doesn't work with
unsigned integers).
This commit is contained in:
Travis 2019-11-18 11:39:50 -06:00
parent 32f754899e
commit ed82a535e5
3 changed files with 36 additions and 4 deletions

View file

@ -172,6 +172,7 @@ func (c *rankCache) Add(id uint64, n uint64) {
// unless the count is 0, which is effectively used
// to clear the cache value.
if n < c.thresholdValue && n > 0 {
delete(c.entries, id)
return
}
@ -185,6 +186,7 @@ func (c *rankCache) BulkAdd(id uint64, n uint64) {
c.mu.Lock()
defer c.mu.Unlock()
if n < c.thresholdValue {
delete(c.entries, id)
return
}

View file

@ -20,8 +20,8 @@ import (
"github.com/pilosa/pilosa/v2"
)
// Ensure a bitmap query can be executed.
func TestCache_Rank(t *testing.T) {
// Ensure cache stays constrained to its configured size.
func TestCache_Rank_Size(t *testing.T) {
cacheSize := uint32(3)
cache := pilosa.NewRankCache(cacheSize)
for i := 1; i < int(2*cacheSize); i++ {
@ -31,5 +31,26 @@ func TestCache_Rank(t *testing.T) {
if cache.Len() != int(cacheSize) {
t.Fatalf("unexpected cache Size: %d!=%d expected\n", cache.Len(), cacheSize)
}
}
// Ensure cache entries set below threshold are handled appropriately.
func TestCache_Rank_Threshold(t *testing.T) {
cacheSize := uint32(5)
cache := pilosa.NewRankCache(cacheSize)
for i := 1; i < int(2*cacheSize); i++ {
cache.Add(uint64(i), 3)
}
// Set the cache value for rows 4 and 5 to a number below the threshold
// value (which is 3), and ensure that they gets zeroed out.
cache.Add(4, 1)
cache.BulkAdd(5, 1)
cache.Recalculate()
if cache.Get(4) != 0 {
t.Fatalf("unexpected cache value after Add: %d!=%d expected\n", cache.Get(4), 0)
}
if cache.Get(5) != 0 {
t.Fatalf("unexpected cache value after BulkAdd: %d!=%d expected\n", cache.Get(5), 0)
}
}

View file

@ -2099,7 +2099,16 @@ func (f *fragment) importRoaring(ctx context.Context, data []byte, clear bool) e
f.rowCache.Add(rowID, nil)
if updateCache {
anyChanged = true
f.cache.BulkAdd(rowID, f.cache.Get(rowID)+uint64(changes))
if changes < 0 {
absChanges := uint64(-1 * changes)
if absChanges <= f.cache.Get(rowID) {
f.cache.BulkAdd(rowID, f.cache.Get(rowID)-absChanges)
} else {
f.cache.BulkAdd(rowID, 0)
}
} else {
f.cache.BulkAdd(rowID, f.cache.Get(rowID)+uint64(changes))
}
}
}
// we only set this if we need to update the cache