首页 > 编程语言 >雪花算法单线程实现-scala

雪花算法单线程实现-scala

时间:2023-08-22 21:24:54浏览次数:70  
标签:val sequence 单线程 timestamp scala lastTimestamp private 算法 id

雪花算法单线程实现-scala

参考blog

/**
 * [时间戳][数据标识id][机器id]
 */
object SnowFlake {
  // 开始时间(ms) 2023-08-01 00:00:00
  private val startTimestamp = 1690819200000L

  // 机器id所占的位数
  private val workerIdBits = 5L

  // 数据标识id所占的位数
  private val datacenterIdBits = 5L

  // 支持的最大机器id
  private val maxWorkerId = -1L ^ (-1L << workerIdBits)

  // 支持的最大数据标识id
  private val maxDatacenterId = -1L ^ (-1L << datacenterIdBits)

  // 序列在id中占的位数
  private val sequenceBits = 12L

  // 机器id左移位数
  private val workerIdShift = sequenceBits

  // 数据标识id向左移位
  private val datacenterIdShift = sequenceBits + workerIdBits

  // 时间截向左移
  private val timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits

  // 生成序列的掩码
  private val sequenceMask = -1L ^ (-1L << sequenceBits)

  // 毫秒内序列
  private var sequence = 0L

  // 上次生成ID的时间截
  private var lastTimestamp = -1L
  
  def apply(
             workerId: Long, // 工作机器id
             datacenterId: Long // 数据中心id
           ): Long = {

    if (workerId > maxWorkerId || workerId < 0) {
      throw new IllegalArgumentException(s"workerId=[$maxWorkerId] 数据范围错误")
    }
    if (datacenterId > maxDatacenterId || datacenterId < 0) {
      throw new IllegalArgumentException(s"datacenterId=[$maxDatacenterId] 数据范围错误")
    }

    var timestamp: Long = timeGen()
    if (timestamp < lastTimestamp) {
      throw new RuntimeException("当前时间小于上一次记录的时间戳")
    }

    if (timestamp == lastTimestamp) {
      sequence = (sequence + 1) & sequenceMask
      if (sequence == 0L) {
        timestamp = tilNextMillis(lastTimestamp)
      }
    } else {
      sequence = 0L
    }

    lastTimestamp = timestamp

    //                 时间戳                      |        数据中心                      |       机器标识               | 序列号
    ((timestamp - startTimestamp) << timestampLeftShift) |(datacenterId << datacenterIdShift) |(workerId << workerIdShift) | sequence
  }

  private def timeGen() : Long = {
    System.currentTimeMillis()
  }

  private def tilNextMillis(lastTimestamp: Long): Long = {
    var timestamp: Long = timeGen()
    while (timestamp <= lastTimestamp) {
      timestamp = timeGen()
    }
    timestamp
  }

  def main(args: Array[String]): Unit = {
    for (_ <- 1 to 10) {
      val id: Long = SnowFlake(1L, 1L)
      println(id)
    }
  }

}

标签:val,sequence,单线程,timestamp,scala,lastTimestamp,private,算法,id
From: https://www.cnblogs.com/jentreywang/p/17649706.html

相关文章

  • 算法学习-exKMP
    什么是exKMPexKMP(Z-Algorithm)是一个可以在\(O(|S|+|T|)\)的时间复杂度内求出\(T\)串的每个后缀与\(T\)的LCP(最长公共前缀)\(T\)串和\(S\)串每个后缀的LCP。的算法。算法过程首先回忆一下KMP算法,求\(nxt\)数组和两串匹配本质上没啥区别。所以我们尝试也将......
  • [算法学习笔记] O(nlogn)求最长上升子序列
    朴素dp求最长上升子序列大家应该都会朴素dp求最长上升子序列,简单回忆一下。我们令\(f_i\)表示以第\(i\)位元素为结尾的最长上升子序列长度。满足\(\forallj<i\),则有:\(f_i=max(f_i,f_j+1)[a_j<a_i]\)Explanation:\(a_i\)前面若有多个可以拼接的序列,则拼一个......
  • scala --半生对象
    半生对象理解如图: objectAccompany{defmain(args:Array[String]):Unit={println(ScalaPerson.sex)//底层等价于ScalaPerson$.MODULE$.sex()ScalaPerson.sayHi()//底层等价于ScalaPerson$.MODULE$.sayHi()}/***说明:*1、当在同一个文件中,有c......
  • 年薪40W,如何高效准备大厂AI算法岗面试?
    如果说求职是人生的一道坎,那么面试就是最难翻越的那一块砖。当你经历过大大小小的面试之后,就会发现不同的公司、不同的面试官问的问题都大同小异,因为企业对于挑选人才是有一些共性的要求的,只要在面试前根据高频问题提前准备,命中率几乎等于100%!但是,为什么还有很多技术精湛、经验丰富......
  • VNPY-网络交易(算法交易)
    fromvnpy.trader.constantimportDirectionfromvnpy.trader.objectimportTradeData,OrderData,TickDatafromvnpy.trader.engineimportBaseEnginefromvnpy.trader.constantimportOrderType,Offset,Directionfrom..templateimportAlgoTemplateimportmat......
  • [代码随想录]Day24-回溯算法part04
    题目:93.复原IP地址思路:函数参数:参数就一个stirng,path先收集ip地址的四个部分,最后存入res中时拼接成一个string,因此path和res都是[]string类型终止条件:当path有了ip的四个部分就终止;当然只有完全的把字符串遍历了才会存入res单层逻辑:先取1-3位,判断是不是0-255内的数并且没......
  • Redis系列19:LRU内存淘汰算法分析
    Redis系列1:深刻理解高性能Redis的本质Redis系列2:数据持久化提高可用性Redis系列3:高可用之主从架构Redis系列4:高可用之Sentinel(哨兵模式)Redis系列5:深入分析Cluster集群模式追求性能极致:Redis6.0的多线程模型追求性能极致:客户端缓存带来的革命Redis系列8:Bitmap实现亿万级......
  • 【算法】分治初步
    目录定义示例快速排序实现第k小三分法归并排序实现定义分治,字面上的解释是“分而治之”,就是把一个问题分成多个的相同或相似的子问题,直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。示例快速排序把原数组分成左右两段,保证左\(≤\)右,再对左右分别排序。实......
  • knn 算法的实现原理是怎样的
    K最近邻(K-NearestNeighbors,简称KNN)算法是一种用于分类和回归的基本机器学习算法。其原理是基于样本之间的距离度量,通过找出离待预测样本最近的K个训练样本,利用这K个样本的标签信息进行分类或回归预测。主要思想就是物以类聚人以群分的思想,关键就是KNN中K近邻中K的确定,和距离的定义......
  • java笔试手写算法面试题大全含答案
    1.统计一篇英文文章单词个数。publicclassWordCounting{publicstaticvoidmain(String[]args){try(FileReaderfr=newFileReader("a.txt")){intcounter=0;booleanstate=false;intcurrentChar;while((currentChar=fr.read())!=-1){if(currentChar=='......