Add optional GroupBy() 'aggregate' field.

This commit adds an `aggregate` field that allows a `Sum()` call
to be executed for every returned group.
This commit is contained in:
Ben Johnson 2019-02-16 15:55:53 -07:00 committed by Matt Jaffee
parent 81a4d32cdd
commit ea9914dba0
No known key found for this signature in database
GPG key ID: 08A3DFFF987B11BF
6 changed files with 227 additions and 103 deletions

View file

@ -864,7 +864,7 @@ Rows(job)
**Spec:**
```
GroupBy(<ROWS_CALL>, [<ROWS_CALL>...], limit=<UINT>, filter=<ROW_CALL>)
GroupBy(<ROWS_CALL>, [<ROWS_CALL>...], limit=<UINT>, filter=<ROW_CALL>, aggregate=<CALL>)
```
**Description:**
@ -874,14 +874,18 @@ taking one row each from the specified `Rows` calls. It returns only those
combinations for which the count is greater than 0.
The optional `filter` argument takes any type of `Row` query (e.g. Row, Union,
Intersect, etc.) which will be intersected with each result prior to returning
the count. This is analogous to a WHERE clause applied to a relational GROUP BY
query.
Intersect, etc.) which will be intersected with each result prior to returning
the count. This is analagous to a WHERE clause applied to a relational GROUP BY
query.
The optional `limit` argument limits the number of results returned. The results
are ordered, so as long as the data isn't changing, the same query will return
the same result set.
The optional `aggregate` argument takes a `Sum()` query which will be used to
calculate the sum & count of each group. This is similar to using a `SUM()` in
the SELECT clause of a relation GROUP BY query.
Paging through results is supported by passing the `previous` argument to each
of the `Rows` calls in the GroupBy. Take the last result from your previous
`GroupBy` query, and pass each row ID in that result as the `previous` argument

View file

@ -1187,6 +1187,7 @@ func decodeGroupCounts(a []*internal.GroupCount) []pilosa.GroupCount {
other[i] = pilosa.GroupCount{
Group: decodeFieldRows(a[i].Group),
Count: a[i].Count,
Sum: a[i].Sum,
}
}
return other
@ -1284,6 +1285,7 @@ func encodeGroupCounts(counts []pilosa.GroupCount) []*internal.GroupCount {
result[i] = &internal.GroupCount{
Group: encodeFieldRows(counts[i].Group),
Count: counts[i].Count,
Sum: counts[i].Sum,
}
}
return result

View file

@ -666,7 +666,7 @@ func (e *executor) executeSum(ctx context.Context, index string, c *pql.Call, sh
// Execute calls in bulk on each remote node and merge.
mapFn := func(shard uint64) (interface{}, error) {
return e.executeSumCountShard(ctx, index, c, shard)
return e.executeSumCountShard(ctx, index, c, nil, shard)
}
// Merge returned results at coordinating node.
@ -1053,12 +1053,12 @@ func (e *executor) executeGenericFieldShard(ctx context.Context, index string, c
}
// executeSumCountShard calculates the sum and count for bsiGroups on a shard.
func (e *executor) executeSumCountShard(ctx context.Context, index string, c *pql.Call, shard uint64) (ValCount, error) {
func (e *executor) executeSumCountShard(ctx context.Context, index string, c *pql.Call, filter *Row, shard uint64) (ValCount, error) {
span, ctx := tracing.StartSpanFromContext(ctx, "Executor.executeSumCountShard")
defer span.Finish()
var filter *Row
if len(c.Children) == 1 {
// Only calculate the filter if it doesn't exist and a child call as been passed in.
if filter == nil && len(c.Children) == 1 {
row, err := e.executeBitmapCallShard(ctx, index, c.Children[0], shard)
if err != nil {
return ValCount{}, errors.Wrap(err, "executing bitmap call")
@ -1563,6 +1563,7 @@ func (fr FieldRow) String() string {
type GroupCount struct {
Group []FieldRow `json:"group"`
Count uint64 `json:"count"`
Sum int64 `json:"sum"`
}
// mergeGroupCounts merges two slices of GroupCounts throwing away any that go
@ -1581,6 +1582,7 @@ func mergeGroupCounts(a, b []GroupCount, limit int) []GroupCount {
i++
case 0:
a[i].Count += b[j].Count
a[i].Sum += b[j].Sum
ret = append(ret, a[i])
i++
j++
@ -1619,7 +1621,12 @@ func (e *executor) executeGroupByShard(ctx context.Context, index string, c *pql
}
}
iter, err := newGroupByIterator(childRows, c.Children, filterRow, index, shard, e.Holder)
aggregate, _, err := c.CallArg("aggregate")
if err != nil {
return nil, err
}
iter, err := newGroupByIterator(e, childRows, c.Children, aggregate, filterRow, index, shard, e.Holder)
if err != nil {
return nil, errors.Wrapf(err, "getting group by iterator for shard %d", shard)
}
@ -1637,7 +1644,10 @@ func (e *executor) executeGroupByShard(ctx context.Context, index string, c *pql
results := make([]GroupCount, 0)
num := 0
for gc, done := iter.Next(); !done && num < limit; gc, done = iter.Next() {
for gc, done, err := iter.Next(ctx); !done && num < limit; gc, done, err = iter.Next(ctx) {
if err != nil {
return nil, err
}
if gc.Count > 0 {
num++
results = append(results, gc)
@ -3279,6 +3289,16 @@ func (e *executor) translateGroupByCall(index string, idx *Index, c *pql.Call) e
}
}
if aggregate, ok, err := c.CallArg("aggregate"); ok {
if err != nil {
return errors.Wrap(err, "getting aggregate call")
}
err = e.translateCall(index, idx, aggregate)
if err != nil {
return errors.Wrap(err, "translating aggregate call")
}
}
prev, ok := c.Args["previous"]
if !ok {
return nil // nothing else to be translated
@ -3416,6 +3436,7 @@ func (e *executor) translateResult(index string, idx *Index, call *pql.Call, res
other = append(other, GroupCount{
Group: group,
Count: gl.Count,
Sum: gl.Sum,
})
}
return other, nil
@ -3656,6 +3677,10 @@ func isValidID(v interface{}) bool {
// elements equal to the number of fields in the group by (the number of Rows
// calls).
type groupByIterator struct {
executor *executor
index string
shard uint64
// rowIters contains a rowIterator for each of the fields in the Group By.
rowIters []*rowIterator
// rows contains the current row data for each of the fields in the Group
@ -3677,18 +3702,25 @@ type groupByIterator struct {
// Optional filter row to intersect against first level of values.
filter *Row
// Optional aggregate function to execute for each group.
aggregate *pql.Call
}
// newGroupByIterator initializes a new groupByIterator.
func newGroupByIterator(rowIDs []RowIDs, children []*pql.Call, filter *Row, index string, shard uint64, holder *Holder) (*groupByIterator, error) {
func newGroupByIterator(executor *executor, rowIDs []RowIDs, children []*pql.Call, aggregate *pql.Call, filter *Row, index string, shard uint64, holder *Holder) (*groupByIterator, error) {
gbi := &groupByIterator{
executor: executor,
index: index,
shard: shard,
rowIters: make([]*rowIterator, len(children)),
rows: make([]struct {
row *Row
id uint64
}, len(children)),
filter: filter,
fields: make([]FieldRow, len(children)),
filter: filter,
aggregate: aggregate,
fields: make([]FieldRow, len(children)),
}
var fieldName string
@ -3796,16 +3828,33 @@ func (gbi *groupByIterator) nextAtIdx(i int) {
// Next returns a GroupCount representing the next group by record. When there
// are no more records it will return an empty GroupCount and done==true.
func (gbi *groupByIterator) Next() (ret GroupCount, done bool) {
func (gbi *groupByIterator) Next(ctx context.Context) (ret GroupCount, done bool, err error) {
// loop until we find a result with count > 0
for {
if gbi.done {
return ret, true
return ret, true, nil
}
if len(gbi.rows) == 1 {
ret.Count = gbi.rows[len(gbi.rows)-1].row.Count()
if gbi.aggregate == nil {
if len(gbi.rows) == 1 {
ret.Count = gbi.rows[len(gbi.rows)-1].row.Count()
} else {
ret.Count = gbi.rows[len(gbi.rows)-1].row.intersectionCount(gbi.rows[len(gbi.rows)-2].row)
}
} else {
ret.Count = gbi.rows[len(gbi.rows)-1].row.intersectionCount(gbi.rows[len(gbi.rows)-2].row)
filter := gbi.rows[len(gbi.rows)-1].row
if len(gbi.rows) != 1 {
filter = filter.Intersect(gbi.rows[len(gbi.rows)-2].row)
}
switch gbi.aggregate.Name {
case "Sum":
result, err := gbi.executor.executeSumCountShard(ctx, gbi.index, gbi.aggregate, filter, gbi.shard)
if err != nil {
return ret, false, err
}
ret.Count = uint64(result.Count)
ret.Sum = result.Val
}
}
if ret.Count == 0 {
gbi.nextAtIdx(len(gbi.rows) - 1)
@ -3824,7 +3873,7 @@ func (gbi *groupByIterator) Next() (ret GroupCount, done bool) {
gbi.nextAtIdx(len(gbi.rows) - 1)
return ret, false
return ret, false, nil
}
// getCondIntSlice looks at the field, the cond op type (which is

View file

@ -3413,15 +3413,25 @@ func TestExecutor_GroupByStrings(t *testing.T) {
c := test.MustRunCluster(t, 1)
defer c.Close()
c.CreateField(t, "istring", pilosa.IndexOptions{Keys: true}, "generals", pilosa.OptFieldKeys())
c.CreateField(t, "istring", pilosa.IndexOptions{Keys: true}, "v", pilosa.OptFieldTypeInt(0, 1000))
req := &pilosa.ImportRequest{
if err := c[0].API.Import(context.Background(), &pilosa.ImportRequest{
Index: "istring",
Field: "generals",
Shard: 0,
RowKeys: []string{"r1", "r2", "r1", "r2", "r1", "r2", "r1", "r2", "r1", "r2"},
ColumnKeys: []string{"c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10"},
}); err != nil {
t.Fatalf("importing: %v", err)
}
if err := c[0].API.Import(context.Background(), req); err != nil {
if err := c[0].API.ImportValue(context.Background(), &pilosa.ImportValueRequest{
Index: "istring",
Field: "v",
Shard: 0,
ColumnKeys: []string{"c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10"},
Values: []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
}); err != nil {
t.Fatalf("importing: %v", err)
}
@ -3442,6 +3452,13 @@ func TestExecutor_GroupByStrings(t *testing.T) {
{Group: []pilosa.FieldRow{{Field: "generals", RowID: 2, RowKey: "r2"}}, Count: 5},
},
},
{
query: "GroupBy(Rows(generals), aggregate=Sum(field=v))",
expected: []pilosa.GroupCount{
{Group: []pilosa.FieldRow{{Field: "generals", RowID: 1, RowKey: "r1"}}, Count: 5, Sum: 25},
{Group: []pilosa.FieldRow{{Field: "generals", RowID: 2, RowKey: "r2"}}, Count: 5, Sum: 30},
},
},
}
for i, tst := range tests {
@ -3595,6 +3612,7 @@ func TestExecutor_Execute_GroupBy(t *testing.T) {
defer c.Close()
c.CreateField(t, "i", pilosa.IndexOptions{}, "general")
c.CreateField(t, "i", pilosa.IndexOptions{}, "sub")
c.CreateField(t, "i", pilosa.IndexOptions{}, "v", pilosa.OptFieldTypeInt(0, 1000))
c.ImportBits(t, "i", "general", [][2]uint64{
{10, 0},
{10, 1},
@ -3613,6 +3631,11 @@ func TestExecutor_Execute_GroupBy(t *testing.T) {
{110, 2},
{110, 0},
})
if _, err := c[0].API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(0, v=10)`}); err != nil {
t.Fatal(err)
} else if _, err := c[0].API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(1, v=100)`}); err != nil {
t.Fatal(err)
}
t.Run("No Field List Arguments", func(t *testing.T) {
if _, err := c[0].API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `GroupBy()`}); err != nil {
@ -3666,6 +3689,16 @@ func TestExecutor_Execute_GroupBy(t *testing.T) {
test.CheckGroupBy(t, expected, results)
})
t.Run("Aggregate", func(t *testing.T) {
expected := []pilosa.GroupCount{
{Group: []pilosa.FieldRow{{Field: "general", RowID: 10}, {Field: "sub", RowID: 100}}, Count: 2, Sum: 110},
{Group: []pilosa.FieldRow{{Field: "general", RowID: 10}, {Field: "sub", RowID: 110}}, Count: 1, Sum: 10},
}
results := c.Query(t, "i", `GroupBy(Rows(general), Rows(sub), aggregate=Sum(field=v))`).Results[0].([]pilosa.GroupCount)
test.CheckGroupBy(t, expected, results)
})
t.Run("check field offset no limit", func(t *testing.T) {
expected := []pilosa.GroupCount{
{Group: []pilosa.FieldRow{{Field: "general", RowID: 11}}, Count: 2},

View file

@ -36,7 +36,7 @@ func (m *Row) Reset() { *m = Row{} }
func (m *Row) String() string { return proto.CompactTextString(m) }
func (*Row) ProtoMessage() {}
func (*Row) Descriptor() ([]byte, []int) {
return fileDescriptor_public_17d2a22edfa80498, []int{0}
return fileDescriptor_public_d14551a4203088d5, []int{0}
}
func (m *Row) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -105,7 +105,7 @@ func (m *SignedRow) Reset() { *m = SignedRow{} }
func (m *SignedRow) String() string { return proto.CompactTextString(m) }
func (*SignedRow) ProtoMessage() {}
func (*SignedRow) Descriptor() ([]byte, []int) {
return fileDescriptor_public_17d2a22edfa80498, []int{1}
return fileDescriptor_public_d14551a4203088d5, []int{1}
}
func (m *SignedRow) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -160,7 +160,7 @@ func (m *RowIdentifiers) Reset() { *m = RowIdentifiers{} }
func (m *RowIdentifiers) String() string { return proto.CompactTextString(m) }
func (*RowIdentifiers) ProtoMessage() {}
func (*RowIdentifiers) Descriptor() ([]byte, []int) {
return fileDescriptor_public_17d2a22edfa80498, []int{2}
return fileDescriptor_public_d14551a4203088d5, []int{2}
}
func (m *RowIdentifiers) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -216,7 +216,7 @@ func (m *Pair) Reset() { *m = Pair{} }
func (m *Pair) String() string { return proto.CompactTextString(m) }
func (*Pair) ProtoMessage() {}
func (*Pair) Descriptor() ([]byte, []int) {
return fileDescriptor_public_17d2a22edfa80498, []int{3}
return fileDescriptor_public_d14551a4203088d5, []int{3}
}
func (m *Pair) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -279,7 +279,7 @@ func (m *FieldRow) Reset() { *m = FieldRow{} }
func (m *FieldRow) String() string { return proto.CompactTextString(m) }
func (*FieldRow) ProtoMessage() {}
func (*FieldRow) Descriptor() ([]byte, []int) {
return fileDescriptor_public_17d2a22edfa80498, []int{4}
return fileDescriptor_public_d14551a4203088d5, []int{4}
}
func (m *FieldRow) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -332,6 +332,7 @@ func (m *FieldRow) GetRowKey() string {
type GroupCount struct {
Group []*FieldRow `protobuf:"bytes,1,rep,name=Group" json:"Group,omitempty"`
Count uint64 `protobuf:"varint,2,opt,name=Count,proto3" json:"Count,omitempty"`
Sum int64 `protobuf:"varint,3,opt,name=Sum,proto3" json:"Sum,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -341,7 +342,7 @@ func (m *GroupCount) Reset() { *m = GroupCount{} }
func (m *GroupCount) String() string { return proto.CompactTextString(m) }
func (*GroupCount) ProtoMessage() {}
func (*GroupCount) Descriptor() ([]byte, []int) {
return fileDescriptor_public_17d2a22edfa80498, []int{5}
return fileDescriptor_public_d14551a4203088d5, []int{5}
}
func (m *GroupCount) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -384,6 +385,13 @@ func (m *GroupCount) GetCount() uint64 {
return 0
}
func (m *GroupCount) GetSum() int64 {
if m != nil {
return m.Sum
}
return 0
}
type ValCount struct {
Val int64 `protobuf:"varint,1,opt,name=Val,proto3" json:"Val,omitempty"`
Count int64 `protobuf:"varint,2,opt,name=Count,proto3" json:"Count,omitempty"`
@ -396,7 +404,7 @@ func (m *ValCount) Reset() { *m = ValCount{} }
func (m *ValCount) String() string { return proto.CompactTextString(m) }
func (*ValCount) ProtoMessage() {}
func (*ValCount) Descriptor() ([]byte, []int) {
return fileDescriptor_public_17d2a22edfa80498, []int{6}
return fileDescriptor_public_d14551a4203088d5, []int{6}
}
func (m *ValCount) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -452,7 +460,7 @@ func (m *ColumnAttrSet) Reset() { *m = ColumnAttrSet{} }
func (m *ColumnAttrSet) String() string { return proto.CompactTextString(m) }
func (*ColumnAttrSet) ProtoMessage() {}
func (*ColumnAttrSet) Descriptor() ([]byte, []int) {
return fileDescriptor_public_17d2a22edfa80498, []int{7}
return fileDescriptor_public_d14551a4203088d5, []int{7}
}
func (m *ColumnAttrSet) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -518,7 +526,7 @@ func (m *Attr) Reset() { *m = Attr{} }
func (m *Attr) String() string { return proto.CompactTextString(m) }
func (*Attr) ProtoMessage() {}
func (*Attr) Descriptor() ([]byte, []int) {
return fileDescriptor_public_17d2a22edfa80498, []int{8}
return fileDescriptor_public_d14551a4203088d5, []int{8}
}
func (m *Attr) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -600,7 +608,7 @@ func (m *AttrMap) Reset() { *m = AttrMap{} }
func (m *AttrMap) String() string { return proto.CompactTextString(m) }
func (*AttrMap) ProtoMessage() {}
func (*AttrMap) Descriptor() ([]byte, []int) {
return fileDescriptor_public_17d2a22edfa80498, []int{9}
return fileDescriptor_public_d14551a4203088d5, []int{9}
}
func (m *AttrMap) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -653,7 +661,7 @@ func (m *QueryRequest) Reset() { *m = QueryRequest{} }
func (m *QueryRequest) String() string { return proto.CompactTextString(m) }
func (*QueryRequest) ProtoMessage() {}
func (*QueryRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_public_17d2a22edfa80498, []int{10}
return fileDescriptor_public_d14551a4203088d5, []int{10}
}
func (m *QueryRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -744,7 +752,7 @@ func (m *QueryResponse) Reset() { *m = QueryResponse{} }
func (m *QueryResponse) String() string { return proto.CompactTextString(m) }
func (*QueryResponse) ProtoMessage() {}
func (*QueryResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_public_17d2a22edfa80498, []int{11}
return fileDescriptor_public_d14551a4203088d5, []int{11}
}
func (m *QueryResponse) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -814,7 +822,7 @@ func (m *QueryResult) Reset() { *m = QueryResult{} }
func (m *QueryResult) String() string { return proto.CompactTextString(m) }
func (*QueryResult) ProtoMessage() {}
func (*QueryResult) Descriptor() ([]byte, []int) {
return fileDescriptor_public_17d2a22edfa80498, []int{12}
return fileDescriptor_public_d14551a4203088d5, []int{12}
}
func (m *QueryResult) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -931,7 +939,7 @@ func (m *ImportRequest) Reset() { *m = ImportRequest{} }
func (m *ImportRequest) String() string { return proto.CompactTextString(m) }
func (*ImportRequest) ProtoMessage() {}
func (*ImportRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_public_17d2a22edfa80498, []int{13}
return fileDescriptor_public_d14551a4203088d5, []int{13}
}
func (m *ImportRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -1033,7 +1041,7 @@ func (m *ImportValueRequest) Reset() { *m = ImportValueRequest{} }
func (m *ImportValueRequest) String() string { return proto.CompactTextString(m) }
func (*ImportValueRequest) ProtoMessage() {}
func (*ImportValueRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_public_17d2a22edfa80498, []int{14}
return fileDescriptor_public_d14551a4203088d5, []int{14}
}
func (m *ImportValueRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -1124,7 +1132,7 @@ func (m *TranslateKeysRequest) Reset() { *m = TranslateKeysRequest{} }
func (m *TranslateKeysRequest) String() string { return proto.CompactTextString(m) }
func (*TranslateKeysRequest) ProtoMessage() {}
func (*TranslateKeysRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_public_17d2a22edfa80498, []int{15}
return fileDescriptor_public_d14551a4203088d5, []int{15}
}
func (m *TranslateKeysRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -1185,7 +1193,7 @@ func (m *TranslateKeysResponse) Reset() { *m = TranslateKeysResponse{} }
func (m *TranslateKeysResponse) String() string { return proto.CompactTextString(m) }
func (*TranslateKeysResponse) ProtoMessage() {}
func (*TranslateKeysResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_public_17d2a22edfa80498, []int{16}
return fileDescriptor_public_d14551a4203088d5, []int{16}
}
func (m *TranslateKeysResponse) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -1233,7 +1241,7 @@ func (m *ImportRoaringRequestView) Reset() { *m = ImportRoaringRequestVi
func (m *ImportRoaringRequestView) String() string { return proto.CompactTextString(m) }
func (*ImportRoaringRequestView) ProtoMessage() {}
func (*ImportRoaringRequestView) Descriptor() ([]byte, []int) {
return fileDescriptor_public_17d2a22edfa80498, []int{17}
return fileDescriptor_public_d14551a4203088d5, []int{17}
}
func (m *ImportRoaringRequestView) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -1288,7 +1296,7 @@ func (m *ImportRoaringRequest) Reset() { *m = ImportRoaringRequest{} }
func (m *ImportRoaringRequest) String() string { return proto.CompactTextString(m) }
func (*ImportRoaringRequest) ProtoMessage() {}
func (*ImportRoaringRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_public_17d2a22edfa80498, []int{18}
return fileDescriptor_public_d14551a4203088d5, []int{18}
}
func (m *ImportRoaringRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -1624,6 +1632,11 @@ func (m *GroupCount) MarshalTo(dAtA []byte) (int, error) {
i++
i = encodeVarintPublic(dAtA, i, uint64(m.Count))
}
if m.Sum != 0 {
dAtA[i] = 0x18
i++
i = encodeVarintPublic(dAtA, i, uint64(m.Sum))
}
if m.XXX_unrecognized != nil {
i += copy(dAtA[i:], m.XXX_unrecognized)
}
@ -2595,6 +2608,9 @@ func (m *GroupCount) Size() (n int) {
if m.Count != 0 {
n += 1 + sovPublic(uint64(m.Count))
}
if m.Sum != 0 {
n += 1 + sovPublic(uint64(m.Sum))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
@ -3830,6 +3846,25 @@ func (m *GroupCount) Unmarshal(dAtA []byte) error {
break
}
}
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Sum", wireType)
}
m.Sum = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPublic
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Sum |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipPublic(dAtA[iNdEx:])
@ -6452,69 +6487,69 @@ var (
ErrIntOverflowPublic = fmt.Errorf("proto: integer overflow")
)
func init() { proto.RegisterFile("public.proto", fileDescriptor_public_17d2a22edfa80498) }
func init() { proto.RegisterFile("public.proto", fileDescriptor_public_d14551a4203088d5) }
var fileDescriptor_public_17d2a22edfa80498 = []byte{
// 966 bytes of a gzipped FileDescriptorProto
var fileDescriptor_public_d14551a4203088d5 = []byte{
// 976 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xdd, 0x8e, 0xdb, 0x44,
0x14, 0x66, 0x62, 0x67, 0xe3, 0x9c, 0xfc, 0x50, 0x0d, 0x69, 0xb1, 0x50, 0x15, 0x22, 0x0b, 0x21,
0x73, 0xb3, 0x55, 0x83, 0x84, 0x7a, 0xc5, 0x4f, 0x9b, 0x2d, 0x8a, 0x4a, 0xa3, 0x72, 0x76, 0x15,
0xae, 0xbd, 0xcd, 0x34, 0xb5, 0xe4, 0x78, 0x82, 0x7f, 0x70, 0xf7, 0x01, 0x78, 0x02, 0x6e, 0x78,
0x04, 0x1e, 0x85, 0x2b, 0xc4, 0x23, 0xc0, 0xf2, 0x18, 0xdc, 0xa0, 0x39, 0xe3, 0xc9, 0x38, 0xee,
0xb6, 0x42, 0x88, 0xbb, 0x39, 0xbf, 0x73, 0xbe, 0x39, 0xe7, 0x7c, 0x36, 0x0c, 0xf7, 0xe5, 0x65,
0x12, 0x3f, 0x3f, 0xdd, 0x67, 0xb2, 0x90, 0xdc, 0x8b, 0xd3, 0x42, 0x64, 0x69, 0x94, 0x04, 0x39,
0x38, 0x28, 0x2b, 0xee, 0x43, 0xef, 0x91, 0x4c, 0xca, 0x5d, 0x9a, 0xfb, 0x6c, 0xe6, 0x84, 0x2e,
0x1a, 0x91, 0x7f, 0x04, 0xdd, 0xaf, 0x8a, 0x22, 0xcb, 0xfd, 0xce, 0xcc, 0x09, 0x07, 0xf3, 0xf1,
0xa9, 0x09, 0x3d, 0x55, 0x6a, 0xd4, 0x46, 0xce, 0xc1, 0x7d, 0x22, 0xae, 0x72, 0xdf, 0x99, 0x39,
0x61, 0x1f, 0xe9, 0xac, 0x72, 0xa2, 0x8c, 0xb2, 0x38, 0xdd, 0xfa, 0xee, 0x8c, 0x85, 0x43, 0x34,
0x62, 0xf0, 0x14, 0xfa, 0xe7, 0xf1, 0x36, 0x15, 0x1b, 0x75, 0xf5, 0x87, 0xe0, 0x3c, 0x93, 0xea,
0x5a, 0x16, 0x0e, 0xe6, 0x23, 0x9b, 0x1e, 0x65, 0x85, 0xca, 0xa2, 0x1c, 0x56, 0x62, 0xeb, 0x77,
0x6e, 0x74, 0x58, 0x89, 0x6d, 0xf0, 0x00, 0xc6, 0x28, 0xab, 0xe5, 0x46, 0xa4, 0x45, 0xfc, 0x22,
0x16, 0xba, 0x1c, 0x94, 0x95, 0xc1, 0x42, 0xe7, 0x43, 0x89, 0x1d, 0x5b, 0x62, 0xf0, 0x39, 0xb8,
0xcf, 0xa2, 0x38, 0xe3, 0x63, 0xe8, 0x2c, 0x17, 0x54, 0x82, 0x8b, 0x9d, 0xe5, 0x82, 0x4f, 0xa0,
0xfb, 0x48, 0x96, 0x69, 0x41, 0x97, 0xba, 0xa8, 0x05, 0x7e, 0x0b, 0x9c, 0x27, 0xe2, 0xca, 0x77,
0x66, 0x2c, 0xec, 0xa3, 0x3a, 0x06, 0x2b, 0xf0, 0x1e, 0xc7, 0x22, 0x21, 0x1c, 0x13, 0xe8, 0xd2,
0x99, 0xd2, 0xf4, 0x51, 0x0b, 0x4a, 0xab, 0x6a, 0x5b, 0x98, 0x4c, 0x24, 0xf0, 0x3b, 0x70, 0x82,
0xb2, 0xb2, 0xc9, 0x6a, 0x29, 0xf8, 0x06, 0xe0, 0xeb, 0x4c, 0x96, 0x7b, 0x7d, 0x5f, 0x08, 0x5d,
0x92, 0x08, 0xc6, 0x60, 0xce, 0x2d, 0x74, 0x73, 0x29, 0x6a, 0x87, 0x9b, 0xeb, 0x0d, 0xe6, 0xe0,
0xad, 0xa3, 0xe4, 0x50, 0xfb, 0x3a, 0x4a, 0xa8, 0x36, 0x07, 0xd5, 0xf1, 0x38, 0xc6, 0x31, 0x31,
0xdf, 0xc1, 0x48, 0x77, 0x5e, 0xf5, 0xf5, 0x5c, 0x14, 0xaf, 0x3d, 0xcd, 0xbf, 0x9b, 0x87, 0xd7,
0x9f, 0xea, 0x17, 0x06, 0xae, 0xb2, 0x19, 0x13, 0x3b, 0x98, 0x54, 0x67, 0x2e, 0xae, 0xf6, 0xa2,
0x2e, 0x9e, 0xce, 0x7c, 0x06, 0x83, 0xf3, 0x42, 0x0d, 0xcb, 0x3a, 0x4a, 0x4a, 0x51, 0x27, 0x6a,
0xaa, 0xf8, 0x07, 0xe0, 0x2d, 0xd3, 0x42, 0x9b, 0x5d, 0x82, 0x70, 0x90, 0xf9, 0x5d, 0xe8, 0x3f,
0x94, 0x32, 0xd1, 0xc6, 0xee, 0x8c, 0x85, 0x1e, 0x5a, 0x05, 0x9f, 0x02, 0x3c, 0x4e, 0x64, 0x54,
0xc7, 0x9e, 0xcc, 0x58, 0xc8, 0xb0, 0xa1, 0x09, 0xee, 0x41, 0x4f, 0x55, 0xfa, 0x34, 0xda, 0x5b,
0xb4, 0xec, 0x2d, 0x68, 0x83, 0xbf, 0x19, 0x0c, 0xbf, 0x2d, 0x45, 0x76, 0x85, 0xe2, 0xfb, 0x52,
0xe4, 0x85, 0x7a, 0x5b, 0x92, 0xcd, 0x2c, 0x90, 0xa0, 0xba, 0x7e, 0xfe, 0x32, 0xca, 0x36, 0xfa,
0xed, 0x5c, 0xac, 0x25, 0x85, 0xd5, 0xbe, 0x79, 0x4e, 0x58, 0x3d, 0x6c, 0xaa, 0x68, 0x5e, 0xc4,
0x4e, 0x16, 0x06, 0x4c, 0x2d, 0xf1, 0x10, 0xde, 0x3d, 0x7b, 0xf5, 0x3c, 0x29, 0x37, 0x02, 0x65,
0xa5, 0xa3, 0x4f, 0xc8, 0xa1, 0xad, 0xe6, 0x1f, 0xc3, 0xb8, 0x56, 0x99, 0x3d, 0xef, 0x91, 0x63,
0x4b, 0xcb, 0xef, 0xc3, 0xf0, 0x6c, 0x77, 0x29, 0x36, 0x1b, 0xb1, 0x59, 0x44, 0x45, 0xe4, 0x7b,
0x84, 0xbb, 0xb5, 0x75, 0x47, 0x2e, 0xc1, 0x4f, 0x0c, 0x46, 0x35, 0xfa, 0x7c, 0x2f, 0xd3, 0x5c,
0xa8, 0x16, 0x9f, 0x65, 0x99, 0x69, 0xf1, 0x59, 0x96, 0xf1, 0x7b, 0xd0, 0x43, 0x91, 0x97, 0x49,
0x61, 0xe6, 0xe6, 0xb6, 0xcd, 0x68, 0x62, 0xcb, 0xa4, 0x40, 0xe3, 0xc5, 0xbf, 0x80, 0xf1, 0xd1,
0x1c, 0x6a, 0x6a, 0x19, 0xcc, 0xdf, 0xb7, 0x71, 0x47, 0x76, 0x6c, 0xb9, 0x07, 0x3f, 0x3a, 0x30,
0x68, 0x64, 0x56, 0x2c, 0x82, 0xb2, 0x7a, 0x03, 0xcd, 0xa8, 0xfd, 0x1d, 0x02, 0x5b, 0xd5, 0x23,
0xc8, 0x56, 0xaa, 0xf1, 0x8a, 0x19, 0xcc, 0xb5, 0x8d, 0xc6, 0x2b, 0x35, 0x6a, 0x23, 0xd1, 0xe6,
0xcb, 0x28, 0xdd, 0x8a, 0x0d, 0x8d, 0xa0, 0x87, 0x46, 0xe4, 0xa7, 0x76, 0xf7, 0xa8, 0x67, 0x47,
0xeb, 0x6b, 0x2c, 0x68, 0xf7, 0xd3, 0xec, 0x80, 0x6a, 0xdf, 0xa8, 0xde, 0x01, 0xcd, 0x12, 0xcb,
0x85, 0xea, 0x15, 0xcd, 0x8b, 0x96, 0xf8, 0x67, 0x30, 0xb0, 0x2c, 0x91, 0xd7, 0x2d, 0x9a, 0xd8,
0xf4, 0xd6, 0x88, 0x4d, 0x47, 0xfe, 0x65, 0x9b, 0x27, 0xfd, 0x3e, 0x55, 0xe6, 0x1f, 0xbd, 0x46,
0xc3, 0x8e, 0x6d, 0x5e, 0xbd, 0xdf, 0x20, 0x6e, 0x1f, 0x28, 0xf8, 0x3d, 0x1b, 0x7c, 0x30, 0xa1,
0xf5, 0x0a, 0xfe, 0x64, 0x30, 0x5a, 0xee, 0xf6, 0x32, 0x2b, 0x1a, 0xcb, 0xb1, 0x4c, 0x37, 0xe2,
0x95, 0x59, 0x0e, 0x12, 0x2c, 0x7d, 0x76, 0x5a, 0xf4, 0x49, 0x4b, 0x42, 0x4b, 0xe1, 0xa2, 0x16,
0x1a, 0x0f, 0xe3, 0x1e, 0x3d, 0xcc, 0x5d, 0xe8, 0xeb, 0x29, 0x50, 0xa6, 0x2e, 0x99, 0xac, 0x42,
0xad, 0xfd, 0x45, 0xbc, 0x13, 0x79, 0x11, 0xed, 0xf6, 0x6a, 0x4f, 0x9c, 0xd0, 0xc1, 0x86, 0x46,
0x7f, 0xaf, 0x2a, 0xfa, 0x46, 0xf4, 0xe8, 0x1b, 0x61, 0x44, 0x15, 0xa9, 0xd3, 0x90, 0xd1, 0x23,
0x63, 0x43, 0x13, 0xfc, 0xc6, 0x80, 0x6b, 0x8c, 0x44, 0x20, 0xff, 0x1f, 0xd0, 0xb7, 0x03, 0xba,
0x03, 0x27, 0x74, 0x9f, 0x01, 0x53, 0x4b, 0xad, 0x72, 0x7b, 0xed, 0x72, 0x15, 0xdf, 0x58, 0xb6,
0xd3, 0x78, 0x18, 0x36, 0x55, 0xc1, 0x1a, 0x26, 0x17, 0x59, 0x94, 0xe6, 0x49, 0x54, 0x08, 0x15,
0xf2, 0x5f, 0x10, 0xdd, 0xf0, 0x4b, 0x10, 0x7c, 0x02, 0xb7, 0x5b, 0x79, 0x2d, 0x63, 0x28, 0x88,
0x0e, 0x41, 0x54, 0xc7, 0xe0, 0x21, 0xf8, 0xf5, 0xd8, 0xe8, 0x9f, 0x86, 0xba, 0x84, 0x75, 0x2c,
0x2a, 0x95, 0x7a, 0x15, 0xed, 0x44, 0x5d, 0x05, 0x9d, 0x95, 0x8e, 0x08, 0xab, 0x43, 0xbf, 0x1a,
0x74, 0x0e, 0x5e, 0xc0, 0xe4, 0xa6, 0x1c, 0xf4, 0xe9, 0x4b, 0x44, 0xa4, 0x19, 0xca, 0x43, 0x2d,
0xf0, 0x07, 0xd0, 0xfd, 0x21, 0x16, 0x95, 0x61, 0xa8, 0xc0, 0x0e, 0xf6, 0x9b, 0x0a, 0x41, 0x1d,
0xf0, 0xf0, 0xd6, 0xaf, 0xd7, 0x53, 0xf6, 0xfb, 0xf5, 0x94, 0xfd, 0x71, 0x3d, 0x65, 0x3f, 0xff,
0x35, 0x7d, 0xe7, 0xf2, 0x84, 0xfe, 0xb3, 0x3e, 0xfd, 0x27, 0x00, 0x00, 0xff, 0xff, 0xe6, 0xfc,
0xfe, 0x74, 0x77, 0x09, 0x00, 0x00,
0x14, 0x66, 0x62, 0x67, 0xe3, 0x9c, 0xec, 0x86, 0x6a, 0x48, 0x8b, 0x85, 0xaa, 0x10, 0x59, 0x08,
0x99, 0x9b, 0xad, 0x1a, 0x24, 0xd4, 0x2b, 0x7e, 0xb6, 0xd9, 0xa2, 0xa8, 0x6a, 0x54, 0x4e, 0x56,
0xe1, 0x0e, 0xc9, 0xdb, 0x4c, 0x53, 0x4b, 0x8e, 0x27, 0xf8, 0x07, 0x77, 0x1f, 0x80, 0x27, 0xe0,
0x86, 0x47, 0xe0, 0x51, 0xb8, 0x42, 0x3c, 0x02, 0x2c, 0x8f, 0xc1, 0x0d, 0x9a, 0x33, 0x9e, 0x8c,
0xe3, 0xee, 0x56, 0x08, 0x71, 0x37, 0xe7, 0x77, 0xce, 0x37, 0xe7, 0x9c, 0xcf, 0x86, 0xe3, 0x5d,
0x79, 0x99, 0xc4, 0x2f, 0x4e, 0x77, 0x99, 0x2c, 0x24, 0xf7, 0xe2, 0xb4, 0x10, 0x59, 0x1a, 0x25,
0x41, 0x0e, 0x0e, 0xca, 0x8a, 0xfb, 0xd0, 0x7b, 0x2c, 0x93, 0x72, 0x9b, 0xe6, 0x3e, 0x9b, 0x38,
0xa1, 0x8b, 0x46, 0xe4, 0x1f, 0x41, 0xf7, 0xab, 0xa2, 0xc8, 0x72, 0xbf, 0x33, 0x71, 0xc2, 0xc1,
0x74, 0x78, 0x6a, 0x42, 0x4f, 0x95, 0x1a, 0xb5, 0x91, 0x73, 0x70, 0x9f, 0x8a, 0xab, 0xdc, 0x77,
0x26, 0x4e, 0xd8, 0x47, 0x3a, 0xab, 0x9c, 0x28, 0xa3, 0x2c, 0x4e, 0x37, 0xbe, 0x3b, 0x61, 0xe1,
0x31, 0x1a, 0x31, 0x78, 0x06, 0xfd, 0x65, 0xbc, 0x49, 0xc5, 0x5a, 0x5d, 0xfd, 0x21, 0x38, 0xcf,
0xa5, 0xba, 0x96, 0x85, 0x83, 0xe9, 0x89, 0x4d, 0x8f, 0xb2, 0x42, 0x65, 0x51, 0x0e, 0x0b, 0xb1,
0xf1, 0x3b, 0x37, 0x3a, 0x2c, 0xc4, 0x26, 0x78, 0x04, 0x43, 0x94, 0xd5, 0x7c, 0x2d, 0xd2, 0x22,
0x7e, 0x19, 0x0b, 0x5d, 0x0e, 0xca, 0xca, 0x60, 0xa1, 0xf3, 0xbe, 0xc4, 0x8e, 0x2d, 0x31, 0xf8,
0x1c, 0xdc, 0xe7, 0x51, 0x9c, 0xf1, 0x21, 0x74, 0xe6, 0x33, 0x2a, 0xc1, 0xc5, 0xce, 0x7c, 0xc6,
0x47, 0xd0, 0x7d, 0x2c, 0xcb, 0xb4, 0xa0, 0x4b, 0x5d, 0xd4, 0x02, 0xbf, 0x03, 0xce, 0x53, 0x71,
0xe5, 0x3b, 0x13, 0x16, 0xf6, 0x51, 0x1d, 0x83, 0x05, 0x78, 0x4f, 0x62, 0x91, 0x10, 0x8e, 0x11,
0x74, 0xe9, 0x4c, 0x69, 0xfa, 0xa8, 0x05, 0xa5, 0x55, 0xb5, 0xcd, 0x4c, 0x26, 0x12, 0xf8, 0x3d,
0x38, 0x42, 0x59, 0xd9, 0x64, 0xb5, 0x14, 0x7c, 0x07, 0xf0, 0x75, 0x26, 0xcb, 0x9d, 0xbe, 0x2f,
0x84, 0x2e, 0x49, 0x04, 0x63, 0x30, 0xe5, 0x16, 0xba, 0xb9, 0x14, 0xb5, 0xc3, 0xed, 0xf5, 0x2e,
0xcb, 0x2d, 0x5d, 0xe1, 0xa0, 0x3a, 0x06, 0x53, 0xf0, 0x56, 0x51, 0xb2, 0xb7, 0xae, 0xa2, 0x84,
0xaa, 0x75, 0x50, 0x1d, 0x0f, 0xb3, 0x38, 0x75, 0x96, 0xe0, 0x5b, 0x38, 0xd1, 0xb3, 0xa0, 0x3a,
0xbd, 0x14, 0xc5, 0x1b, 0x8f, 0xf5, 0xef, 0x26, 0xe4, 0xcd, 0xc7, 0xfb, 0x85, 0x81, 0xab, 0x6c,
0xc6, 0xc4, 0xf6, 0x26, 0xd5, 0xab, 0x8b, 0xab, 0x9d, 0xa8, 0xe1, 0xd0, 0x99, 0x4f, 0x60, 0xb0,
0x2c, 0xd4, 0xf8, 0xac, 0xa2, 0xa4, 0x14, 0x75, 0xa2, 0xa6, 0x8a, 0x7f, 0x00, 0xde, 0x3c, 0x2d,
0xb4, 0xd9, 0x25, 0x08, 0x7b, 0x99, 0xdf, 0x87, 0xfe, 0x99, 0x94, 0x89, 0x36, 0x76, 0x27, 0x2c,
0xf4, 0xd0, 0x2a, 0xf8, 0x18, 0xe0, 0x49, 0x22, 0xa3, 0x3a, 0xf6, 0x68, 0xc2, 0x42, 0x86, 0x0d,
0x4d, 0xf0, 0x00, 0x7a, 0xaa, 0xd2, 0x67, 0xd1, 0xce, 0xa2, 0x65, 0x6f, 0x41, 0x1b, 0xfc, 0xcd,
0xe0, 0xf8, 0x9b, 0x52, 0x64, 0x57, 0x28, 0xbe, 0x2f, 0x45, 0x5e, 0xa8, 0xb7, 0x25, 0xd9, 0x4c,
0x07, 0x09, 0x6a, 0x0e, 0x96, 0xaf, 0xa2, 0x6c, 0xad, 0xdf, 0xce, 0xc5, 0x5a, 0x52, 0x58, 0xed,
0x9b, 0xe7, 0x84, 0xd5, 0xc3, 0xa6, 0x8a, 0x26, 0x48, 0x6c, 0x65, 0x61, 0xc0, 0xd4, 0x12, 0x0f,
0xe1, 0xdd, 0xf3, 0xd7, 0x2f, 0x92, 0x72, 0x2d, 0x50, 0x56, 0x3a, 0xfa, 0x88, 0x1c, 0xda, 0x6a,
0xfe, 0x31, 0x0c, 0x6b, 0x95, 0xd9, 0xfc, 0x1e, 0x39, 0xb6, 0xb4, 0xfc, 0x21, 0x1c, 0x9f, 0x6f,
0x2f, 0xc5, 0x7a, 0x2d, 0xd6, 0xb3, 0xa8, 0x88, 0x7c, 0x8f, 0x70, 0xb7, 0xf6, 0xf0, 0xc0, 0x25,
0xf8, 0x89, 0xc1, 0x49, 0x8d, 0x3e, 0xdf, 0xc9, 0x34, 0x17, 0xaa, 0xc5, 0xe7, 0x59, 0x66, 0x5a,
0x7c, 0x9e, 0x65, 0xfc, 0x01, 0xf4, 0x50, 0xe4, 0x65, 0x52, 0x98, 0xb9, 0xb9, 0x6b, 0x33, 0x9a,
0xd8, 0x32, 0x29, 0xd0, 0x78, 0xf1, 0x2f, 0x60, 0x78, 0x30, 0x87, 0x9a, 0x6c, 0x06, 0xd3, 0xf7,
0x6d, 0xdc, 0x81, 0x1d, 0x5b, 0xee, 0xc1, 0x8f, 0x0e, 0x0c, 0x1a, 0x99, 0x15, 0xaf, 0xa0, 0xac,
0x6e, 0x21, 0x1e, 0xb5, 0xd1, 0xc7, 0xc0, 0x16, 0xf5, 0x08, 0xb2, 0x85, 0x6a, 0xbc, 0xe2, 0x0a,
0x73, 0x6d, 0xa3, 0xf1, 0x4a, 0x8d, 0xda, 0x48, 0x44, 0xfa, 0x2a, 0x4a, 0x37, 0x62, 0x4d, 0x23,
0xe8, 0xa1, 0x11, 0xf9, 0xa9, 0xdd, 0x3d, 0xea, 0xd9, 0xc1, 0x42, 0x1b, 0x0b, 0xda, 0xfd, 0x34,
0x3b, 0xa0, 0xda, 0x77, 0x52, 0xef, 0x80, 0xe6, 0x8d, 0xf9, 0x4c, 0xf5, 0x8a, 0xe6, 0x45, 0x4b,
0xfc, 0x33, 0x18, 0x58, 0xde, 0xc8, 0xeb, 0x16, 0x8d, 0x6c, 0x7a, 0x6b, 0xc4, 0xa6, 0x23, 0xff,
0xb2, 0xcd, 0x9c, 0x7e, 0x9f, 0x2a, 0xf3, 0x0f, 0x5e, 0xa3, 0x61, 0xc7, 0x36, 0xd3, 0x3e, 0x6c,
0x50, 0xb9, 0x0f, 0x14, 0xfc, 0x9e, 0x0d, 0xde, 0x9b, 0xd0, 0x7a, 0x05, 0x7f, 0x32, 0x38, 0x99,
0x6f, 0x77, 0x32, 0x2b, 0x1a, 0xcb, 0x31, 0x4f, 0xd7, 0xe2, 0xb5, 0x59, 0x0e, 0x12, 0x2c, 0xa1,
0x76, 0x5a, 0x84, 0x4a, 0x4b, 0x42, 0x4b, 0xe1, 0xa2, 0x16, 0x1a, 0x0f, 0xe3, 0x1e, 0x3c, 0xcc,
0x7d, 0xe8, 0xeb, 0x29, 0x50, 0xa6, 0x2e, 0x99, 0xac, 0x42, 0xad, 0xfd, 0x45, 0xbc, 0x15, 0x79,
0x11, 0x6d, 0x77, 0x6a, 0x4f, 0x9c, 0xd0, 0xc1, 0x86, 0x46, 0x7f, 0xc1, 0x2a, 0xfa, 0x6a, 0xf4,
0xe8, 0xab, 0x61, 0x44, 0x15, 0xa9, 0xd3, 0x90, 0xd1, 0x23, 0x63, 0x43, 0x13, 0xfc, 0xc6, 0x80,
0x6b, 0x8c, 0x44, 0x20, 0xff, 0x1f, 0xd0, 0xb7, 0x03, 0xba, 0x07, 0x47, 0x74, 0x9f, 0x01, 0x53,
0x4b, 0xad, 0x72, 0x7b, 0xed, 0x72, 0x15, 0xdf, 0x58, 0xb6, 0xd3, 0x78, 0x18, 0x36, 0x55, 0xc1,
0x0a, 0x46, 0x17, 0x59, 0x94, 0xe6, 0x49, 0x54, 0x08, 0x15, 0xf2, 0x5f, 0x10, 0xdd, 0xf0, 0x93,
0x10, 0x7c, 0x02, 0x77, 0x5b, 0x79, 0x2d, 0x63, 0x28, 0x88, 0x0e, 0x41, 0x54, 0xc7, 0xe0, 0x0c,
0xfc, 0x7a, 0x6c, 0xf4, 0x6f, 0x44, 0x5d, 0xc2, 0x2a, 0x16, 0x95, 0x4a, 0xbd, 0x88, 0xb6, 0xa2,
0xae, 0x82, 0xce, 0x4a, 0x47, 0x84, 0xd5, 0xa1, 0x9f, 0x0f, 0x3a, 0x07, 0x2f, 0x61, 0x74, 0x53,
0x0e, 0xfa, 0xf4, 0x25, 0x22, 0xd2, 0x0c, 0xe5, 0xa1, 0x16, 0xf8, 0x23, 0xe8, 0xfe, 0x10, 0x8b,
0xca, 0x30, 0x54, 0x60, 0x07, 0xfb, 0xb6, 0x42, 0x50, 0x07, 0x9c, 0xdd, 0xf9, 0xf5, 0x7a, 0xcc,
0x7e, 0xbf, 0x1e, 0xb3, 0x3f, 0xae, 0xc7, 0xec, 0xe7, 0xbf, 0xc6, 0xef, 0x5c, 0x1e, 0xd1, 0x9f,
0xd7, 0xa7, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0xaf, 0xff, 0xd4, 0x70, 0x89, 0x09, 0x00, 0x00,
}

View file

@ -34,6 +34,7 @@ message FieldRow{
message GroupCount{
repeated FieldRow Group = 1;
uint64 Count = 2;
int64 Sum = 3;
}
message ValCount {