distinct on timestamps can reduce now

This commit is contained in:
reesporte 2022-01-10 13:07:57 -06:00
parent b82e05b012
commit cf483aca77
2 changed files with 59 additions and 0 deletions

View file

@ -1181,6 +1181,8 @@ func (e *executor) executeDistinct(ctx context.Context, qcx *Qcx, index string,
return other.Union(v.(*Row))
case nil:
return v
case DistinctTimestamp:
return other.Union(v.(DistinctTimestamp))
default:
return errors.Errorf("unexpected return type from executeDistinctShard: %+v %T", other, other)
}
@ -1633,6 +1635,22 @@ type DistinctTimestamp struct {
Name string
}
// Union returns the union of the values of `d` and `other`
func (d *DistinctTimestamp) Union(other DistinctTimestamp) DistinctTimestamp {
both := map[string]string{}
for _, val := range d.Values {
both[val] = val
}
for _, val := range other.Values {
both[val] = val
}
vals := []string{}
for key := range both {
vals = append(vals, key)
}
return DistinctTimestamp{Name: d.Name, Values: vals}
}
func executeDistinctShardSet(ctx context.Context, qcx *Qcx, idx *Index, fieldName string, shard uint64, filterBitmap *roaring.Bitmap) (result *Row, err0 error) {
index := idx.Name()
tx, finisher, err := qcx.GetTx(Txo{Write: !writable, Index: idx, Shard: shard})

View file

@ -504,3 +504,44 @@ func TestGetScaledInt(t *testing.T) {
}
}
func TestDistinctTimestampUnion(t *testing.T) {
cases := []struct {
name string
a DistinctTimestamp
b DistinctTimestamp
expected DistinctTimestamp
}{
{
name: "empty other",
a: DistinctTimestamp{Name: "a", Values: []string{"a", "b", "c"}},
b: DistinctTimestamp{Name: "a", Values: []string{}},
expected: DistinctTimestamp{Name: "a", Values: []string{"a", "b", "c"}},
},
{
name: "one more in other",
a: DistinctTimestamp{Name: "a", Values: []string{"a", "b", "c"}},
b: DistinctTimestamp{Name: "a", Values: []string{"a", "b", "c", "d"}},
expected: DistinctTimestamp{Name: "a", Values: []string{"a", "b", "c", "d"}},
},
}
for _, test := range cases {
t.Run(test.name, func(t *testing.T) {
res := test.a.Union(test.b)
allThere := true
for _, val := range res.Values {
here := false
for _, expected := range test.expected.Values {
if val == expected {
here = true
break
}
}
allThere = allThere && here
}
if !allThere {
t.Errorf("expected %v, got %v", test.expected, res)
}
})
}
}