ironsmith/datastore/key.go
Tim Shannon b9c945ed92 Fixed several issues, contineued web work
Fixed lots of issues with thread saftey and had to rethink some stuff

Fixed order issues with timekeys
Starting to flesh out the web REST API
2016-04-06 21:59:24 +00:00

86 lines
2.0 KiB
Go

// Copyright 2016 Tim Shannon. All rights reserved.
// Use of this source code is governed by the MIT license
// that can be found in the LICENSE file.
package datastore
import (
"crypto/rand"
"encoding/hex"
"fmt"
"io"
"time"
)
// TimeKey is a unique time ordered key for use in the datastore
// A TimeKey is 32 bits random data + 96 bit UNIX timestamp (64bits seconds + 32 bit nanoseconds)
type TimeKey [16]byte
// NewTimeKey returns a newly generated TimeKey based on the current time
func NewTimeKey() TimeKey {
rBits := make([]byte, 32/8)
_, err := io.ReadFull(rand.Reader, rBits)
if err != nil {
panic(fmt.Sprintf("Error generating random values for New TimeKey: %v", err))
}
t := time.Now()
sec := t.Unix()
nsec := t.Nanosecond()
return TimeKey{
byte(sec >> 56), // seconds
byte(sec >> 48),
byte(sec >> 40),
byte(sec >> 32),
byte(sec >> 24),
byte(sec >> 16),
byte(sec >> 8),
byte(sec),
byte(nsec >> 24), // nanoseconds
byte(nsec >> 16),
byte(nsec >> 8),
byte(nsec),
rBits[0], //random
rBits[1],
rBits[2],
rBits[3],
}
}
// Time returns the time portion of a timekey
func (k TimeKey) Time() time.Time {
buf := k[:]
sec := int64(buf[7]) | int64(buf[6])<<8 | int64(buf[5])<<16 | int64(buf[4])<<24 |
int64(buf[3])<<32 | int64(buf[2])<<40 | int64(buf[1])<<48 | int64(buf[0])<<56
buf = buf[8:]
nsec := int32(buf[3]) | int32(buf[2])<<8 | int32(buf[1])<<16 | int32(buf[0])<<24
return time.Unix(sec, int64(nsec))
}
// UUID returns the string representation of a TimeKey in Hex format separated by dashes
// similar to a UUID xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
func (k TimeKey) UUID() string {
buf := make([]byte, 36)
hex.Encode(buf[0:8], k[0:4])
buf[8] = '-'
hex.Encode(buf[9:13], k[4:6])
buf[13] = '-'
hex.Encode(buf[14:18], k[6:8])
buf[18] = '-'
hex.Encode(buf[19:23], k[8:10])
buf[23] = '-'
hex.Encode(buf[24:], k[10:])
return string(buf)
}
// Bytes returns the a slice of the underlying bytes of a TimeKey
func (k TimeKey) Bytes() []byte {
return []byte(k[:])
}