mirror of https://github.com/usbharu/Hideout.git
feat: ID生成器を追加
This commit is contained in:
parent
8355df70cb
commit
7f11c1b605
|
@ -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