Skip to content

Instantly share code, notes, and snippets.

@kamijin-fanta
Created November 29, 2016 02:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kamijin-fanta/6ee4d543d43268c9858d3db76f9b6773 to your computer and use it in GitHub Desktop.
Save kamijin-fanta/6ee4d543d43268c9858d3db76f9b6773 to your computer and use it in GitHub Desktop.
scalaVersion := "2.11.8"
ibraryDependencies ++= Seq(
"org.apache.commons" % "commons-lang3" % "3.5"
)
import org.apache.commons.lang3.RandomUtils
sealed abstract class FlakeSalt {
def getSalt(): Int = RandomUtils.nextInt(0, Int.MaxValue)
}
object FlakeSalt {
case class Random() extends FlakeSalt {
override def getSalt(): Int= {
RandomUtils.nextInt(0, Int.MaxValue)
}
}
}
case class Flake(flakeSalt: FlakeSalt = FlakeSalt.Random()){
private val saltBits = 12L
private val sequenceBits = 10L
private val sequenceMask = -1L ^ (-1L << sequenceBits)
private val timestampShift = sequenceBits + saltBits
private val saltShift = sequenceBits
def twepoch = 1451574000000L
val salt = flakeSalt.getSalt() & 0x3ff // 10bits
private var lastTimestamp = 0L
private var sequence = 0L
def getNext() = synchronized {
var timestamp = getCurrentTime()
val timeOffset = twepoch - timestamp
if(lastTimestamp == timestamp){
sequence = (sequence + 1) & sequenceMask
if(sequence==0){
println("TilNextMilss...")
timestamp = tilNextMillis(timestamp)
}
} else {
sequence = 0
}
lastTimestamp = timestamp
((timestamp - twepoch) << timestampShift) | (salt << saltShift) | sequence
}
protected def tilNextMillis(lastTimestamp: Long): Long = {
var timestamp = getCurrentTime()
while (timestamp <= lastTimestamp) {
timestamp = getCurrentTime()
}
timestamp
}
protected def getCurrentTime() = {
System.currentTimeMillis()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment