From 58b4f40cdcde6caca98fae50ed9588ab7071234e Mon Sep 17 00:00:00 2001 From: Matthew Jaffee Date: Fri, 3 Dec 2021 11:23:43 -0600 Subject: [PATCH 1/2] enable TopK on mutex fields I think it was just an oversight that it wasn't, because this seems to work --- executor.go | 2 +- executor_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/executor.go b/executor.go index 009f55c7b..20af2da4a 100644 --- a/executor.go +++ b/executor.go @@ -2098,7 +2098,7 @@ func (e *executor) executeTopKShard(ctx context.Context, qcx *Qcx, index string, return e.executeTopKShardTime(ctx, tx, filterBitmap, index, fieldName, shard, fromTime, toTime) } fallthrough - case FieldTypeSet: + case FieldTypeSet, FieldTypeMutex: return e.executeTopKShardSet(ctx, tx, filterBitmap, index, fieldName, shard) default: return nil, errors.Errorf("field type %q is not yet supported by TopK", ftype) diff --git a/executor_test.go b/executor_test.go index e4924887e..49590df95 100644 --- a/executor_test.go +++ b/executor_test.go @@ -1719,6 +1719,36 @@ func TestExecutor_Execute_TopK_Set(t *testing.T) { } } +func TestExecutor_Execute_TopK_Mutex(t *testing.T) { + c := test.MustRunCluster(t, 3) + defer c.Close() + + // Load some test data into a mutex field. + c.CreateField(t, "i", pilosa.IndexOptions{TrackExistence: true}, "f", pilosa.OptFieldTypeMutex(pilosa.CacheTypeRanked, 10)) + c.ImportBits(t, "i", "f", [][2]uint64{ + {0, 0}, + {0, ShardWidth + 2}, + {10, 2}, + {10, ShardWidth}, + {10, 2 * ShardWidth}, + {10, ShardWidth + 1}, + {20, ShardWidth}, + }) + + // Execute query. + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `TopK(f, k=2)`}); err != nil { + t.Fatal(err) + } else if !reflect.DeepEqual(result.Results, []interface{}{&pilosa.PairsField{ + Pairs: []pilosa.Pair{ + {ID: 10, Count: 3}, + {ID: 0, Count: 2}, + }, + Field: "f", + }}) { + t.Fatalf("unexpected result: %s", spew.Sdump(result)) + } +} + func TestExecutor_Execute_TopK_Time(t *testing.T) { c := test.MustRunCluster(t, 3) defer c.Close() From bd3e73ba66ab4bf48502e3afbabf4e3b283c924c Mon Sep 17 00:00:00 2001 From: Matthew Jaffee Date: Fri, 3 Dec 2021 16:40:23 -0600 Subject: [PATCH 2/2] refactor test to reduce duplication I guess this is actually better... thanks SonarCloud! --- executor_test.go | 93 ++++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 47 deletions(-) diff --git a/executor_test.go b/executor_test.go index 49590df95..ed4ffa735 100644 --- a/executor_test.go +++ b/executor_test.go @@ -1688,64 +1688,63 @@ func TestExecutor_Execute_SetValue(t *testing.T) { } -func TestExecutor_Execute_TopK_Set(t *testing.T) { - c := test.MustRunCluster(t, 3) - defer c.Close() - - // Load some test data into a set field. - c.CreateField(t, "i", pilosa.IndexOptions{TrackExistence: true}, "f") - c.ImportBits(t, "i", "f", [][2]uint64{ +func TestExecutor_ExecuteTopK(t *testing.T) { + baseBits := [][2]uint64{ {0, 0}, - {0, 1}, {0, ShardWidth + 2}, {10, 2}, {10, ShardWidth}, {10, 2 * ShardWidth}, {10, ShardWidth + 1}, {20, ShardWidth}, - }) - - // Execute query. - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `TopK(f, k=2)`}); err != nil { - t.Fatal(err) - } else if !reflect.DeepEqual(result.Results, []interface{}{&pilosa.PairsField{ - Pairs: []pilosa.Pair{ - {ID: 10, Count: 4}, - {ID: 0, Count: 3}, - }, - Field: "f", - }}) { - t.Fatalf("unexpected result: %s", spew.Sdump(result)) } -} - -func TestExecutor_Execute_TopK_Mutex(t *testing.T) { + tests := []struct { + fieldName string + fieldOptions []pilosa.FieldOption + bits [][2]uint64 + query string + result []pilosa.Pair + }{ + { + fieldName: "f", + bits: append(baseBits, [2]uint64{0, 1}), + query: "TopK(f, k=2)", + result: []pilosa.Pair{ + {ID: 10, Count: 4}, + {ID: 0, Count: 3}, + }, + }, + { + fieldName: "fmutex", + fieldOptions: []pilosa.FieldOption{pilosa.OptFieldTypeMutex(pilosa.CacheTypeRanked, 10)}, + bits: baseBits, + query: "TopK(f, k=2)", + result: []pilosa.Pair{ + {ID: 10, Count: 3}, + {ID: 0, Count: 2}, + }, + }, + } c := test.MustRunCluster(t, 3) defer c.Close() - // Load some test data into a mutex field. - c.CreateField(t, "i", pilosa.IndexOptions{TrackExistence: true}, "f", pilosa.OptFieldTypeMutex(pilosa.CacheTypeRanked, 10)) - c.ImportBits(t, "i", "f", [][2]uint64{ - {0, 0}, - {0, ShardWidth + 2}, - {10, 2}, - {10, ShardWidth}, - {10, 2 * ShardWidth}, - {10, ShardWidth + 1}, - {20, ShardWidth}, - }) - - // Execute query. - if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `TopK(f, k=2)`}); err != nil { - t.Fatal(err) - } else if !reflect.DeepEqual(result.Results, []interface{}{&pilosa.PairsField{ - Pairs: []pilosa.Pair{ - {ID: 10, Count: 3}, - {ID: 0, Count: 2}, - }, - Field: "f", - }}) { - t.Fatalf("unexpected result: %s", spew.Sdump(result)) + for _, tst := range tests { + t.Run(tst.fieldName, func(t *testing.T) { + pilosa.OptFieldTypeMutex(pilosa.CacheTypeRanked, 10) + c.CreateField(t, "i", pilosa.IndexOptions{TrackExistence: true}, tst.fieldName) + c.ImportBits(t, "i", tst.fieldName, tst.bits) + if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: tst.query}); err != nil { + t.Fatal(err) + } else if !reflect.DeepEqual(result.Results, []interface{}{&pilosa.PairsField{ + Pairs: []pilosa.Pair{ + {ID: 10, Count: 4}, + {ID: 0, Count: 3}, + }, + Field: "f", + }}) { + t.Fatalf("unexpected result: %s", spew.Sdump(result)) + } + }) } }