-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit f431abb
Showing
8 changed files
with
180 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# EditorConfig is awesome: https://EditorConfig.org | ||
|
||
# top-most EditorConfig file | ||
root = true | ||
|
||
[*] | ||
indent_style = space | ||
indent_size = 4 | ||
end_of_line = lf | ||
charset = utf-8 | ||
trim_trailing_whitespace = true | ||
insert_final_newline = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
.vscode/ | ||
.cache/ | ||
*.macrocall | ||
tmpFile* | ||
*.gcno | ||
*.gcda | ||
|
||
target/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<div align="center"> | ||
<h1>snowflake4cj</h1> | ||
<p>Snowflake algorithm for Cangjie</p> | ||
</div> | ||
<p align="center"> | ||
<img alt="" src="https://img.shields.io/badge/release-v1.0.0-brightgreen" style="display: inline-block;" /> | ||
<img alt="" src="https://img.shields.io/badge/cjc-v0.55.3-brightgreen" style="display: inline-block;" /> | ||
</p> | ||
|
||
## 介绍 / Introduction | ||
|
||
snowflake4cj 是一个基于 Cangjie 的雪花算法实现。 | ||
|
||
snowflake4cj is a snowflake algorithm implementation based on Cangjie. | ||
|
||
## 安装 / Installation | ||
|
||
```toml | ||
# In the `dependencies` section of `cjpm.toml` | ||
snowflake4cj = { git = "https://github.com/gtn1024/snowflake4cj.git", tag = "v1.0.0" } | ||
``` | ||
|
||
## 使用 / Usage | ||
|
||
```cj | ||
import snowflake4cj.snowflake.Snowflake | ||
main(): Int64 { | ||
let snowflake = Snowflake(0, 0) | ||
for (i in 0..1000) { | ||
let id = snowflake.nextId() | ||
println(id) | ||
} | ||
return 0 | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
version = 0 | ||
|
||
[requires] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
[dependencies] | ||
|
||
[package] | ||
cjc-version = "0.55.3" | ||
compile-option = "" | ||
description = "Snowflake algorithm for Cangjie" | ||
link-option = "" | ||
name = "snowflake4cj" | ||
output-type = "dynamic" | ||
override-compile-option = "" | ||
src-dir = "" | ||
target-dir = "" | ||
version = "1.0.0" | ||
package-configuration = {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
package snowflake4cj |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package snowflake4cj.snowflake | ||
|
||
import std.time.* | ||
import std.sync.* | ||
|
||
public class Snowflake { | ||
internal let twepoch: Int64 = 1725148800000 | ||
internal let workerIdBits: Int64 = 5 | ||
internal let datacenterIdBits: Int64 = 5 | ||
internal let maxWorkerId: Int64 = -1 ^ (-1 << workerIdBits) | ||
internal let maxDatacenterId: Int64 = -1 ^ (-1 << datacenterIdBits) | ||
internal let sequenceBits: Int64 = 12 | ||
internal let workerIdShift: Int64 = sequenceBits | ||
internal let datacenterIdShift: Int64 = sequenceBits + workerIdBits | ||
internal let timestampLeftShift: Int64 = sequenceBits + workerIdBits + datacenterIdBits | ||
internal let sequenceMask: Int64 = -1 ^ (-1 << sequenceBits) | ||
|
||
internal let workerId: Int64 | ||
internal let datacenterId: Int64 | ||
internal var sequence: Int64 = 0 | ||
internal var lastTimestamp: Int64 = -1 | ||
|
||
public init(workerId: Int64, datacenterId: Int64) { | ||
if (workerId > maxWorkerId || workerId < 0) { | ||
throw IllegalArgumentException("workerId can't be greater than ${maxWorkerId} or less than 0") | ||
} | ||
|
||
if (datacenterId > maxDatacenterId || datacenterId < 0) { | ||
throw IllegalArgumentException("datacenterId can't be greater than ${maxWorkerId} or less than 0") | ||
} | ||
|
||
this.workerId = workerId | ||
this.datacenterId = datacenterId | ||
} | ||
|
||
let mtx = ReentrantMutex() | ||
|
||
public func nextId() { | ||
synchronized (mtx) { | ||
var timestamp = timeGen() | ||
|
||
if (timestamp < lastTimestamp) { | ||
throw IllegalStateException("Clock moved backwards. Refusing to generate id for ${lastTimestamp - timestamp} milliseconds") | ||
} | ||
|
||
if (lastTimestamp == timestamp) { | ||
sequence = (sequence + 1) & sequenceMask | ||
|
||
if (sequence == 0) { | ||
timestamp = tilNextMillis(lastTimestamp) | ||
} | ||
} else { | ||
sequence = 0 | ||
} | ||
|
||
lastTimestamp = timestamp | ||
|
||
((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift) | (workerId << workerIdShift) | sequence | ||
} | ||
} | ||
|
||
internal func tilNextMillis(lastTimestamp: Int64) { | ||
var timestamp = timeGen() | ||
|
||
while (timestamp <= lastTimestamp) { | ||
timestamp = timeGen() | ||
} | ||
|
||
timestamp | ||
} | ||
|
||
internal func timeGen() { | ||
DateTime.nowUTC().toUnixTimeStamp().toMilliseconds() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package snowflake4cj.snowflake | ||
|
||
import std.unittest.* | ||
import std.unittest.testmacro.* | ||
|
||
@Test | ||
func testSnowflake() { | ||
let snowflake = Snowflake(0, 0) | ||
var last = 0 | ||
for (i in 0..10000) { | ||
let new = snowflake.nextId() | ||
@Expect(new > last) | ||
} | ||
} | ||
|
||
@Test | ||
func testFailedWhenMachineIdIsInvalid() { | ||
for (i in -1..50) { | ||
for (j in -1..50) { | ||
if (i < 0 || i > 31 || j < 0 || j > 31) { | ||
@ExpectThrows[IllegalArgumentException]({ | ||
Snowflake(i, j) | ||
}) | ||
} else { | ||
let snowflake = Snowflake(i, j) | ||
let id = snowflake.nextId() | ||
@Expect(id > 0) | ||
} | ||
} | ||
} | ||
} |