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  }