featurebase/util/id.go
Ben Johnson 3c832591df move index package to root package
This commit moves the index package to the root. Because pilosa
is an index at its core, it's redundant to have an index
subpackage. It also provides better naming such as `pilosa.Bitmap`
instead of `index.Bitmap`.
2015-08-31 16:54:53 -06:00

129 lines
2.3 KiB
Go

package util
import (
"bytes"
"encoding/binary"
"encoding/hex"
"fmt"
"math/rand"
"os"
"strings"
"time"
log "github.com/cihub/seelog"
"github.com/gocql/gocql"
)
var (
counter = uint64(0)
Random *os.File
)
func init() {
rand.Seed(time.Now().UTC().UnixNano())
f, err := os.Open("/dev/urandom")
if err != nil {
log.Warn(err)
}
Random = f
}
type SUUID uint64
func Id() SUUID {
millis := uint64(time.Now().UTC().UnixNano())
id := millis << (64 - 41)
id |= uint64(rand.Intn(128)) << (64 - 41 - 13)
id |= counter % 1024
counter += 1
return SUUID(id)
}
func SUUID_to_Hex(a SUUID) string {
buf := new(bytes.Buffer)
binary.Write(buf, binary.BigEndian, a)
return hex.EncodeToString(buf.Bytes())
}
func Hex_to_SUUID(str string) SUUID {
l := len(str)
var m string
if l < 16 {
m = strings.Repeat("0", 16-l) + str
} else {
m = str
}
b, _ := hex.DecodeString(m)
num := binary.BigEndian.Uint64(b)
return SUUID(num)
}
type GUID [16]byte
// UnmarshalText parses a text value into a GUID.
// This is used by the TOML parser.
func (id *GUID) UnmarshalText(text []byte) error {
v, err := ParseGUID(string(text))
if err != nil {
return err
}
*id = v
return nil
}
func (self GUID) String() string {
var offsets = [...]int{0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34}
const hexString = "0123456789abcdef"
r := make([]byte, 36)
for i, b := range self {
r[offsets[i]] = hexString[b>>4]
r[offsets[i]+1] = hexString[b&0xF]
}
r[8] = '-'
r[13] = '-'
r[18] = '-'
r[23] = '-'
return string(r)
}
func Equal(a, b *GUID) bool {
for i, v := range a {
if v != b[i] {
return false
}
}
return true
}
func RandomUUID() GUID {
uid, _ := gocql.RandomUUID()
var r GUID
copy(r[:], uid[:])
return r
}
func ParseGUID(input string) (GUID, error) {
var u GUID
j := 0
for _, r := range input {
switch {
case r == '-' && j&1 == 0:
continue
case r >= '0' && r <= '9' && j < 32:
u[j/2] |= byte(r-'0') << uint(4-j&1*4)
case r >= 'a' && r <= 'f' && j < 32:
u[j/2] |= byte(r-'a'+10) << uint(4-j&1*4)
case r >= 'A' && r <= 'F' && j < 32:
u[j/2] |= byte(r-'A'+10) << uint(4-j&1*4)
default:
return GUID{}, fmt.Errorf("invalid GUID %q", input)
}
j += 1
}
if j != 32 {
return GUID{}, fmt.Errorf("invalid GUID %q", input)
}
return u, nil
}