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
}

guid.go的更多相关文章

  1. UniqueIdentifier 数据类型 和 GUID 生成函数

    UniqueIdentifier 数据类型用于存储GUID的值,占用16Byte. SQL Server将UniqueIdentifier存储为16字节的二进制数值,Binary(16),按照特定的格 ...

  2. System.Guid ToString五中格式

    参考:https://msdn.microsoft.com/en-us/library/97af8hh4.aspx 测试代码: using System; using System.Collectio ...

  3. EF里Guid类型数据的自增长、时间戳和复杂类型的用法

    通过前两章Lodging和Destination类的演示,大家肯定基本了解Code First是怎么玩的了,本章继续演示一些很实用的东西.文章的开头提示下:提供的demo为了后面演示效果,前面代码有些 ...

  4. 为Guid数据类型的属性(property)赋值

    先来看看数据库表中的字段设计: 在数据库的数据类型为uniqueidentifier. 而在程序中对应的数据类型为GUID. property有get和set,也就是说能获取值也可以赋值.

  5. Guid的使用

    今天在公司做修改功能时,老大让使用部分更新,但是表中的主键是UNIQUEIDENTIFIER类型,它会在我们添加纪录时,默认生成一个unicode码, 但是我现在必须要将获取到的已经是string类型 ...

  6. GUID生成器

    这个GUID生成器是一个小巧的软件,属于笔者在空余时间开发的. http://pan.baidu.com/s/1sk6VGpn

  7. 使用Guid做主键和int做主键性能比较

    使用Guid做主键和int做主键性能比较 在数据库的设计中我们常常用Guid或int来做主键,根据所学的知识一直感觉int做主键效率要高,但没有做仔细的测试无法 说明道理.碰巧今天在数据库的优化过程中 ...

  8. 生成GUID唯一值的方法汇总(dotnet/javascript/sqlserver)

    一.在 .NET 中生成1.直接用.NET Framework 提供的 Guid() 函数,此种方法使用非常广泛.GUID(全局统一标识符)是指在一台机器上生成的数字,它保证对在同一时空中的任何两台计 ...

  9. SQLSERVER如何使用递增排序的GUID做主键

    场景: 产品表数据量较大想用Guid做表的主键,并在此字段上建立聚簇索引. 因为Guid是随机生成的,生成的值大小是不确定的,每次生成的数可能很大,也可能很小.这样会影响插入的效率 1.NEWSEQU ...

  10. COM 组件基础——GUID 和 接口

    一.前言 书接上回,话说在 doc(Word) 复合文件中,已经解决了保存 xls(Excel) 数据的问题了.那么,接下来又要解决另一个问题:当 WORD 程序读取复合文件,遇到了 xls 数据的时 ...

随机推荐

  1. javascript中正则表达式和ruby中的一点差异

    看到一个例子,不过这个例子中正则表达式的格式貌似是错的: Function.prototype.get_name = function(){ return this.name || this.toSt ...

  2. Java数据结构面试题,输出 最后一个 出现次数为1的字符

    今天去面试,遇到一个数据结构题,给定一个字符串,输出 最后一个 出现次数为1的字符 回来研究了下,代码如下: package com.pine.interview.test; import java. ...

  3. Spring Cloud入门教程-Ribbon实现客户端负载均衡

    简介 我们继续以之前博客的代码为基础,增加Ribbon组件来提供客户端负载均衡.负载均衡是实现高并发.高性能.可伸缩服务的重要组成部分,它可以把请求分散到一个集群中不同的服务器中,以减轻每个服务器的负 ...

  4. JavaScript设计模式之一Interface接口

    如何用面向对象的思想来写JavaScript,对于初学者应该是比较难的,我们经常用的JQuery其实也是用面向对象的思想去封装的,今天我们来看看如何在Javascript中用Interface,在C# ...

  5. Activiti初学问题,求解

    <userTask id="writeReportTask" name="Write monthly financial report" > < ...

  6. Android之动画

    Android的动画可以分为三种,View动画.帧动画.属性动画.View动画通过对场景里的对象不断做图像变化(平移.缩放.旋转.透明度)从而产生动画效果,它是一种渐进式动画,而且View动画支持自定 ...

  7. JqueryMobile学习记录一

    安装 做页面之前首先引用三个文件: <link href="/Scripts/jquery.mobile-1.4.5/jquery.mobile-1.4.5.css" rel ...

  8. hadoop配置文件详解系列(二)-hdfs-site.xml篇

    上一篇介绍了core-site.xml的配置,本篇继续介绍hdfs-site.xml的配置. 属性名称 属性值 描述 hadoop.hdfs.configuration.version 1 配置文件的 ...

  9. JVM学习记录-垃圾回收算法

    简述 因为各个平台的虚拟机的垃圾收集器的实现各有不同,所以只介绍几个常见的垃圾收集算法. JVM中常见的垃圾收集算法有以下四种: 标记-清除算法(Mark-Sweep). 复制算法(Copying). ...

  10. “蝉原则”与CSS3随机多背景随机圆角等效果

    一.什么是“蝉原则”? “蝉原则”,英文称作“cicada principle”,是一种让事物的重复出现符合“自然随机性”的规则,为什么这么说呢? “蝉原则”源自于北美,中国似乎并未有这样的说法,这背 ...