github.com/segmentio/parquet-go@v0.0.0-20230712180008-5d42db8f0d47/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  // Int32ToInt96 converts a int32 value to a Int96.
    13  func Int32ToInt96(value int32) (i96 Int96) {
    14  	if value < 0 {
    15  		i96[2] = 0xFFFFFFFF
    16  		i96[1] = 0xFFFFFFFF
    17  	}
    18  	i96[0] = uint32(value)
    19  	return
    20  }
    21  
    22  // Int64ToInt96 converts a int64 value to Int96.
    23  func Int64ToInt96(value int64) (i96 Int96) {
    24  	if value < 0 {
    25  		i96[2] = 0xFFFFFFFF
    26  	}
    27  	i96[1] = uint32(value >> 32)
    28  	i96[0] = uint32(value)
    29  	return
    30  }
    31  
    32  // IsZero returns true if i is the zero-value.
    33  func (i Int96) IsZero() bool { return i == Int96{} }
    34  
    35  // Negative returns true if i is a negative value.
    36  func (i Int96) Negative() bool {
    37  	return (i[2] >> 31) != 0
    38  }
    39  
    40  // Less returns true if i < j.
    41  //
    42  // The method implements a signed comparison between the two operands.
    43  func (i Int96) Less(j Int96) bool {
    44  	if i.Negative() {
    45  		if !j.Negative() {
    46  			return true
    47  		}
    48  	} else {
    49  		if j.Negative() {
    50  			return false
    51  		}
    52  	}
    53  	for k := 2; k >= 0; k-- {
    54  		a, b := i[k], j[k]
    55  		switch {
    56  		case a < b:
    57  			return true
    58  		case a > b:
    59  			return false
    60  		}
    61  	}
    62  	return false
    63  }
    64  
    65  // Int converts i to a big.Int representation.
    66  func (i Int96) Int() *big.Int {
    67  	z := new(big.Int)
    68  	z.Or(z, big.NewInt(int64(i[2])<<32|int64(i[1])))
    69  	z.Lsh(z, 32)
    70  	z.Or(z, big.NewInt(int64(i[0])))
    71  	return z
    72  }
    73  
    74  // Int32 converts i to a int32, potentially truncating the value.
    75  func (i Int96) Int32() int32 {
    76  	return int32(i[0])
    77  }
    78  
    79  // Int64 converts i to a int64, potentially truncating the value.
    80  func (i Int96) Int64() int64 {
    81  	return int64(i[1])<<32 | int64(i[0])
    82  }
    83  
    84  // String returns a string representation of i.
    85  func (i Int96) String() string {
    86  	return i.Int().String()
    87  }
    88  
    89  // Len returns the minimum length in bits required to store the value of i.
    90  func (i Int96) Len() int {
    91  	switch {
    92  	case i[2] != 0:
    93  		return 64 + bits.Len32(i[2])
    94  	case i[1] != 0:
    95  		return 32 + bits.Len32(i[1])
    96  	default:
    97  		return bits.Len32(i[0])
    98  	}
    99  }
   100  
   101  // Int96ToBytes converts the slice of Int96 values to a slice of bytes sharing
   102  // the same backing array.
   103  func Int96ToBytes(data []Int96) []byte {
   104  	return unsafe.Slice(*(**byte)(unsafe.Pointer(&data)), 12*len(data))
   105  }
   106  
   107  // BytesToInt96 converts the byte slice passed as argument to a slice of Int96
   108  // sharing the same backing array.
   109  //
   110  // When the number of bytes in the input is not a multiple of 12, the function
   111  // truncates it in the returned slice.
   112  func BytesToInt96(data []byte) []Int96 {
   113  	return unsafe.Slice(*(**Int96)(unsafe.Pointer(&data)), len(data)/12)
   114  }
   115  
   116  func MaxLenInt96(data []Int96) int {
   117  	max := 0
   118  	for i := range data {
   119  		n := data[i].Len()
   120  		if n > max {
   121  			max = n
   122  		}
   123  	}
   124  	return max
   125  }
   126  
   127  func MinInt96(data []Int96) (min Int96) {
   128  	if len(data) > 0 {
   129  		min = data[0]
   130  		for _, v := range data[1:] {
   131  			if v.Less(min) {
   132  				min = v
   133  			}
   134  		}
   135  	}
   136  	return min
   137  }
   138  
   139  func MaxInt96(data []Int96) (max Int96) {
   140  	if len(data) > 0 {
   141  		max = data[0]
   142  		for _, v := range data[1:] {
   143  			if max.Less(v) {
   144  				max = v
   145  			}
   146  		}
   147  	}
   148  	return max
   149  }
   150  
   151  func MinMaxInt96(data []Int96) (min, max Int96) {
   152  	if len(data) > 0 {
   153  		min = data[0]
   154  		max = data[0]
   155  		for _, v := range data[1:] {
   156  			if v.Less(min) {
   157  				min = v
   158  			}
   159  			if max.Less(v) {
   160  				max = v
   161  			}
   162  		}
   163  	}
   164  	return min, max
   165  }
   166  
   167  func OrderOfInt96(data []Int96) int {
   168  	if len(data) > 1 {
   169  		if int96AreInAscendingOrder(data) {
   170  			return +1
   171  		}
   172  		if int96AreInDescendingOrder(data) {
   173  			return -1
   174  		}
   175  	}
   176  	return 0
   177  }
   178  
   179  func int96AreInAscendingOrder(data []Int96) bool {
   180  	for i := len(data) - 1; i > 0; i-- {
   181  		if data[i].Less(data[i-1]) {
   182  			return false
   183  		}
   184  	}
   185  	return true
   186  }
   187  
   188  func int96AreInDescendingOrder(data []Int96) bool {
   189  	for i := len(data) - 1; i > 0; i-- {
   190  		if data[i-1].Less(data[i]) {
   191  			return false
   192  		}
   193  	}
   194  	return true
   195  }