diff --git a/src/main/kotlin/cn/tursom/core/DataOperate.kt b/src/main/kotlin/cn/tursom/core/DataOperate.kt index 656ca0b..a2fa9f0 100644 --- a/src/main/kotlin/cn/tursom/core/DataOperate.kt +++ b/src/main/kotlin/cn/tursom/core/DataOperate.kt @@ -111,10 +111,10 @@ fun ByteArray.toShort(offset: Int = 0): Short { fun ByteArray.toInt(offset: Int = 0): Int { return if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { this[offset].toInt() and 0xff or (this[offset + 1].toInt() shl 8 and 0xff00) or - (this[offset + 2].toInt() shl 16 and 0xff0000) or (this[offset + 3].toInt() shl 24 and 0xff000000.toInt()) + (this[offset + 2].toInt() shl 16 and 0xff0000) or (this[offset + 3].toInt() shl 24 and 0xff000000.toInt()) } else { this[offset + 3].toInt() and 0xff or (this[offset + 2].toInt() shl 8 and 0xff00) or - (this[offset + 1].toInt() shl 16 and 0xff0000) or (this[offset].toInt() shl 24 and 0xff000000.toInt()) + (this[offset + 1].toInt() shl 16 and 0xff0000) or (this[offset].toInt() shl 24 and 0xff000000.toInt()) } } @@ -695,13 +695,13 @@ inline fun toShort(get: () -> Byte): Short { inline fun toInt(get: () -> Byte): Int { return if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { get().toInt() and 0xff or (get().toInt() shl 8 and 0xff00) or - (get().toInt() shl 16 and 0xff0000) or (get().toInt() shl 24 and 0xff000000.toInt()) + (get().toInt() shl 16 and 0xff0000) or (get().toInt() shl 24 and 0xff000000.toInt()) } else { val i1 = get() val i2 = get() val i3 = get() get().toInt() and 0xff or (i3.toInt() shl 8 and 0xff00) or - (i2.toInt() shl 16 and 0xff0000) or (i1.toInt() shl 24 and 0xff000000.toInt()) + (i2.toInt() shl 16 and 0xff0000) or (i1.toInt() shl 24 and 0xff000000.toInt()) } } @@ -720,4 +720,29 @@ inline fun toFloat(get: () -> Byte): Float { inline fun toDouble(get: () -> Byte): Double { return Double.fromBits(toLong(get)) -} \ No newline at end of file +} + + +private val UPPER_HEX_ARRAY = "0123456789ABCDEF".toCharArray() +private val LOWER_HEX_ARRAY = "0123456789abcdef".toCharArray() + +private inline fun T.toHexString(upper: Boolean, length: Int, toBytes: ((Byte) -> Unit) -> Unit): String { + val hexArray = if (upper) UPPER_HEX_ARRAY else LOWER_HEX_ARRAY + val hexChars = CharArray(length) + var i = 0 + toBytes { b -> + @Suppress("NAME_SHADOWING") val b = b.toInt() + hexChars[i shl 1] = hexArray[b ushr 4 and 0x0F] + hexChars[(i shl 1) + 1] = hexArray[b and 0x0F] + i++ + } + return String(hexChars) +} + +fun Char.toHexString(upper: Boolean = true): String = toHexString(upper, 4, ::toBytes) +fun Short.toHexString(upper: Boolean = true): String = toHexString(upper, 4, ::toBytes) +fun Int.toHexString(upper: Boolean = true): String = toHexString(upper, 8, ::toBytes) +fun Long.toHexString(upper: Boolean = true): String = toHexString(upper, 16, ::toBytes) +fun Float.toHexString(upper: Boolean = true): String = toHexString(upper, 8, ::toBytes) +fun Double.toHexString(upper: Boolean = true): String = toHexString(upper, 16, ::toBytes) + diff --git a/src/main/kotlin/cn/tursom/core/Snowflake.kt b/src/main/kotlin/cn/tursom/core/Snowflake.kt index 3ea3930..65d2c4f 100644 --- a/src/main/kotlin/cn/tursom/core/Snowflake.kt +++ b/src/main/kotlin/cn/tursom/core/Snowflake.kt @@ -19,12 +19,13 @@ import java.util.concurrent.atomic.AtomicLong * * 当前最多支持 8192 个节点同时上线, 未来如果节点数超过了 8192 个, 也可以以ID生成的最晚时间为代价提升节点最高数量 */ -@Suppress("MemberVisibilityCanBePrivate", "CanBeParameter", "unused") +@Suppress("MemberVisibilityCanBePrivate") class Snowflake( @Suppress("MemberVisibilityCanBePrivate") val nodeId: Int, val executorService: ScheduledExecutorService? = null, val updateRateMs: Long = defaultUpdateRateMs, - val workMode: WorkMode = WorkMode.INCREMENT + val workMode: WorkMode = WorkMode.INCREMENT, + val incrementLength: Int = 7 ) { constructor( workerId: String, @@ -33,7 +34,7 @@ class Snowflake( workMode: WorkMode = WorkMode.INCREMENT ) : this(parseId(workerId), executorService, updateRateMs, workMode) - private var _timestamp = System.currentTimeMillis().and(0x00_00_07_ff__ff_ff_ff_ff).shl(7 + 13) + private var _timestamp = System.currentTimeMillis().shl(incrementLength + 13).and(0x7f_ff_ff_ff__ff_ff_ff_ff) set(value) { field = value seed = AtomicLong((nodeId and 0x1fff).toLong() or field) @@ -50,13 +51,13 @@ class Snowflake( when (workMode) { WorkMode.REALTIME -> { val timestamp = System.currentTimeMillis() - .and(0x00_00_07_ff__ff_ff_ff_ff) - .shl(7 + 13) - if (seed.get() < timestamp - 0x10_00_00) { + .shl(incrementLength + 13) + .and(0x7f_ff_ff_ff__ff_ff_ff_ff) + if (seed.get() < timestamp - 1.shl(incrementLength + 13)) { _timestamp = timestamp } } - WorkMode.INCREMENT -> _timestamp += 0x10_00_00 + WorkMode.INCREMENT -> _timestamp += 1.shl(incrementLength + 13) WorkMode.NO_INCREMENT -> { } } @@ -64,8 +65,8 @@ class Snowflake( } override fun toString() = "Snowflake(workerId=${nodeId - }, timestamp=0x${timestamp.toByteArray().toHexString(false) - }, seed=0x${seed.get().toByteArray().toHexString(false)})" + }, timestamp=0x${timestamp.toHexString(false) + }, seed=0x${seed.get().toHexString(false)})" enum class WorkMode { REALTIME, INCREMENT, NO_INCREMENT diff --git a/src/main/kotlin/cn/tursom/core/Tools.kt b/src/main/kotlin/cn/tursom/core/Tools.kt index 75a3cec..f7e7be3 100644 --- a/src/main/kotlin/cn/tursom/core/Tools.kt +++ b/src/main/kotlin/cn/tursom/core/Tools.kt @@ -53,6 +53,13 @@ inline fun usingTime(action: () -> T): Long { return t2 - t1 } +inline fun usingNanoTime(action: () -> T): Long { + val t1 = System.nanoTime() + action() + val t2 = System.nanoTime() + return t2 - t1 +} + inline fun Collection.toString(action: (T) -> Any): String { val iterator = iterator() if (!iterator.hasNext()) return "[]"