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  }