github.com/vc42/parquet-go@v0.0.0-20240320194221-1a9adb5f23f5/deprecated/int96.go (about) 1 package deprecated 2 3 import ( 4 "math/big" 5 "math/bits" 6 "unsafe" 7 ) 8 9 // Int96 is an implementation of the deprecated INT96 parquet type. 10 type Int96 [3]uint32 11 12 // Negative returns true if i is a negative value. 13 func (i Int96) Negative() bool { 14 return (i[2] >> 31) != 0 15 } 16 17 // Less returns true if i < j. 18 // 19 // The method implements a signed comparison between the two operands. 20 func (i Int96) Less(j Int96) bool { 21 if i.Negative() { 22 if !j.Negative() { 23 return true 24 } 25 } else { 26 if j.Negative() { 27 return false 28 } 29 } 30 for k := 2; k >= 0; k-- { 31 a, b := i[k], j[k] 32 switch { 33 case a < b: 34 return true 35 case a > b: 36 return false 37 } 38 } 39 return false 40 } 41 42 // Int converts i to a big.Int representation. 43 func (i Int96) Int() *big.Int { 44 z := new(big.Int) 45 z.Or(z, big.NewInt(int64(i[2])<<32|int64(i[1]))) 46 z.Lsh(z, 32) 47 z.Or(z, big.NewInt(int64(i[0]))) 48 return z 49 } 50 51 // String returns a string representation of i. 52 func (i Int96) String() string { 53 return i.Int().String() 54 } 55 56 // Len returns the minimum length in bits required to store the value of i. 57 func (i Int96) Len() int { 58 switch { 59 case i[2] != 0: 60 return 64 + bits.Len32(i[2]) 61 case i[1] != 0: 62 return 32 + bits.Len32(i[1]) 63 default: 64 return bits.Len32(i[0]) 65 } 66 } 67 68 // Int96ToBytes converts the slice of Int96 values to a slice of bytes sharing 69 // the same backing array. 70 func Int96ToBytes(data []Int96) []byte { 71 return unsafe.Slice(*(**byte)(unsafe.Pointer(&data)), 12*len(data)) 72 } 73 74 // BytesToInt96 converts the byte slice passed as argument to a slice of Int96 75 // sharing the same backing array. 76 // 77 // When the number of bytes in the input is not a multiple of 12, the function 78 // truncates it in the returned slice. 79 func BytesToInt96(data []byte) []Int96 { 80 return unsafe.Slice(*(**Int96)(unsafe.Pointer(&data)), len(data)/12) 81 } 82 83 func MaxLenInt96(data []Int96) int { 84 max := 0 85 for i := range data { 86 n := data[i].Len() 87 if n > max { 88 max = n 89 } 90 } 91 return max 92 } 93 94 func MinInt96(data []Int96) (min Int96) { 95 if len(data) > 0 { 96 min = data[0] 97 for _, v := range data[1:] { 98 if v.Less(min) { 99 min = v 100 } 101 } 102 } 103 return min 104 } 105 106 func MaxInt96(data []Int96) (max Int96) { 107 if len(data) > 0 { 108 max = data[0] 109 for _, v := range data[1:] { 110 if max.Less(v) { 111 max = v 112 } 113 } 114 } 115 return max 116 } 117 118 func MinMaxInt96(data []Int96) (min, max Int96) { 119 if len(data) > 0 { 120 min = data[0] 121 max = data[0] 122 for _, v := range data[1:] { 123 if v.Less(min) { 124 min = v 125 } 126 if max.Less(v) { 127 max = v 128 } 129 } 130 } 131 return min, max 132 } 133 134 func OrderOfInt96(data []Int96) int { 135 if len(data) > 1 { 136 if int96AreInAscendingOrder(data) { 137 return +1 138 } 139 if int96AreInDescendingOrder(data) { 140 return -1 141 } 142 } 143 return 0 144 } 145 146 func int96AreInAscendingOrder(data []Int96) bool { 147 for i := len(data) - 1; i > 0; i-- { 148 if data[i].Less(data[i-1]) { 149 return false 150 } 151 } 152 return true 153 } 154 155 func int96AreInDescendingOrder(data []Int96) bool { 156 for i := len(data) - 1; i > 0; i-- { 157 if data[i-1].Less(data[i]) { 158 return false 159 } 160 } 161 return true 162 }