mirror of https://github.com/usbharu/Hideout.git
feat: ID生成器を追加
This commit is contained in:
parent
6151fd8a0a
commit
6bc01f6552
|
@ -0,0 +1,5 @@
|
|||
package dev.usbharu.hideout.service
|
||||
|
||||
interface IdGenerateService {
|
||||
suspend fun generateId():Long
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package dev.usbharu.hideout.service
|
||||
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import java.time.Instant
|
||||
|
||||
open class SnowflakeIdGenerateService(private val baseTime:Long) : IdGenerateService {
|
||||
var lastTimeStamp: Long = -1
|
||||
var sequenceId: Int = 0
|
||||
val mutex = Mutex()
|
||||
|
||||
@Throws(IllegalStateException::class)
|
||||
override suspend fun generateId(): Long {
|
||||
return mutex.withLock {
|
||||
|
||||
var timestamp = getTime()
|
||||
if (timestamp < lastTimeStamp) {
|
||||
while (timestamp <= lastTimeStamp) {
|
||||
delay(1L)
|
||||
timestamp = getTime()
|
||||
}
|
||||
// throw IllegalStateException(" $lastTimeStamp $timestamp ${lastTimeStamp-timestamp} ")
|
||||
}
|
||||
if (timestamp == lastTimeStamp) {
|
||||
sequenceId++
|
||||
if (sequenceId >= 4096) {
|
||||
while (timestamp <= lastTimeStamp) {
|
||||
delay(1L)
|
||||
timestamp = getTime()
|
||||
}
|
||||
sequenceId = 0
|
||||
}
|
||||
} else {
|
||||
sequenceId = 0
|
||||
}
|
||||
lastTimeStamp = timestamp
|
||||
return@withLock (timestamp - baseTime).shl(22).or(1L.shl(12)).or(sequenceId.toLong())
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private fun getTime(): Long {
|
||||
return Instant.now().toEpochMilli()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package dev.usbharu.hideout.service
|
||||
|
||||
// 2010-11-04T01:42:54.657
|
||||
object TwitterSnowflakeIdGenerateService : SnowflakeIdGenerateService(1288834974657L)
|
|
@ -0,0 +1,35 @@
|
|||
package dev.usbharu.hideout.service
|
||||
|
||||
//import kotlinx.coroutines.NonCancellable.message
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class TwitterSnowflakeIdGenerateServiceTest {
|
||||
@Test
|
||||
fun noDuplicateTest() = runBlocking {
|
||||
val mutex = Mutex()
|
||||
val mutableListOf = mutableListOf<Long>()
|
||||
coroutineScope {
|
||||
|
||||
repeat(500000) {
|
||||
|
||||
launch(Dispatchers.IO) {
|
||||
val id = TwitterSnowflakeIdGenerateService.generateId()
|
||||
mutex.withLock {
|
||||
mutableListOf.add(id)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals(0, mutableListOf.size - mutableListOf.toSet().size)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue