github.com/parquet-go/parquet-go@v0.21.1-0.20240501160520-b3c3a0c3ed6f/encoding/delta/binary_packed_purego.go (about) 1 //go:build purego || !amd64 2 3 package delta 4 5 import ( 6 "encoding/binary" 7 ) 8 9 func encodeMiniBlockInt32(dst []byte, src *[miniBlockSize]int32, bitWidth uint) { 10 bitMask := uint32(1<<bitWidth) - 1 11 bitOffset := uint(0) 12 13 for _, value := range src { 14 i := bitOffset / 32 15 j := bitOffset % 32 16 17 lo := binary.LittleEndian.Uint32(dst[(i+0)*4:]) 18 hi := binary.LittleEndian.Uint32(dst[(i+1)*4:]) 19 20 lo |= (uint32(value) & bitMask) << j 21 hi |= (uint32(value) >> (32 - j)) 22 23 binary.LittleEndian.PutUint32(dst[(i+0)*4:], lo) 24 binary.LittleEndian.PutUint32(dst[(i+1)*4:], hi) 25 26 bitOffset += bitWidth 27 } 28 } 29 30 func encodeMiniBlockInt64(dst []byte, src *[miniBlockSize]int64, bitWidth uint) { 31 bitMask := uint64(1<<bitWidth) - 1 32 bitOffset := uint(0) 33 34 for _, value := range src { 35 i := bitOffset / 64 36 j := bitOffset % 64 37 38 lo := binary.LittleEndian.Uint64(dst[(i+0)*8:]) 39 hi := binary.LittleEndian.Uint64(dst[(i+1)*8:]) 40 41 lo |= (uint64(value) & bitMask) << j 42 hi |= (uint64(value) >> (64 - j)) 43 44 binary.LittleEndian.PutUint64(dst[(i+0)*8:], lo) 45 binary.LittleEndian.PutUint64(dst[(i+1)*8:], hi) 46 47 bitOffset += bitWidth 48 } 49 } 50 51 func decodeBlockInt32(block []int32, minDelta, lastValue int32) int32 { 52 for i := range block { 53 block[i] += minDelta 54 block[i] += lastValue 55 lastValue = block[i] 56 } 57 return lastValue 58 } 59 60 func decodeBlockInt64(block []int64, minDelta, lastValue int64) int64 { 61 for i := range block { 62 block[i] += minDelta 63 block[i] += lastValue 64 lastValue = block[i] 65 } 66 return lastValue 67 } 68 69 func decodeMiniBlockInt32(dst []int32, src []uint32, bitWidth uint) { 70 bitMask := uint32(1<<bitWidth) - 1 71 bitOffset := uint(0) 72 73 for n := range dst { 74 i := bitOffset / 32 75 j := bitOffset % 32 76 d := (src[i] & (bitMask << j)) >> j 77 if j+bitWidth > 32 { 78 k := 32 - j 79 d |= (src[i+1] & (bitMask >> k)) << k 80 } 81 dst[n] = int32(d) 82 bitOffset += bitWidth 83 } 84 } 85 86 func decodeMiniBlockInt64(dst []int64, src []uint32, bitWidth uint) { 87 bitMask := uint64(1<<bitWidth) - 1 88 bitOffset := uint(0) 89 90 for n := range dst { 91 i := bitOffset / 32 92 j := bitOffset % 32 93 d := (uint64(src[i]) & (bitMask << j)) >> j 94 if j+bitWidth > 32 { 95 k := 32 - j 96 d |= (uint64(src[i+1]) & (bitMask >> k)) << k 97 if j+bitWidth > 64 { 98 k := 64 - j 99 d |= (uint64(src[i+2]) & (bitMask >> k)) << k 100 } 101 } 102 dst[n] = int64(d) 103 bitOffset += bitWidth 104 } 105 }