github.com/grafana/pyroscope@v1.18.0/pkg/parquet/group.go (about) 1 package parquet 2 3 import ( 4 "reflect" 5 "strings" 6 "unicode" 7 "unicode/utf8" 8 9 "github.com/parquet-go/parquet-go" 10 "github.com/parquet-go/parquet-go/compress" 11 "github.com/parquet-go/parquet-go/deprecated" 12 "github.com/parquet-go/parquet-go/encoding" 13 "github.com/parquet-go/parquet-go/format" 14 ) 15 16 // Group allows to write a custom ordered schema. As opposed to parquet.Group which orders fields alphabethical as it is based on a map. 17 type Group []parquet.Field 18 19 func (g Group) String() string { 20 s := new(strings.Builder) 21 if err := parquet.PrintSchema(s, "", g); err != nil { 22 panic(err.Error()) 23 } 24 return s.String() 25 } 26 27 func (g Group) ID() int { return 0 } 28 29 func (g Group) Type() parquet.Type { return &groupType{} } 30 31 func (g Group) Optional() bool { return false } 32 33 func (g Group) Repeated() bool { return false } 34 35 func (g Group) Required() bool { return true } 36 37 func (g Group) Leaf() bool { return false } 38 39 func (g Group) Fields() []parquet.Field { 40 fields := make([]parquet.Field, len(g)) 41 copy(fields, g) 42 return fields 43 } 44 45 func (g Group) Encoding() encoding.Encoding { return nil } 46 47 func (g Group) Compression() compress.Codec { return nil } 48 49 func (g Group) GoType() reflect.Type { return goTypeOfGroup(g) } 50 51 func exportedStructFieldName(name string) string { 52 firstRune, size := utf8.DecodeRuneInString(name) 53 return string([]rune{unicode.ToUpper(firstRune)}) + name[size:] 54 } 55 56 func goTypeOfGroup(node parquet.Node) reflect.Type { 57 fields := node.Fields() 58 structFields := make([]reflect.StructField, len(fields)) 59 for i, field := range fields { 60 structFields[i].Name = exportedStructFieldName(field.Name()) 61 structFields[i].Type = field.GoType() 62 // TODO: can we reconstruct a struct tag that would be valid if a value 63 // of this type were passed to SchemaOf? 64 } 65 return reflect.StructOf(structFields) 66 } 67 68 func NewGroupField(name string, node parquet.Node) parquet.Field { 69 return &groupField{ 70 Node: node, 71 name: name, 72 } 73 } 74 75 type groupField struct { 76 parquet.Node 77 name string 78 } 79 80 type groupType struct{} 81 82 func (groupType) String() string { return "group" } 83 84 func (groupType) AssignValue(dst reflect.Value, src parquet.Value) error { return nil } 85 86 func (groupType) ConvertValue(val parquet.Value, typ parquet.Type) (parquet.Value, error) { 87 return val, nil 88 } 89 90 func (groupType) Kind() parquet.Kind { 91 panic("cannot call Kind on parquet group") 92 } 93 94 func (groupType) Compare(parquet.Value, parquet.Value) int { 95 panic("cannot compare values on parquet group") 96 } 97 98 func (groupType) NewColumnIndexer(int) parquet.ColumnIndexer { 99 panic("cannot create column indexer from parquet group") 100 } 101 102 func (groupType) NewDictionary(int, int, encoding.Values) parquet.Dictionary { 103 panic("cannot create dictionary from parquet group") 104 } 105 106 func (t groupType) NewColumnBuffer(int, int) parquet.ColumnBuffer { 107 panic("cannot create column buffer from parquet group") 108 } 109 110 func (t groupType) NewPage(int, int, encoding.Values) parquet.Page { 111 panic("cannot create page from parquet group") 112 } 113 114 func (t groupType) NewValues(_ []byte, _ []uint32) encoding.Values { 115 panic("cannot create values from parquet group") 116 } 117 118 func (groupType) Encode(_ []byte, _ encoding.Values, _ encoding.Encoding) ([]byte, error) { 119 panic("cannot encode parquet group") 120 } 121 122 func (groupType) Decode(_ encoding.Values, _ []byte, _ encoding.Encoding) (encoding.Values, error) { 123 panic("cannot decode parquet group") 124 } 125 126 func (groupType) EstimateDecodeSize(_ int, _ []byte, _ encoding.Encoding) int { 127 panic("cannot estimate decode size of parquet group") 128 } 129 130 func (groupType) Length() int { return 0 } 131 132 func (groupType) EstimateSize(int) int { return 0 } 133 134 func (groupType) EstimateNumValues(int) int { return 0 } 135 136 func (groupType) ColumnOrder() *format.ColumnOrder { return nil } 137 138 func (groupType) PhysicalType() *format.Type { return nil } 139 140 func (groupType) LogicalType() *format.LogicalType { return nil } 141 142 func (groupType) ConvertedType() *deprecated.ConvertedType { return nil } 143 144 func (f *groupField) Name() string { return f.name } 145 146 func (f *groupField) Value(base reflect.Value) reflect.Value { 147 if base.Kind() == reflect.Ptr { 148 if base.IsNil() { 149 base.Set(reflect.New(base.Type().Elem())) 150 } 151 return f.Value(base.Elem()) 152 } 153 return base.FieldByName(f.name) 154 }