mirror of https://github.com/containers/podman.git
142 lines
2.4 KiB
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})
|
|
}
|