Skip to content

Commit

Permalink
Merge pull request #4423 from xiang90/id
Browse files Browse the repository at this point in the history
pkg/idutil: reduce conflict rate from 1% to 0.005%
  • Loading branch information
xiang90 committed Feb 4, 2016
2 parents 0cdf1c4 + e44e753 commit 60085a0
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 9 deletions.
2 changes: 1 addition & 1 deletion etcdserver/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) {
lstats: lstats,
SyncTicker: time.Tick(500 * time.Millisecond),
peerRt: prt,
reqIDGen: idutil.NewGenerator(uint8(id), time.Now()),
reqIDGen: idutil.NewGenerator(uint16(id), time.Now()),
forceVersionC: make(chan struct{}),
msgSnapC: make(chan raftpb.Message, maxInFlightMsgSnap),
}
Expand Down
12 changes: 6 additions & 6 deletions pkg/idutil/id.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ import (

const (
tsLen = 5 * 8
cntLen = 2 * 8
cntLen = 8
suffixLen = tsLen + cntLen
)

// The initial id is in this format:
// High order byte is memberID, next 5 bytes are from timestamp,
// and low order 2 bytes are 0s.
// | prefix | suffix |
// | 1 byte | 5 bytes | 2 bytes |
// | 2 bytes | 5 bytes | 1 byte |
// | memberID | timestamp | cnt |
//
// The timestamp 5 bytes is different when the machine is restart
Expand All @@ -42,16 +42,16 @@ const (
// The count field may overflow to timestamp field, which is intentional.
// It helps to extend the event window to 2^56. This doesn't break that
// id generated after restart is unique because etcd throughput is <<
// 65536req/ms.
// 256req/ms(250k reqs/second).
type Generator struct {
mu sync.Mutex
// high order byte
// high order 2 bytes
prefix uint64
// low order 7 bytes
// low order 6 bytes
suffix uint64
}

func NewGenerator(memberID uint8, now time.Time) *Generator {
func NewGenerator(memberID uint16, now time.Time) *Generator {
prefix := uint64(memberID) << suffixLen
unixMilli := uint64(now.UnixNano()) / uint64(time.Millisecond/time.Nanosecond)
suffix := lowbit(unixMilli, tsLen) << cntLen
Expand Down
4 changes: 2 additions & 2 deletions pkg/idutil/id_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
func TestNewGenerator(t *testing.T) {
g := NewGenerator(0x12, time.Unix(0, 0).Add(0x3456*time.Millisecond))
id := g.Next()
wid := uint64(0x1200000034560001)
wid := uint64(0x12000000345601)
if id != wid {
t.Errorf("id = %x, want %x", id, wid)
}
Expand All @@ -45,7 +45,7 @@ func TestNewGeneratorUnique(t *testing.T) {

func TestNext(t *testing.T) {
g := NewGenerator(0x12, time.Unix(0, 0).Add(0x3456*time.Millisecond))
wid := uint64(0x1200000034560001)
wid := uint64(0x12000000345601)
for i := 0; i < 1000; i++ {
id := g.Next()
if id != wid+uint64(i) {
Expand Down

0 comments on commit 60085a0

Please sign in to comment.