Support ranked cache value=0.

Since there is no way to remove a value from the cache (because
the interface doesn't support it), this PR modifies the ranked
cache implemetation to allow setting the cache value to 0 for a
row. Doing so effectively removes that row from the cache. Values
below the threshold (other than 0) are still ignored by the
ranked cache's Add() method.
This commit is contained in:
Travis Turner 2018-09-17 14:59:38 -05:00
parent b6e99734f0
commit 1b6d738bab
No known key found for this signature in database
GPG key ID: 7F08008DFD9314C9
2 changed files with 74 additions and 2 deletions

View file

@ -167,8 +167,10 @@ func NewRankCache(maxEntries uint32) *rankCache {
func (c *rankCache) Add(id uint64, n uint64) {
c.mu.Lock()
defer c.mu.Unlock()
// Ignore if the column count is below the threshold.
if n < c.thresholdValue {
// Ignore if the column count is below the threshold,
// unless the count is 0, which is effectively used
// to clear the cache value.
if n < c.thresholdValue && n > 0 {
return
}

View file

@ -1841,6 +1841,76 @@ func TestExecutor_Execute_ClearRow(t *testing.T) {
t.Fatal("expected clear row to return an error")
}
})
t.Run("TopN", func(t *testing.T) {
c := test.MustRunCluster(t, 1)
defer c.Close()
hldr := test.Holder{Holder: c[0].Server.Holder()}
index := hldr.MustCreateIndexIfNotExists("i", pilosa.IndexOptions{TrackExistence: true})
_, err := index.CreateField("f", pilosa.OptFieldTypeDefault())
if err != nil {
t.Fatal(err)
}
cc := `
Set(2, f=1)
Set(3, f=1)
Set(4, f=1)
Set(5, f=1)
Set(6, f=1)
Set(7, f=1)
Set(8, f=1)
Set(2, f=2)
Set(3, f=2)
Set(4, f=2)
Set(5, f=2)
Set(6, f=2)
Set(7, f=2)
Set(2, f=3)
Set(3, f=3)
Set(4, f=3)
Set(5, f=3)
Set(6, f=3)
`
// Set bits.
if _, err := c[0].API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: cc}); err != nil {
t.Fatal(err)
}
if err := c[0].RecalculateCaches(); err != nil {
t.Fatalf("recalculating caches: %v", err)
}
// Check the TopN results.
if res, err := c[0].API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `TopN(f, n=5)`}); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual(res.Results, []interface{}{[]pilosa.Pair{
{ID: 1, Count: 7},
{ID: 2, Count: 6},
{ID: 3, Count: 5},
}}) {
t.Fatalf("topn wrong results: %v", res.Results)
}
// Clear the row and ensure we get a `true` response.
if res, err := c[0].API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `ClearRow(f=2)`}); err != nil {
t.Fatal(err)
} else if res := res.Results[0].(bool); !res {
t.Fatalf("unexpected clear row result: %+v", res)
}
// Ensure that the cleared row doesn't show up in TopN (i.e. it was removed from the cache).
if res, err := c[0].API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `TopN(f, n=5)`}); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual(res.Results, []interface{}{[]pilosa.Pair{
{ID: 1, Count: 7},
{ID: 3, Count: 5},
}}) {
t.Fatalf("topn wrong results: %v", res.Results)
}
})
}
func benchmarkExistence(nn bool, b *testing.B) {