storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/s3select/internal/parquet-go/encoding/plain-encode.go (about) 1 /* 2 * Minio Cloud Storage, (C) 2019 Minio, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package encoding 18 19 import ( 20 "bytes" 21 "encoding/binary" 22 "fmt" 23 "math" 24 25 "storj.io/minio/pkg/s3select/internal/parquet-go/gen-go/parquet" 26 ) 27 28 func plainEncodeBools(bs []bool) []byte { 29 data := make([]byte, (len(bs)+7)/8) 30 31 for i := range bs { 32 if bs[i] { 33 data[i/8] |= 1 << uint(i%8) 34 } 35 } 36 37 return data 38 } 39 40 func plainEncodeInt32s(i32s []int32) []byte { 41 data := make([]byte, len(i32s)*4) 42 43 for i, i32 := range i32s { 44 binary.LittleEndian.PutUint32(data[i*4:], uint32(i32)) 45 } 46 47 return data 48 } 49 50 func plainEncodeInt64s(i64s []int64) []byte { 51 data := make([]byte, len(i64s)*8) 52 53 for i, i64 := range i64s { 54 binary.LittleEndian.PutUint64(data[i*8:], uint64(i64)) 55 } 56 57 return data 58 } 59 60 func plainEncodeFloat32s(f32s []float32) []byte { 61 data := make([]byte, len(f32s)*4) 62 63 for i, f32 := range f32s { 64 binary.LittleEndian.PutUint32(data[i*4:], math.Float32bits(f32)) 65 } 66 67 return data 68 } 69 70 func plainEncodeFloat64s(f64s []float64) []byte { 71 data := make([]byte, len(f64s)*8) 72 73 for i, f64 := range f64s { 74 binary.LittleEndian.PutUint64(data[i*8:], math.Float64bits(f64)) 75 } 76 77 return data 78 } 79 80 func plainEncodeBytesSlices(bytesSlices [][]byte) []byte { 81 buf := new(bytes.Buffer) 82 83 for _, s := range bytesSlices { 84 if err := binary.Write(buf, binary.LittleEndian, uint32(len(s))); err != nil { 85 panic(err) 86 } 87 88 if _, err := buf.Write(s); err != nil { 89 panic(err) 90 } 91 } 92 93 return buf.Bytes() 94 } 95 96 // PlainEncode encodes values specified in https://github.com/apache/parquet-format/blob/master/Encodings.md#plain-plain--0 97 // 98 // Supported Types: BOOLEAN, INT32, INT64, FLOAT, DOUBLE, BYTE_ARRAY 99 func PlainEncode(values interface{}, parquetType parquet.Type) []byte { 100 switch parquetType { 101 case parquet.Type_BOOLEAN: 102 bs, ok := values.([]bool) 103 if !ok { 104 panic(fmt.Errorf("expected slice of bool")) 105 } 106 return plainEncodeBools(bs) 107 case parquet.Type_INT32: 108 i32s, ok := values.([]int32) 109 if !ok { 110 panic(fmt.Errorf("expected slice of int32")) 111 } 112 return plainEncodeInt32s(i32s) 113 case parquet.Type_INT64: 114 i64s, ok := values.([]int64) 115 if !ok { 116 panic(fmt.Errorf("expected slice of int64")) 117 } 118 return plainEncodeInt64s(i64s) 119 case parquet.Type_FLOAT: 120 f32s, ok := values.([]float32) 121 if !ok { 122 panic(fmt.Errorf("expected slice of float32")) 123 } 124 return plainEncodeFloat32s(f32s) 125 case parquet.Type_DOUBLE: 126 f64s, ok := values.([]float64) 127 if !ok { 128 panic(fmt.Errorf("expected slice of float64")) 129 } 130 return plainEncodeFloat64s(f64s) 131 case parquet.Type_BYTE_ARRAY: 132 bytesSlices, ok := values.([][]byte) 133 if !ok { 134 panic(fmt.Errorf("expected slice of byte array")) 135 } 136 return plainEncodeBytesSlices(bytesSlices) 137 } 138 139 panic(fmt.Errorf("%v parquet type unsupported", parquetType)) 140 }