zoukankan      html  css  js  c++  java
  • Snowflake 全局唯一Id 生成

    /// <summary>
        /// From: https://github.com/twitter/snowflake
        /// An object that generates IDs.
        /// This is broken into a separate class in case
        /// we ever want to support multiple worker threads
        /// per process
        /// </summary>
        public class IdWorker
        {
            private long workerId;
            private long datacenterId;
            private long sequence = 0L;
    
            private static long twepoch = 1288834974657L;
    
            private static long workerIdBits = 5L;
            private static long datacenterIdBits = 5L;
            private static long maxWorkerId = -1L ^ (-1L << (int)workerIdBits);
            private static long maxDatacenterId = -1L ^ (-1L << (int)datacenterIdBits);
            private static long sequenceBits = 12L;
    
            private long workerIdShift = sequenceBits;
            private long datacenterIdShift = sequenceBits + workerIdBits;
            private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
            private long sequenceMask = -1L ^ (-1L << (int)sequenceBits);
    
            private long lastTimestamp = -1L;
            private static object syncRoot = new object();
    
            public IdWorker(long workerId, long datacenterId)
            {
    
                // sanity check for workerId
                if (workerId > maxWorkerId || workerId < 0)
                {
                    throw new ArgumentException(string.Format("worker Id can't be greater than %d or less than 0", maxWorkerId));
                }
                if (datacenterId > maxDatacenterId || datacenterId < 0)
                {
                    throw new ArgumentException(string.Format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
                }
                this.workerId = workerId;
                this.datacenterId = datacenterId;
            }
    
            public long nextId()
            {
                lock (syncRoot)
                {
                    long timestamp = timeGen();
    
                    if (timestamp < lastTimestamp)
                    {
                        throw new ApplicationException(string.Format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
                    }
    
                    if (lastTimestamp == timestamp)
                    {
                        sequence = (sequence + 1) & sequenceMask;
                        if (sequence == 0)
                        {
                            timestamp = tilNextMillis(lastTimestamp);
                        }
                    }
                    else
                    {
                        sequence = 0L;
                    }
    
                    lastTimestamp = timestamp;
    
                    return ((timestamp - twepoch) << (int)timestampLeftShift) | (datacenterId << (int)datacenterIdShift) | (workerId << (int)workerIdShift) | sequence;
                }
            }
    
            protected long tilNextMillis(long lastTimestamp)
            {
                long timestamp = timeGen();
                while (timestamp <= lastTimestamp)
                {
                    timestamp = timeGen();
                }
                return timestamp;
            }
    
            protected long timeGen()
            {
                return (long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
            }
        }
  • 相关阅读:
    ECC 构筑安全可靠的区块链
    代理模式和装饰者模式
    Context都没弄明白,还怎么做Android开发?
    如何在Android Studio中查看一个类的继承关系呢?
    Android控件的继承关系
    安卓控件体系结构
    Android View框架总结(三)View工作原理
    Laravel中用GuzzleHttp
    学习PHP好,还是Python好呢?
    ElasticSearch入门 第一篇:Windows下安装ElasticSearch
  • 原文地址:https://www.cnblogs.com/zery/p/6076464.html
Copyright © 2011-2022 走看看