add FieldRow struct to replace the groupBy string key

This commit is contained in:
Travis Turner 2018-08-22 12:18:27 -05:00
parent 54ce537327
commit e1b938e52c
No known key found for this signature in database
GPG key ID: 7F08008DFD9314C9
5 changed files with 381 additions and 160 deletions

View file

@ -999,11 +999,29 @@ func decodeAttr(attr *internal.Attr) (key string, value interface{}) {
}
func decodeGroupByCounts(a []*internal.GroupLine) pilosa.GroupByCounts {
gbc := make(pilosa.GroupByCounts, 0)
other := make([]pilosa.GroupLine, len(a))
for i := range a {
gbc = append(gbc, pilosa.GroupLine{a[i].Groups, a[i].Total})
other[i] = pilosa.GroupLine{
decodeFieldRows(a[i].Groups),
a[i].Total,
}
}
return pilosa.GroupByCounts(other)
}
func decodeFieldRows(a []*internal.FieldRow) []pilosa.FieldRow {
other := make([]pilosa.FieldRow, len(a))
for i := range a {
other[i] = decodeFieldRow(a[i])
}
return other
}
func decodeFieldRow(pb *internal.FieldRow) pilosa.FieldRow {
return pilosa.FieldRow{
Field: pb.Field,
RowID: pb.RowID,
}
return gbc
}
func decodePairs(a []*internal.Pair) []pilosa.Pair {
@ -1060,11 +1078,29 @@ func encodeRow(r *pilosa.Row) *internal.Row {
func encodeGroupByCount(counts pilosa.GroupByCounts) []*internal.GroupLine {
result := make([]*internal.GroupLine, len(counts))
for i := range counts {
result[i] = &internal.GroupLine{Groups: counts[i].Groups, Total: counts[i].Total}
result[i] = &internal.GroupLine{
Groups: encodeFieldRows(counts[i].Groups),
Total: counts[i].Total,
}
}
return result
}
func encodeFieldRows(a []pilosa.FieldRow) []*internal.FieldRow {
other := make([]*internal.FieldRow, len(a))
for i := range a {
other[i] = encodeFieldRow(a[i])
}
return other
}
func encodeFieldRow(p pilosa.FieldRow) *internal.FieldRow {
return &internal.FieldRow{
Field: p.Field,
RowID: p.RowID,
}
}
func encodePairs(a pilosa.Pairs) []*internal.Pair {
other := make([]*internal.Pair, len(a))
for i := range a {

View file

@ -786,16 +786,37 @@ func (e *executor) executeGroupBy(ctx context.Context, index string, c *pql.Call
return results, nil
}
// FieldRow is used to distinguish rows in a group by result.
type FieldRow struct {
Field string
RowID uint64
RowKey string
}
func (fr FieldRow) String() string {
return fmt.Sprintf("%s.%d", fr.Field, fr.RowID)
}
// TODO: we shouldn't need to string this
func uniqueGroupString(fr []FieldRow) string {
s := []string{}
for _, f := range fr {
s = append(s, f.String())
}
return strings.Join(s, "-")
}
// gbi is a groupBy item.
type gbi struct {
row *Row
fieldKey string
rowID uint64
fieldRow FieldRow
}
type GroupLine struct {
Groups []string
Groups []FieldRow
Total uint64
}
// GroupByCounts is the return type for GroupBy queries.
type GroupByCounts []GroupLine
func (gbc GroupByCounts) Merge(other GroupByCounts) GroupByCounts {
@ -804,14 +825,13 @@ func (gbc GroupByCounts) Merge(other GroupByCounts) GroupByCounts {
total uint64
})
for i := range gbc {
m[strings.Join(gbc[i].Groups, "-")] = struct {
m[uniqueGroupString(gbc[i].Groups)] = struct {
i int
total uint64
}{total: gbc[i].Total, i: i}
}{i, gbc[i].Total}
}
for i := range other {
key := strings.Join(other[i].Groups, "-")
o, found := m[key]
o, found := m[uniqueGroupString(other[i].Groups)]
if found {
gbc[o.i].Total += other[i].Total
} else {
@ -820,20 +840,7 @@ func (gbc GroupByCounts) Merge(other GroupByCounts) GroupByCounts {
}
return gbc
}
func makeGroup(parts []gbi) GroupLine {
var other *Row
line := GroupLine{}
for i, o := range parts {
if i == 0 {
other = o.row
} else {
other = other.Intersect(o.row)
}
line.Groups = append(line.Groups, o.fieldKey)
}
line.Total = other.Count()
return line
}
func (e *executor) executeGroupByShard(ctx context.Context, index string, c *pql.Call, shard uint64) (GroupByCounts, error) {
// Fetch index.
idx := e.Holder.Index(index)
@ -867,7 +874,7 @@ func (e *executor) executeGroupByShard(ctx context.Context, index string, c *pql
}
}
results := make(GroupByCounts, 0)
var work listOfGBILists
var work [][]gbi
for _, fieldDirective := range fieldDirectives.([]interface{}) {
fieldName := getFieldName(fieldDirective.(string))
// Fetch fragment.
@ -880,12 +887,15 @@ func (e *executor) executeGroupByShard(ctx context.Context, index string, c *pql
if err != nil {
return nil, err
}
set := make(gbiList, 0)
set := make([]gbi, 0)
for _, rowID := range frag.rowsWithFilter(filter) {
set = append(set, gbi{
row: frag.row(rowID),
rowID: rowID,
fieldKey: fmt.Sprintf("%s.%d", fieldName, rowID),
row: frag.row(rowID),
fieldRow: FieldRow{
Field: fieldName,
RowID: rowID,
},
})
}
work = append(work, set)
@ -899,35 +909,29 @@ func (e *executor) executeGroupByShard(ctx context.Context, index string, c *pql
return results, nil
}
type gbiList []gbi
type listOfGBILists []gbiList
// pi is a product process item.
type pi struct {
// ppi is a product process item.
type ppi struct {
row *Row
gl GroupLine
}
type piList []pi
// product generates the cartiesian product of the input
// using tail recursion
func product(input listOfGBILists) piList {
res := make(piList, 0)
if len(input) == 0 { //base return empty list
res = append(res, pi{gl: GroupLine{Groups: make([]string, 0)}})
} else {
res = productHelper(input, res)
// product generates the cartesian product of the input
// using tail recursion.
func product(input [][]gbi) []ppi {
if len(input) == 0 { // base return empty list
return []ppi{
{gl: GroupLine{Groups: make([]FieldRow, 0)}},
}
}
return res
}
func productHelper(lists listOfGBILists, res piList) piList {
head := lists[0] //take first element of the list
tail := product(lists[1:]) //invoke product on remaining element
res := make([]ppi, 0)
head := input[0] // take first element of the list
tail := product(input[1:]) // invoke product on remaining element
for h := range head { // for each head
for t := range tail { //iterate over the tail
s := pi{gl: GroupLine{Groups: make([]string, 0)}}
s.gl.Groups = append([]string{head[h].fieldKey}, tail[t].gl.Groups...) //had to insert at the front to match input order
if tail[t].row != nil { //first time around nothing to intersect
for t := range tail { // iterate over the tail
s := ppi{gl: GroupLine{Groups: make([]FieldRow, 0)}}
s.gl.Groups = append([]FieldRow{head[h].fieldRow}, tail[t].gl.Groups...) // had to insert at the front to match input order
if tail[t].row != nil { // first time around nothing to intersect
s.row = head[h].row.Intersect(tail[t].row)
} else {
s.row = head[h].row

View file

@ -1234,11 +1234,11 @@ Set(4500001, fn=4)
t.Fatalf("GroupBy querying: %v", err)
} else {
expected := pilosa.GroupByCounts{
{Groups: []string{"f.10"}, Total: 4},
{Groups: []string{"f.7"}, Total: 1},
{Groups: []pilosa.FieldRow{{Field: "f", RowID: 10}}, Total: 4},
{Groups: []pilosa.FieldRow{{Field: "f", RowID: 7}}, Total: 1},
}
results := res.Results[0].(pilosa.GroupByCounts)
checkGroupBy(expected, results, t)
checkGroupBy(t, expected, results)
}
})
}
@ -1681,17 +1681,15 @@ func TestExecutor_Execute_GroupBy(t *testing.T) {
hldr.SetBit("i", "general", 11, ShardWidth+2)
hldr.SetBit("i", "general", 12, 2)
hldr.SetBit("i", "general", 12, ShardWidth+2)
hldr.SetBit("i", "sub", 10, 0)
hldr.SetBit("i", "sub", 10, 1)
hldr.SetBit("i", "sub", 10, 3)
hldr.SetBit("i", "sub", 11, 2)
hldr.SetBit("i", "sub", 11, 0)
expected := pilosa.GroupByCounts{
{Groups: []string{"general.10", "sub.11"}, Total: 1},
{Groups: []string{"general.11", "sub.11"}, Total: 1},
{Groups: []string{"general.12", "sub.11"}, Total: 1},
{Groups: []string{"general.10", "sub.10"}, Total: 2},
}
hldr.SetBit("i", "sub", 100, 0)
hldr.SetBit("i", "sub", 100, 1)
hldr.SetBit("i", "sub", 100, 3)
hldr.SetBit("i", "sub", 100, ShardWidth+1)
hldr.SetBit("i", "sub", 110, 2)
hldr.SetBit("i", "sub", 110, 0)
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 {
if errors.Cause(err) != pilosa.ErrFieldsArgumentRequired {
@ -1714,38 +1712,50 @@ func TestExecutor_Execute_GroupBy(t *testing.T) {
}
})
t.Run("Basic", func(t *testing.T) {
expected := pilosa.GroupByCounts{
{Groups: []pilosa.FieldRow{{Field: "general", RowID: 10}, {Field: "sub", RowID: 110}}, Total: 1},
{Groups: []pilosa.FieldRow{{Field: "general", RowID: 11}, {Field: "sub", RowID: 110}}, Total: 1},
{Groups: []pilosa.FieldRow{{Field: "general", RowID: 12}, {Field: "sub", RowID: 110}}, Total: 1},
{Groups: []pilosa.FieldRow{{Field: "general", RowID: 10}, {Field: "sub", RowID: 100}}, Total: 3},
}
if res, err := c[0].API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `GroupBy(fields=[general,sub])`}); err != nil {
t.Fatal(err)
} else {
results := res.Results[0].(pilosa.GroupByCounts)
checkGroupBy(expected, results, t)
checkGroupBy(t, expected, results)
}
})
expected = pilosa.GroupByCounts{
{Groups: []string{"general.11"}, Total: 2},
{Groups: []string{"general.12"}, Total: 2},
}
t.Run("check field offset no limit", func(t *testing.T) {
expected := pilosa.GroupByCounts{
{Groups: []pilosa.FieldRow{{Field: "general", RowID: 11}}, Total: 2},
{Groups: []pilosa.FieldRow{{Field: "general", RowID: 12}}, Total: 2},
}
if res, err := c[0].API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `GroupBy(fields=[general:11:])`}); err != nil {
t.Fatal(err)
} else {
results := res.Results[0].(pilosa.GroupByCounts)
checkGroupBy(expected, results, t)
checkGroupBy(t, expected, results)
}
})
expected = pilosa.GroupByCounts{
{Groups: []string{"general.11"}, Total: 2},
}
t.Run("check field offset limit", func(t *testing.T) {
expected := pilosa.GroupByCounts{
{Groups: []pilosa.FieldRow{{Field: "general", RowID: 11}}, Total: 2},
}
if res, err := c[0].API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `GroupBy(fields=[general:11:1])`}); err != nil {
t.Fatal(err)
} else {
results := res.Results[0].(pilosa.GroupByCounts)
checkGroupBy(expected, results, t)
checkGroupBy(t, expected, results)
}
})
}
func checkGroupBy(expected, results pilosa.GroupByCounts, t *testing.T) {
func checkGroupBy(t *testing.T, expected, results pilosa.GroupByCounts) {
notIn := func(item pilosa.GroupLine, expected pilosa.GroupByCounts) bool {
for i := range expected {
if item.Total == expected[i].Total {

View file

@ -10,6 +10,7 @@
It has these top-level messages:
Row
Pair
FieldRow
GroupLine
ValCount
Bit
@ -107,17 +108,41 @@ func (m *Pair) GetCount() uint64 {
return 0
}
type FieldRow struct {
Field string `protobuf:"bytes,1,opt,name=Field,proto3" json:"Field,omitempty"`
RowID uint64 `protobuf:"varint,2,opt,name=RowID,proto3" json:"RowID,omitempty"`
}
func (m *FieldRow) Reset() { *m = FieldRow{} }
func (m *FieldRow) String() string { return proto.CompactTextString(m) }
func (*FieldRow) ProtoMessage() {}
func (*FieldRow) Descriptor() ([]byte, []int) { return fileDescriptorPublic, []int{2} }
func (m *FieldRow) GetField() string {
if m != nil {
return m.Field
}
return ""
}
func (m *FieldRow) GetRowID() uint64 {
if m != nil {
return m.RowID
}
return 0
}
type GroupLine struct {
Groups []string `protobuf:"bytes,1,rep,name=Groups" json:"Groups,omitempty"`
Total uint64 `protobuf:"varint,2,opt,name=Total,proto3" json:"Total,omitempty"`
Groups []*FieldRow `protobuf:"bytes,1,rep,name=Groups" json:"Groups,omitempty"`
Total uint64 `protobuf:"varint,2,opt,name=Total,proto3" json:"Total,omitempty"`
}
func (m *GroupLine) Reset() { *m = GroupLine{} }
func (m *GroupLine) String() string { return proto.CompactTextString(m) }
func (*GroupLine) ProtoMessage() {}
func (*GroupLine) Descriptor() ([]byte, []int) { return fileDescriptorPublic, []int{2} }
func (*GroupLine) Descriptor() ([]byte, []int) { return fileDescriptorPublic, []int{3} }
func (m *GroupLine) GetGroups() []string {
func (m *GroupLine) GetGroups() []*FieldRow {
if m != nil {
return m.Groups
}
@ -139,7 +164,7 @@ type ValCount struct {
func (m *ValCount) Reset() { *m = ValCount{} }
func (m *ValCount) String() string { return proto.CompactTextString(m) }
func (*ValCount) ProtoMessage() {}
func (*ValCount) Descriptor() ([]byte, []int) { return fileDescriptorPublic, []int{3} }
func (*ValCount) Descriptor() ([]byte, []int) { return fileDescriptorPublic, []int{4} }
func (m *ValCount) GetVal() int64 {
if m != nil {
@ -164,7 +189,7 @@ type Bit struct {
func (m *Bit) Reset() { *m = Bit{} }
func (m *Bit) String() string { return proto.CompactTextString(m) }
func (*Bit) ProtoMessage() {}
func (*Bit) Descriptor() ([]byte, []int) { return fileDescriptorPublic, []int{4} }
func (*Bit) Descriptor() ([]byte, []int) { return fileDescriptorPublic, []int{5} }
func (m *Bit) GetRowID() uint64 {
if m != nil {
@ -196,7 +221,7 @@ type ColumnAttrSet struct {
func (m *ColumnAttrSet) Reset() { *m = ColumnAttrSet{} }
func (m *ColumnAttrSet) String() string { return proto.CompactTextString(m) }
func (*ColumnAttrSet) ProtoMessage() {}
func (*ColumnAttrSet) Descriptor() ([]byte, []int) { return fileDescriptorPublic, []int{5} }
func (*ColumnAttrSet) Descriptor() ([]byte, []int) { return fileDescriptorPublic, []int{6} }
func (m *ColumnAttrSet) GetID() uint64 {
if m != nil {
@ -231,7 +256,7 @@ type Attr struct {
func (m *Attr) Reset() { *m = Attr{} }
func (m *Attr) String() string { return proto.CompactTextString(m) }
func (*Attr) ProtoMessage() {}
func (*Attr) Descriptor() ([]byte, []int) { return fileDescriptorPublic, []int{6} }
func (*Attr) Descriptor() ([]byte, []int) { return fileDescriptorPublic, []int{7} }
func (m *Attr) GetKey() string {
if m != nil {
@ -282,7 +307,7 @@ type AttrMap struct {
func (m *AttrMap) Reset() { *m = AttrMap{} }
func (m *AttrMap) String() string { return proto.CompactTextString(m) }
func (*AttrMap) ProtoMessage() {}
func (*AttrMap) Descriptor() ([]byte, []int) { return fileDescriptorPublic, []int{7} }
func (*AttrMap) Descriptor() ([]byte, []int) { return fileDescriptorPublic, []int{8} }
func (m *AttrMap) GetAttrs() []*Attr {
if m != nil {
@ -303,7 +328,7 @@ type QueryRequest struct {
func (m *QueryRequest) Reset() { *m = QueryRequest{} }
func (m *QueryRequest) String() string { return proto.CompactTextString(m) }
func (*QueryRequest) ProtoMessage() {}
func (*QueryRequest) Descriptor() ([]byte, []int) { return fileDescriptorPublic, []int{8} }
func (*QueryRequest) Descriptor() ([]byte, []int) { return fileDescriptorPublic, []int{9} }
func (m *QueryRequest) GetQuery() string {
if m != nil {
@ -356,7 +381,7 @@ type QueryResponse struct {
func (m *QueryResponse) Reset() { *m = QueryResponse{} }
func (m *QueryResponse) String() string { return proto.CompactTextString(m) }
func (*QueryResponse) ProtoMessage() {}
func (*QueryResponse) Descriptor() ([]byte, []int) { return fileDescriptorPublic, []int{9} }
func (*QueryResponse) Descriptor() ([]byte, []int) { return fileDescriptorPublic, []int{10} }
func (m *QueryResponse) GetErr() string {
if m != nil {
@ -393,7 +418,7 @@ type QueryResult struct {
func (m *QueryResult) Reset() { *m = QueryResult{} }
func (m *QueryResult) String() string { return proto.CompactTextString(m) }
func (*QueryResult) ProtoMessage() {}
func (*QueryResult) Descriptor() ([]byte, []int) { return fileDescriptorPublic, []int{10} }
func (*QueryResult) Descriptor() ([]byte, []int) { return fileDescriptorPublic, []int{11} }
func (m *QueryResult) GetType() uint32 {
if m != nil {
@ -465,7 +490,7 @@ type ImportRequest struct {
func (m *ImportRequest) Reset() { *m = ImportRequest{} }
func (m *ImportRequest) String() string { return proto.CompactTextString(m) }
func (*ImportRequest) ProtoMessage() {}
func (*ImportRequest) Descriptor() ([]byte, []int) { return fileDescriptorPublic, []int{11} }
func (*ImportRequest) Descriptor() ([]byte, []int) { return fileDescriptorPublic, []int{12} }
func (m *ImportRequest) GetIndex() string {
if m != nil {
@ -535,7 +560,7 @@ type ImportValueRequest struct {
func (m *ImportValueRequest) Reset() { *m = ImportValueRequest{} }
func (m *ImportValueRequest) String() string { return proto.CompactTextString(m) }
func (*ImportValueRequest) ProtoMessage() {}
func (*ImportValueRequest) Descriptor() ([]byte, []int) { return fileDescriptorPublic, []int{12} }
func (*ImportValueRequest) Descriptor() ([]byte, []int) { return fileDescriptorPublic, []int{13} }
func (m *ImportValueRequest) GetIndex() string {
if m != nil {
@ -582,6 +607,7 @@ func (m *ImportValueRequest) GetValues() []int64 {
func init() {
proto.RegisterType((*Row)(nil), "internal.Row")
proto.RegisterType((*Pair)(nil), "internal.Pair")
proto.RegisterType((*FieldRow)(nil), "internal.FieldRow")
proto.RegisterType((*GroupLine)(nil), "internal.GroupLine")
proto.RegisterType((*ValCount)(nil), "internal.ValCount")
proto.RegisterType((*Bit)(nil), "internal.Bit")
@ -690,6 +716,35 @@ func (m *Pair) MarshalTo(dAtA []byte) (int, error) {
return i, nil
}
func (m *FieldRow) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *FieldRow) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if len(m.Field) > 0 {
dAtA[i] = 0xa
i++
i = encodeVarintPublic(dAtA, i, uint64(len(m.Field)))
i += copy(dAtA[i:], m.Field)
}
if m.RowID != 0 {
dAtA[i] = 0x10
i++
i = encodeVarintPublic(dAtA, i, uint64(m.RowID))
}
return i, nil
}
func (m *GroupLine) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@ -706,18 +761,15 @@ func (m *GroupLine) MarshalTo(dAtA []byte) (int, error) {
var l int
_ = l
if len(m.Groups) > 0 {
for _, s := range m.Groups {
for _, msg := range m.Groups {
dAtA[i] = 0xa
i++
l = len(s)
for l >= 1<<7 {
dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
l >>= 7
i++
i = encodeVarintPublic(dAtA, i, uint64(msg.Size()))
n, err := msg.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
dAtA[i] = uint8(l)
i++
i += copy(dAtA[i:], s)
i += n
}
}
if m.Total != 0 {
@ -1396,12 +1448,25 @@ func (m *Pair) Size() (n int) {
return n
}
func (m *FieldRow) Size() (n int) {
var l int
_ = l
l = len(m.Field)
if l > 0 {
n += 1 + l + sovPublic(uint64(l))
}
if m.RowID != 0 {
n += 1 + sovPublic(uint64(m.RowID))
}
return n
}
func (m *GroupLine) Size() (n int) {
var l int
_ = l
if len(m.Groups) > 0 {
for _, s := range m.Groups {
l = len(s)
for _, e := range m.Groups {
l = e.Size()
n += 1 + l + sovPublic(uint64(l))
}
}
@ -1977,6 +2042,104 @@ func (m *Pair) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *FieldRow) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPublic
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: FieldRow: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: FieldRow: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Field", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPublic
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthPublic
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Field = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field RowID", wireType)
}
m.RowID = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPublic
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.RowID |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipPublic(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthPublic
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *GroupLine) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
@ -2010,7 +2173,7 @@ func (m *GroupLine) Unmarshal(dAtA []byte) error {
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Groups", wireType)
}
var stringLen uint64
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPublic
@ -2020,20 +2183,22 @@ func (m *GroupLine) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
if msglen < 0 {
return ErrInvalidLengthPublic
}
postIndex := iNdEx + intStringLen
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Groups = append(m.Groups, string(dAtA[iNdEx:postIndex]))
m.Groups = append(m.Groups, &FieldRow{})
if err := m.Groups[len(m.Groups)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 2:
if wireType != 0 {
@ -4076,53 +4241,54 @@ var (
func init() { proto.RegisterFile("public.proto", fileDescriptorPublic) }
var fileDescriptorPublic = []byte{
// 760 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0xcd, 0x6e, 0xd3, 0x4a,
0x14, 0xbe, 0x13, 0x3b, 0x89, 0x73, 0xd2, 0xe4, 0x56, 0x73, 0xef, 0xed, 0xb5, 0x50, 0x15, 0x2c,
0x0b, 0x21, 0xaf, 0x52, 0x29, 0xac, 0xba, 0x01, 0x91, 0xfe, 0xa0, 0xa8, 0x50, 0xc1, 0xb4, 0x14,
0xb1, 0x74, 0x9b, 0x51, 0x6b, 0xc9, 0xf1, 0x18, 0x7b, 0xac, 0x34, 0xcf, 0xd1, 0x0d, 0x8f, 0xc0,
0x82, 0x07, 0xe9, 0x92, 0x47, 0x80, 0xf2, 0x22, 0x68, 0xce, 0x78, 0x62, 0x27, 0x95, 0x2a, 0x16,
0xec, 0xfc, 0x7d, 0x67, 0xe6, 0xcc, 0xf9, 0xce, 0x9f, 0x61, 0x23, 0x2d, 0xce, 0xe3, 0xe8, 0x62,
0x98, 0x66, 0x42, 0x0a, 0xea, 0x44, 0x89, 0xe4, 0x59, 0x12, 0xc6, 0xfe, 0x47, 0xb0, 0x98, 0x98,
0x53, 0x17, 0xda, 0x7b, 0x22, 0x2e, 0x66, 0x49, 0xee, 0x12, 0xcf, 0x0a, 0x6c, 0x66, 0x20, 0x7d,
0x02, 0xcd, 0x97, 0x52, 0x66, 0xb9, 0xdb, 0xf0, 0xac, 0xa0, 0x3b, 0xea, 0x0f, 0xcd, 0xd5, 0xa1,
0xa2, 0x99, 0x36, 0x52, 0x0a, 0xf6, 0x11, 0x5f, 0xe4, 0xae, 0xe5, 0x59, 0x41, 0x87, 0xe1, 0xb7,
0xff, 0x1c, 0xec, 0xb7, 0x61, 0x94, 0xd1, 0x3e, 0x34, 0x26, 0xfb, 0x2e, 0xf1, 0x48, 0x60, 0xb3,
0xc6, 0x64, 0x9f, 0xfe, 0x0b, 0xcd, 0x3d, 0x51, 0x24, 0xd2, 0x6d, 0x20, 0xa5, 0x01, 0xdd, 0x04,
0xeb, 0x88, 0x2f, 0x5c, 0xcb, 0x23, 0x41, 0x87, 0xa9, 0x4f, 0x7f, 0x17, 0x3a, 0xaf, 0x32, 0x51,
0xa4, 0xaf, 0xa3, 0x84, 0xd3, 0x2d, 0x68, 0x21, 0xd0, 0xf1, 0x75, 0x58, 0x89, 0x94, 0xb3, 0x53,
0x21, 0xc3, 0xd8, 0x38, 0x43, 0xe0, 0x8f, 0xc0, 0x39, 0x0b, 0xe3, 0xa5, 0xe3, 0xb3, 0x30, 0xc6,
0xf7, 0x2d, 0xa6, 0x3e, 0x57, 0x03, 0xb0, 0xca, 0x00, 0xfc, 0xf7, 0x60, 0x8d, 0x23, 0xa9, 0x8c,
0x4c, 0xcc, 0x97, 0x01, 0x6b, 0x40, 0x1f, 0x81, 0xa3, 0x13, 0x32, 0xd9, 0x2f, 0x5f, 0x5a, 0x62,
0xba, 0x0d, 0x9d, 0xd3, 0x68, 0xc6, 0x73, 0x19, 0xce, 0x52, 0x8c, 0xdf, 0x62, 0x15, 0xe1, 0x7f,
0x80, 0x9e, 0x3e, 0xa9, 0x12, 0x75, 0xc2, 0xe5, 0xbd, 0x74, 0xfc, 0x5e, 0x82, 0xef, 0xa7, 0xe7,
0x0b, 0x01, 0x5b, 0xd9, 0x8c, 0x89, 0x2c, 0x4d, 0xaa, 0x1a, 0xa7, 0x8b, 0x94, 0x97, 0x91, 0xe2,
0x37, 0xf5, 0xa0, 0x7b, 0x22, 0xb3, 0x28, 0xb9, 0x3c, 0x0b, 0xe3, 0x82, 0x97, 0x8e, 0xea, 0x94,
0xd2, 0x38, 0x49, 0xa4, 0x36, 0xdb, 0x28, 0x63, 0x89, 0x95, 0xc6, 0xb1, 0x10, 0xb1, 0x36, 0x36,
0x3d, 0x12, 0x38, 0xac, 0x22, 0xe8, 0x00, 0xe0, 0x30, 0x16, 0x61, 0x79, 0xb7, 0xe5, 0x91, 0x80,
0xb0, 0x1a, 0xe3, 0xef, 0x40, 0x5b, 0x45, 0xfa, 0x26, 0x4c, 0x2b, 0xb5, 0xe4, 0x01, 0xb5, 0xfe,
0x2d, 0x81, 0x8d, 0x77, 0x05, 0xcf, 0x16, 0x8c, 0x7f, 0x2a, 0x78, 0x8e, 0x55, 0x41, 0x5c, 0xaa,
0xd4, 0x40, 0x35, 0xc5, 0xc9, 0x55, 0x98, 0x4d, 0x75, 0xee, 0x6c, 0x56, 0x22, 0xa5, 0xb5, 0xca,
0x79, 0x8e, 0x5a, 0x1d, 0x56, 0xa7, 0xd4, 0x4d, 0xc6, 0x67, 0x42, 0x1a, 0x31, 0x25, 0xa2, 0x01,
0xfc, 0x7d, 0x70, 0x7d, 0x11, 0x17, 0x53, 0xce, 0xc4, 0x5c, 0xdf, 0x6e, 0xe1, 0x81, 0x75, 0x9a,
0x3e, 0x85, 0x7e, 0x49, 0x99, 0xc1, 0x69, 0xe3, 0xc1, 0x35, 0xd6, 0xbf, 0x21, 0xd0, 0x2b, 0xa5,
0xe4, 0xa9, 0x48, 0x72, 0xae, 0xea, 0x75, 0x90, 0x65, 0xa6, 0x5e, 0x07, 0x59, 0x46, 0x77, 0xa0,
0xcd, 0x78, 0x5e, 0xc4, 0xd2, 0x34, 0xc1, 0x7f, 0x55, 0x5a, 0xcc, 0xdd, 0x22, 0x96, 0xcc, 0x9c,
0xa2, 0x2f, 0xa0, 0xbf, 0xd2, 0x54, 0x7a, 0xf0, 0xba, 0xa3, 0xff, 0xab, 0x7b, 0x2b, 0x76, 0xb6,
0x76, 0xdc, 0xbf, 0x69, 0x40, 0xb7, 0xe6, 0x99, 0x3e, 0xc6, 0x35, 0x80, 0x31, 0x75, 0x47, 0xbd,
0xca, 0x0b, 0x13, 0x73, 0x86, 0x0b, 0x62, 0x03, 0xc8, 0x71, 0xd9, 0x4f, 0xe4, 0x58, 0x55, 0x51,
0x8d, 0xb6, 0x79, 0xb6, 0x56, 0x45, 0x45, 0x33, 0x6d, 0xc4, 0xa5, 0x72, 0x15, 0x26, 0x97, 0x7c,
0x8a, 0xfd, 0xe4, 0x30, 0x03, 0xe9, 0xb0, 0x9a, 0x4f, 0x2c, 0x40, 0x77, 0x44, 0x2b, 0x17, 0xc6,
0xc2, 0xaa, 0x19, 0x36, 0x0d, 0xad, 0x6a, 0xd1, 0x2b, 0x1b, 0x5a, 0x95, 0x50, 0xcd, 0xa6, 0x4a,
0x3c, 0x16, 0x5f, 0x23, 0xba, 0x0b, 0x3d, 0xdc, 0x0d, 0xe3, 0x05, 0xde, 0xcd, 0x5d, 0x07, 0x63,
0xfc, 0xa7, 0x7a, 0x60, 0xb9, 0x55, 0xd8, 0xea, 0x49, 0xff, 0x07, 0x81, 0xde, 0x64, 0x96, 0x8a,
0x4c, 0xd6, 0xfa, 0x6e, 0x92, 0x4c, 0xf9, 0xb5, 0xe9, 0x3b, 0x04, 0x8a, 0x3d, 0x8c, 0x78, 0x3c,
0xc5, 0x84, 0x74, 0x98, 0x06, 0x8a, 0xc5, 0xfe, 0xc3, 0x7e, 0xb3, 0x99, 0x06, 0xb5, 0x30, 0xed,
0x95, 0x30, 0xb7, 0xa1, 0x63, 0x36, 0x48, 0xee, 0x36, 0xd1, 0x54, 0x11, 0x6a, 0xa2, 0x96, 0x2b,
0x44, 0xb5, 0xa0, 0x15, 0x58, 0xac, 0xc6, 0xa8, 0xd4, 0x32, 0x31, 0xc7, 0x95, 0xdb, 0xc6, 0x7d,
0x68, 0xa0, 0xba, 0xa9, 0xdd, 0xa0, 0xd1, 0x41, 0x63, 0x8d, 0xf1, 0xbf, 0x12, 0xa0, 0x5a, 0x23,
0xce, 0xe6, 0x9f, 0x13, 0xfa, 0xb0, 0xa0, 0x2d, 0x68, 0xe1, 0x7b, 0x46, 0x4c, 0x89, 0xd6, 0xc2,
0x6d, 0xaf, 0x87, 0x3b, 0xde, 0xbc, 0xbd, 0x1b, 0x90, 0x6f, 0x77, 0x03, 0xf2, 0xfd, 0x6e, 0x40,
0x3e, 0xff, 0x1c, 0xfc, 0x75, 0xde, 0xc2, 0x5f, 0xd8, 0xb3, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff,
0x22, 0x44, 0x8c, 0x98, 0xd2, 0x06, 0x00, 0x00,
// 783 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0xdd, 0x6a, 0xdb, 0x48,
0x14, 0xde, 0xb1, 0x64, 0x5b, 0x3e, 0x8e, 0xbd, 0x61, 0x36, 0x9b, 0x15, 0x4b, 0xf0, 0x0a, 0xb1,
0x2c, 0x62, 0x2f, 0x1c, 0xf0, 0xc2, 0x42, 0x6f, 0x5a, 0xea, 0xfc, 0x14, 0x93, 0x26, 0xb4, 0x93,
0x34, 0xa5, 0x97, 0x4a, 0x3c, 0x24, 0x02, 0x59, 0xa3, 0x4a, 0x23, 0x1c, 0x3f, 0x47, 0x6e, 0xfa,
0x08, 0xbd, 0xe8, 0x83, 0xe4, 0xb2, 0x8f, 0xd0, 0xa6, 0x2f, 0x52, 0xe6, 0x8c, 0xc6, 0x92, 0x1d,
0x08, 0xbd, 0xe8, 0xdd, 0x7c, 0xe7, 0xcc, 0x1c, 0x7d, 0xdf, 0xf9, 0x13, 0x6c, 0xa4, 0xc5, 0x45,
0x1c, 0x5d, 0x0e, 0xd3, 0x4c, 0x48, 0x41, 0x9d, 0x28, 0x91, 0x3c, 0x4b, 0xc2, 0xd8, 0x7f, 0x07,
0x16, 0x13, 0x73, 0xea, 0x42, 0x7b, 0x4f, 0xc4, 0xc5, 0x2c, 0xc9, 0x5d, 0xe2, 0x59, 0x81, 0xcd,
0x0c, 0xa4, 0x7f, 0x43, 0xf3, 0xb9, 0x94, 0x59, 0xee, 0x36, 0x3c, 0x2b, 0xe8, 0x8e, 0xfa, 0x43,
0xf3, 0x74, 0xa8, 0xcc, 0x4c, 0x3b, 0x29, 0x05, 0xfb, 0x88, 0x2f, 0x72, 0xd7, 0xf2, 0xac, 0xa0,
0xc3, 0xf0, 0xec, 0x3f, 0x05, 0xfb, 0x55, 0x18, 0x65, 0xb4, 0x0f, 0x8d, 0xc9, 0xbe, 0x4b, 0x3c,
0x12, 0xd8, 0xac, 0x31, 0xd9, 0xa7, 0x5b, 0xd0, 0xdc, 0x13, 0x45, 0x22, 0xdd, 0x06, 0x9a, 0x34,
0xa0, 0x9b, 0x60, 0x1d, 0xf1, 0x85, 0x6b, 0x79, 0x24, 0xe8, 0x30, 0x75, 0xf4, 0xff, 0x07, 0xe7,
0x30, 0xe2, 0xf1, 0x54, 0xf1, 0xdb, 0x82, 0x26, 0x9e, 0x31, 0x4c, 0x87, 0x69, 0xa0, 0xac, 0x4c,
0xcc, 0x27, 0xfb, 0x26, 0x12, 0x02, 0xff, 0x18, 0x3a, 0x2f, 0x32, 0x51, 0xa4, 0x2f, 0xa3, 0x84,
0xd3, 0x7f, 0xa1, 0x85, 0x40, 0xeb, 0xea, 0x8e, 0x68, 0xc5, 0xdf, 0x04, 0x67, 0xe5, 0x0d, 0x15,
0xee, 0x4c, 0xc8, 0x30, 0x36, 0xe1, 0x10, 0xf8, 0x23, 0x70, 0xce, 0xc3, 0x78, 0x49, 0xf2, 0x3c,
0x8c, 0x91, 0x84, 0xc5, 0xd4, 0x71, 0x55, 0x8c, 0x55, 0x8a, 0xf1, 0xdf, 0x80, 0x35, 0x8e, 0x64,
0xc5, 0x8f, 0xd4, 0xf8, 0xd1, 0x3f, 0xc1, 0xd1, 0xc9, 0x5d, 0x12, 0x5f, 0x62, 0xba, 0x03, 0x9d,
0xb3, 0x68, 0xc6, 0x73, 0x19, 0xce, 0x52, 0xcc, 0x85, 0xc5, 0x2a, 0x83, 0xff, 0x16, 0x7a, 0xfa,
0xa6, 0x4a, 0xfa, 0x29, 0x97, 0x0f, 0x52, 0xfb, 0x63, 0xc5, 0x7a, 0x98, 0xea, 0x8f, 0x04, 0x6c,
0xe5, 0x33, 0x2e, 0xb2, 0x74, 0xa9, 0xca, 0x9e, 0x2d, 0x52, 0x5e, 0x32, 0xc5, 0x33, 0xf5, 0xa0,
0x7b, 0x2a, 0xb3, 0x28, 0xb9, 0x3a, 0x0f, 0xe3, 0x82, 0x97, 0x81, 0xea, 0x26, 0xa5, 0x71, 0x92,
0x48, 0xed, 0xb6, 0x51, 0xc6, 0x12, 0x2b, 0x8d, 0x63, 0x21, 0x62, 0xed, 0x6c, 0x7a, 0x24, 0x70,
0x58, 0x65, 0xa0, 0x03, 0x80, 0xc3, 0x58, 0x84, 0xe5, 0xdb, 0x96, 0x47, 0x02, 0xc2, 0x6a, 0x16,
0x7f, 0x17, 0xda, 0x8a, 0xe9, 0x71, 0x98, 0x56, 0x6a, 0xc9, 0x23, 0x6a, 0xfd, 0x3b, 0x02, 0x1b,
0xaf, 0x0b, 0x9e, 0x2d, 0x18, 0x7f, 0x5f, 0xf0, 0x1c, 0xab, 0x82, 0xd8, 0xf4, 0x12, 0x02, 0xba,
0x0d, 0xad, 0xd3, 0xeb, 0x30, 0x9b, 0xea, 0xdc, 0xd9, 0xac, 0x44, 0x4a, 0x6b, 0x95, 0xf3, 0x1c,
0xb5, 0x3a, 0xac, 0x6e, 0x52, 0x2f, 0x19, 0x9f, 0x09, 0x69, 0xc4, 0x94, 0x88, 0x06, 0xf0, 0xeb,
0xc1, 0xcd, 0x65, 0x5c, 0x4c, 0x39, 0x13, 0x73, 0xfd, 0xba, 0x85, 0x17, 0xd6, 0xcd, 0xf4, 0x1f,
0xe8, 0x97, 0x26, 0x33, 0x84, 0x6d, 0xbc, 0xb8, 0x66, 0xf5, 0x6f, 0x09, 0xf4, 0x4a, 0x29, 0x79,
0x2a, 0x92, 0x9c, 0xab, 0x7a, 0x1d, 0x64, 0x99, 0xa9, 0xd7, 0x41, 0x96, 0xd1, 0x5d, 0x68, 0x33,
0x9e, 0x17, 0xb1, 0x34, 0x4d, 0xf0, 0x7b, 0x95, 0x16, 0xf3, 0xb6, 0x88, 0x25, 0x33, 0xb7, 0xe8,
0x33, 0xe8, 0xaf, 0x34, 0x95, 0x1e, 0xe2, 0xee, 0xe8, 0x8f, 0xea, 0xdd, 0x8a, 0x9f, 0xad, 0x5d,
0xf7, 0x6f, 0x1b, 0xd0, 0xad, 0x45, 0xa6, 0x7f, 0xe1, 0x4a, 0x41, 0x4e, 0xdd, 0x51, 0xaf, 0x8a,
0xa2, 0x46, 0x0d, 0x97, 0xcd, 0x06, 0x90, 0x93, 0xb2, 0x9f, 0xc8, 0x89, 0xaa, 0xa2, 0x5a, 0x13,
0xe6, 0xb3, 0xb5, 0x2a, 0x2a, 0x33, 0xd3, 0x4e, 0x5c, 0x50, 0xd7, 0x61, 0x72, 0xc5, 0xa7, 0xd8,
0x4f, 0x0e, 0x33, 0x90, 0x0e, 0xab, 0xf9, 0xc4, 0x02, 0xac, 0xcc, 0xb8, 0xf1, 0xb0, 0x6a, 0x86,
0x4d, 0x43, 0xab, 0x5a, 0xf4, 0xca, 0x86, 0x56, 0x25, 0x54, 0xb3, 0xa9, 0x12, 0x8f, 0xc5, 0xd7,
0x88, 0x3e, 0x81, 0x1e, 0xee, 0x86, 0xf1, 0x02, 0xdf, 0xe6, 0xae, 0x83, 0x1c, 0x7f, 0xab, 0x3e,
0xb0, 0xdc, 0x34, 0x6c, 0xf5, 0xa6, 0xff, 0x95, 0x40, 0x6f, 0x32, 0x4b, 0x45, 0x26, 0x6b, 0x7d,
0x37, 0x49, 0xa6, 0xfc, 0xc6, 0xf4, 0x1d, 0x82, 0x6a, 0xb3, 0x35, 0xd6, 0x36, 0x1b, 0xf6, 0x1f,
0xf6, 0x9b, 0xcd, 0x34, 0xa8, 0xd1, 0xb4, 0x57, 0x68, 0xee, 0x40, 0xc7, 0x6c, 0x90, 0xdc, 0x6d,
0xa2, 0xab, 0x32, 0xa8, 0x89, 0x5a, 0xae, 0x10, 0xd5, 0x82, 0x56, 0x60, 0xb1, 0x9a, 0x45, 0xa5,
0x96, 0x89, 0x39, 0xae, 0xef, 0x36, 0xae, 0x6f, 0x03, 0xd5, 0x4b, 0x1d, 0x06, 0x9d, 0x0e, 0x3a,
0x6b, 0x16, 0xff, 0x13, 0x01, 0xaa, 0x35, 0xe2, 0x6c, 0xfe, 0x3c, 0xa1, 0x8f, 0x0b, 0xda, 0x86,
0x16, 0x7e, 0xcf, 0x88, 0x29, 0xd1, 0x1a, 0xdd, 0xf6, 0x3a, 0xdd, 0xf1, 0xe6, 0xdd, 0xfd, 0x80,
0x7c, 0xbe, 0x1f, 0x90, 0x2f, 0xf7, 0x03, 0xf2, 0xe1, 0xdb, 0xe0, 0x97, 0x8b, 0x16, 0xfe, 0x0e,
0xff, 0xfb, 0x1e, 0x00, 0x00, 0xff, 0xff, 0x1c, 0xa1, 0x99, 0xa7, 0x1e, 0x07, 0x00, 0x00,
}

View file

@ -14,9 +14,14 @@ message Pair {
uint64 Count = 2;
}
message FieldRow{
string Field = 1;
uint64 RowID = 2;
}
message GroupLine{
repeated string Groups = 1;
uint64 Total=2;
repeated FieldRow Groups = 1;
uint64 Total = 2;
}
message ValCount {