package variant
import (
"encoding/binary"
"math"
"unsafe"
"github.com/apache/arrow-go/v18/arrow/endian"
"github.com/apache/arrow-go/v18/parquet/internal/debug"
)
func readLEU32(b []byte ) uint32 {
debug .Assert (len (b ) <= 4 , "buffer too large" )
debug .Assert (len (b ) >= 1 , "buffer too small" )
var result uint32
v := (*[4 ]byte )(unsafe .Pointer (&result ))
copy (v [:], b )
return endian .FromLE (result )
}
func readLEU64(b []byte ) uint64 {
debug .Assert (len (b ) <= 8 , "buffer too large" )
debug .Assert (len (b ) >= 1 , "buffer too small" )
var result uint64
v := (*[8 ]byte )(unsafe .Pointer (&result ))
copy (v [:], b )
return endian .FromLE (result )
}
func readExact[T int8 | int16 | int32 | int64 | float32 | float64 ](b []byte ) T {
debug .Assert (len (b ) >= binary .Size (T (0 )), "buffer size mismatch" )
var result T
binary .Decode (b , binary .LittleEndian , &result )
return result
}
func primitiveHeader(t PrimitiveType ) byte {
return (byte (t )<<2 | byte (BasicPrimitive ))
}
func shortStrHeader(sz int ) byte {
return byte (sz <<2 ) | byte (BasicShortString )
}
func arrayHeader(large bool , offsetSize uint8 ) byte {
var largeBit byte
if large {
largeBit = 1
}
return (largeBit << (basicTypeBits + 2 )) |
((offsetSize - 1 ) << basicTypeBits ) | byte (BasicArray )
}
func objectHeader(large bool , idSize , offsetSize uint8 ) byte {
var largeBit byte
if large {
largeBit = 1
}
return (largeBit << (basicTypeBits + 4 )) |
((idSize - 1 ) << (basicTypeBits + 2 )) |
((offsetSize - 1 ) << basicTypeBits ) | byte (BasicObject )
}
func intSize(v int ) uint8 {
debug .Assert (v <= metadataMaxSizeLimit , "size too large" )
debug .Assert (v >= 0 , "size cannot be negative" )
switch {
case v <= math .MaxUint8 :
return 1
case v <= math .MaxUint16 :
return 2
case v <= 0xFFFFFF :
return 3
default :
return 4
}
}
func writeOffset(buf []byte , v int , nbytes uint8 ) {
debug .Assert (nbytes <= 4 , "nbytes size too large" )
debug .Assert (nbytes >= 1 , "nbytes size too small" )
for i := range nbytes {
buf [i ] = byte ((v >> (i * 8 )) & 0xFF )
}
}
func valueSize(v []byte ) int {
basicType , typeInfo := v [0 ]&basicTypeMask , (v [0 ]>>basicTypeBits )&typeInfoMask
switch basicType {
case byte (BasicShortString ):
return 1 + int (typeInfo )
case byte (BasicObject ):
var szBytes uint8 = 1
if ((typeInfo >> 4 ) & 0x1 ) != 0 {
szBytes = 4
}
sz := readLEU32 (v [1 : 1 +szBytes ])
idSize , offsetSize := ((typeInfo >>2 )&0b11 )+1 , uint32 ((typeInfo &0b11 )+1 )
idStart := 1 + szBytes
offsetStart := uint32 (idStart ) + sz *uint32 (idSize )
dataStart := offsetStart + (sz +1 )*offsetSize
idx := offsetStart + sz *uint32 (offsetSize )
return int (dataStart + readLEU32 (v [idx :idx +offsetSize ]))
case byte (BasicArray ):
var szBytes uint8 = 1
if ((typeInfo >> 4 ) & 0x1 ) != 0 {
szBytes = 4
}
sz := readLEU32 (v [1 : 1 +szBytes ])
offsetSize , offsetStart := uint32 ((typeInfo &0b11 )+1 ), uint32 (1 +szBytes )
dataStart := offsetStart + (sz +1 )*offsetSize
idx := offsetStart + sz *uint32 (offsetSize )
return int (dataStart + readLEU32 (v [idx :idx +offsetSize ]))
default :
switch PrimitiveType (typeInfo ) {
case PrimitiveNull , PrimitiveBoolTrue , PrimitiveBoolFalse :
return 1
case PrimitiveInt8 :
return 2
case PrimitiveInt16 :
return 3
case PrimitiveInt32 , PrimitiveDate , PrimitiveFloat :
return 5
case PrimitiveInt64 , PrimitiveDouble , PrimitiveTimeMicrosNTZ ,
PrimitiveTimestampMicros , PrimitiveTimestampMicrosNTZ ,
PrimitiveTimestampNanos , PrimitiveTimestampNanosNTZ :
return 9
case PrimitiveDecimal4 :
return 6
case PrimitiveDecimal8 :
return 10
case PrimitiveDecimal16 :
return 18
case PrimitiveBinary , PrimitiveString :
return 5 + int (readLEU32 (v [1 :5 ]))
case PrimitiveUUID :
return 17
default :
panic ("unknown primitive type" )
}
}
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .