refactor: SnowflakeIdGenerateServiceを改良

This commit is contained in:
usbharu 2024-08-24 11:31:36 +09:00
parent 4dcec9e806
commit c872a837eb
Signed by: usbharu
GPG Key ID: 6556747BF94EEBC8
2 changed files with 15 additions and 20 deletions

View File

@ -24,9 +24,9 @@ import java.time.Instant
@Suppress("MagicNumber")
open class SnowflakeIdGenerateService(private val baseTime: Long) : IdGenerateService {
var lastTimeStamp: Long = -1
var sequenceId: Int = 0
val mutex = Mutex()
private var lastTimeStamp: Long = -1
private var sequenceId: Long = 0
private val mutex = Mutex()
@Throws(IllegalStateException::class)
override suspend fun generateId(): Long {
@ -34,7 +34,6 @@ open class SnowflakeIdGenerateService(private val baseTime: Long) : IdGenerateSe
var timestamp = getTime()
if (timestamp < lastTimeStamp) {
timestamp = wait(timestamp)
// throw IllegalStateException(" $lastTimeStamp $timestamp ${lastTimeStamp-timestamp} ")
}
if (timestamp == lastTimeStamp) {
sequenceId++
@ -46,7 +45,7 @@ open class SnowflakeIdGenerateService(private val baseTime: Long) : IdGenerateSe
sequenceId = 0
}
lastTimeStamp = timestamp
return@withLock (timestamp - baseTime).shl(22).or(1L.shl(12)).or(sequenceId.toLong())
return@withLock (timestamp - baseTime).shl(22).or(1L.shl(12)).or(sequenceId)
}
}
@ -77,8 +76,10 @@ open class SnowflakeIdGenerateService(private val baseTime: Long) : IdGenerateSe
override fun hashCode(): Int {
var result = baseTime.hashCode()
result = 31 * result + lastTimeStamp.hashCode()
result = 31 * result + sequenceId
result = 31 * result + sequenceId.hashCode()
result = 31 * result + mutex.hashCode()
return result
}
}

View File

@ -1,28 +1,22 @@
package dev.usbharu.hideout.core.infrastructure.other
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
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)
}
}
val mutableListOf = coroutineScope {
(1..10000).map {
async {
TwitterSnowflakeIdGenerateService.generateId()
}
}.awaitAll()
}
assertEquals(0, mutableListOf.size - mutableListOf.toSet().size)