podman/vendor/github.com/segmentio/ksuid/uint128.go

142 lines
2.4 KiB
Go

package ksuid
import "fmt"
// uint128 represents an unsigned 128 bits little endian integer.
type uint128 [2]uint64
func uint128Payload(ksuid KSUID) uint128 {
return makeUint128FromPayload(ksuid[timestampLengthInBytes:])
}
func makeUint128(high uint64, low uint64) uint128 {
return uint128{low, high}
}
func makeUint128FromPayload(payload []byte) uint128 {
return uint128{
// low
uint64(payload[8])<<56 |
uint64(payload[9])<<48 |
uint64(payload[10])<<40 |
uint64(payload[11])<<32 |
uint64(payload[12])<<24 |
uint64(payload[13])<<16 |
uint64(payload[14])<<8 |
uint64(payload[15]),
// high
uint64(payload[0])<<56 |
uint64(payload[1])<<48 |
uint64(payload[2])<<40 |
uint64(payload[3])<<32 |
uint64(payload[4])<<24 |
uint64(payload[5])<<16 |
uint64(payload[6])<<8 |
uint64(payload[7]),
}
}
func (v uint128) ksuid(timestamp uint32) KSUID {
return KSUID{
// time
byte(timestamp >> 24),
byte(timestamp >> 16),
byte(timestamp >> 8),
byte(timestamp),
// high
byte(v[1] >> 56),
byte(v[1] >> 48),
byte(v[1] >> 40),
byte(v[1] >> 32),
byte(v[1] >> 24),
byte(v[1] >> 16),
byte(v[1] >> 8),
byte(v[1]),
// low
byte(v[0] >> 56),
byte(v[0] >> 48),
byte(v[0] >> 40),
byte(v[0] >> 32),
byte(v[0] >> 24),
byte(v[0] >> 16),
byte(v[0] >> 8),
byte(v[0]),
}
}
func (v uint128) bytes() [16]byte {
return [16]byte{
// high
byte(v[1] >> 56),
byte(v[1] >> 48),
byte(v[1] >> 40),
byte(v[1] >> 32),
byte(v[1] >> 24),
byte(v[1] >> 16),
byte(v[1] >> 8),
byte(v[1]),
// low
byte(v[0] >> 56),
byte(v[0] >> 48),
byte(v[0] >> 40),
byte(v[0] >> 32),
byte(v[0] >> 24),
byte(v[0] >> 16),
byte(v[0] >> 8),
byte(v[0]),
}
}
func (v uint128) String() string {
return fmt.Sprintf("0x%016X%016X", v[0], v[1])
}
const wordBitSize = 64
func cmp128(x, y uint128) int {
if x[1] < y[1] {
return -1
}
if x[1] > y[1] {
return 1
}
if x[0] < y[0] {
return -1
}
if x[0] > y[0] {
return 1
}
return 0
}
func add128(x, y uint128) (z uint128) {
x0 := x[0]
y0 := y[0]
z0 := x0 + y0
z[0] = z0
c := (x0&y0 | (x0|y0)&^z0) >> (wordBitSize - 1)
z[1] = x[1] + y[1] + c
return
}
func sub128(x, y uint128) (z uint128) {
x0 := x[0]
y0 := y[0]
z0 := x0 - y0
z[0] = z0
c := (y0&^x0 | (y0|^x0)&z0) >> (wordBitSize - 1)
z[1] = x[1] - y[1] - c
return
}
func incr128(x uint128) uint128 {
return add128(x, uint128{1, 0})
}