zoukankan      html  css  js  c++  java
  • guid.go

    package nsqd

    // the core algorithm here was borrowed from:
    // Blake Mizerany's `noeqd` https://github.com/bmizerany/noeqd
    // and indirectly:
    // Twitter's `snowflake` https://github.com/twitter/snowflake

    // only minor cleanup and changes to introduce a type, combine the concept
    // of workerID + datacenterId into a single identifier, and modify the
    // behavior when sequences rollover for our specific implementation needs

    import (
        "encoding/hex"
        "errors"
        "time"
    )

    const (
        workerIDBits   = uint64(10)
        sequenceBits   = uint64(12)
        workerIDShift  = sequenceBits
        timestampShift = sequenceBits + workerIDBits
        sequenceMask   = int64(-1) ^ (int64(-1) << sequenceBits)

        // ( 2012-10-28 16:23:42 UTC ).UnixNano() >> 20
        twepoch = int64(1288834974288)
    )

    var ErrTimeBackwards = errors.New("time has gone backwards")
    var ErrSequenceExpired = errors.New("sequence expired")
    var ErrIDBackwards = errors.New("ID went backward")

    type guid int64

    type guidFactory struct {
        sequence      int64
        lastTimestamp int64
        lastID        guid
    }

    func (f *guidFactory) NewGUID(workerID int64) (guid, error) {
        // divide by 1048576, giving pseudo-milliseconds
        ts := time.Now().UnixNano() >> 20

        if ts < f.lastTimestamp {
            return 0, ErrTimeBackwards
        }

        if f.lastTimestamp == ts {
            f.sequence = (f.sequence + 1) & sequenceMask
            if f.sequence == 0 {
                return 0, ErrSequenceExpired
            }
        } else {
            f.sequence = 0
        }

        f.lastTimestamp = ts

        id := guid(((ts - twepoch) << timestampShift) |
            (workerID << workerIDShift) |
            f.sequence)

        if id <= f.lastID {
            return 0, ErrIDBackwards
        }

        f.lastID = id

        return id, nil
    }

    func (g guid) Hex() MessageID {
        var h MessageID
        var b [8]byte

        b[0] = byte(g >> 56)
        b[1] = byte(g >> 48)
        b[2] = byte(g >> 40)
        b[3] = byte(g >> 32)
        b[4] = byte(g >> 24)
        b[5] = byte(g >> 16)
        b[6] = byte(g >> 8)
        b[7] = byte(g)

        hex.Encode(h[:], b[:])
        return h
    }

  • 相关阅读:
    二叉排序树(BST)创建,删除,查找操作
    Android中利用AIDL机制调用远程服务
    Android Studio更新升级方法
    C语言+ODBC+SQL 操作(向SQL里面添加数据)
    C语言+ODBC+SQL 连接
    macOS下 java+selenium+firefox 环境搭建
    php 上传二进制流图片 转存到图片格式 本地
    『工作の技术』突然想到的一些问题
    通过MySQL存储原理来分析排序和锁
    解析阿里开源混沌工程工具ChaosBlade是什么?
  • 原文地址:https://www.cnblogs.com/zhangboyu/p/7457316.html
Copyright © 2011-2022 走看看