Last active
April 16, 2019 04:12
-
-
Save thetooth/c795fee8b9afce946d24c7b612fefdde to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package seq | |
import ( | |
"fmt" | |
"time" | |
) | |
// DSN type for global ordering | |
type DSN struct { | |
Value uint64 | |
} | |
func (s *DSN) String() string { | |
return fmt.Sprintf("%v", s.Value) | |
} | |
// Time returns the time.Time of when the DSN was created | |
func (s *DSN) Time() time.Time { | |
var timestamp = int64(s.Value >> 22) | |
return time.Unix(timestamp, 0) | |
} | |
// Machine returns the machine identifier | |
func (s *DSN) Machine() uint { | |
return uint(s.Value & ((1 << 10) - 1)) | |
} | |
// Sequence returns the message sequence number | |
func (s *DSN) Sequence() uint { | |
return uint(s.Value & ((1 << 12) - 1)) | |
} | |
// Explain format | |
func (s *DSN) Explain() { | |
var timestamp = int64(s.Value >> 22) | |
var machine = s.Value & ((1 << 10) - 1) | |
var sequence = s.Value & ((1 << 12) - 1) | |
fmt.Printf(" %v%v%v\n", pad.Right("Time", 42, " "), pad.Right("Machine", 10, " "), pad.Right("Sequence", 12, " ")) | |
fmt.Printf(" %v%v%v\n\n", pad.Right(time.Unix(timestamp, 0).String(), 42, " "), pad.Left(fmt.Sprint(machine), 10, " "), pad.Left(fmt.Sprint(sequence), 12, " ")) | |
fmt.Printf(" %v\n", pad.Right(fmt.Sprintf("%042b", timestamp), 64, ".")) | |
fmt.Printf(" %v\n", pad.Left(pad.Right(fmt.Sprintf("%010b", machine), 22, "."), 64, ".")) | |
fmt.Printf(" %v\n\n", pad.Left(fmt.Sprintf("%012b", sequence), 64, ".")) | |
fmt.Printf(" (timestamp << 22) | (machine << 12) | sequence == %v\n\n", s.String()) | |
} | |
// New returns a new sequence type, if time stamp is 0, returns a new sequence | |
// with the current local time | |
func New(timestamp int64, machine, sequence uint) *DSN { | |
if timestamp == 0 { | |
timestamp = time.Now().Unix() | |
} | |
// 41 bit | 10 bit | 12 bit | |
return &DSN{Value: uint64(timestamp<<22) | uint64(machine<<12) | uint64(sequence)} | |
} | |
func times(str string, n int) (out string) { | |
for i := 0; i < n; i++ { | |
out += str | |
} | |
return | |
} | |
// Left left-pads the string with pad up to len runes | |
// len may be exceeded if | |
func Left(str string, len int, pad string) string { | |
return times(pad, len-utf8.RuneCountInString(str)) + str | |
} | |
// Right right-pads the string with pad up to len runes | |
func Right(str string, len int, pad string) string { | |
return str + times(pad, len-utf8.RuneCountInString(str)) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package seq_test | |
import ( | |
"testing" | |
"time" | |
"github.com/thetooth/test2/seq" | |
) | |
func TestNew(t *testing.T) { | |
var timestamp = time.Date(2018, 1, 1, 12, 34, 0, 0, time.Local).Unix() | |
var machine uint = 0x3FF | |
var sequence uint = 0xFFF | |
s := seq.New(timestamp, machine, sequence) | |
s.Explain() | |
if s.Value != 0x169265c43fffff { | |
t.Errorf("s.Value invalid %#x != 0x169265c43fffff", s.Value) | |
} | |
if s.String() != "////odzMpAsAAA==" { | |
t.Errorf("s.String() invalid %s != ////odzMpAsAAA==", s) | |
} | |
if s.Time() != time.Date(2018, 1, 1, 12, 34, 0, 0, time.Local) { | |
t.Errorf("s.Time() invalid") | |
} | |
if s.Machine() != 1023 { | |
t.Errorf("s.Machine() invalid") | |
} | |
if s.Sequence() != 4095 { | |
t.Errorf("s.Sequence() invalid") | |
} | |
} | |
func BenchmarkNew(b *testing.B) { | |
for i := 0; i < b.N; i++ { | |
s := seq.New(0, uint(i), uint(i)) | |
b.Log(s) | |
} | |
} | |
func BenchmarkGetters(b *testing.B) { | |
s := seq.New(time.Now().Unix(), 53, 1056) | |
for i := 0; i < b.N; i++ { | |
t := s.Time() | |
m := s.Machine() | |
seq := s.Sequence() | |
b.Log(t, m, seq) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment