diff --git a/C#/README.md b/C#.NET/README.md
similarity index 100%
rename from C#/README.md
rename to C#.NET/README.md
diff --git a/C#/source/.gitignore b/C#.NET/source/.gitignore
similarity index 100%
rename from C#/source/.gitignore
rename to C#.NET/source/.gitignore
diff --git a/C#/source/Yitter.IdGen.sln b/C#.NET/source/Yitter.IdGen.sln
similarity index 100%
rename from C#/source/Yitter.IdGen.sln
rename to C#.NET/source/Yitter.IdGen.sln
diff --git a/C#/source/Yitter.IdGenTest/GenTest.cs b/C#.NET/source/Yitter.IdGenTest/GenTest.cs
similarity index 100%
rename from C#/source/Yitter.IdGenTest/GenTest.cs
rename to C#.NET/source/Yitter.IdGenTest/GenTest.cs
diff --git a/C#/source/Yitter.IdGenTest/Program.cs b/C#.NET/source/Yitter.IdGenTest/Program.cs
similarity index 100%
rename from C#/source/Yitter.IdGenTest/Program.cs
rename to C#.NET/source/Yitter.IdGenTest/Program.cs
diff --git a/C#/source/Yitter.IdGenTest/Yitter.IdGenTest.csproj b/C#.NET/source/Yitter.IdGenTest/Yitter.IdGenTest.csproj
similarity index 100%
rename from C#/source/Yitter.IdGenTest/Yitter.IdGenTest.csproj
rename to C#.NET/source/Yitter.IdGenTest/Yitter.IdGenTest.csproj
diff --git a/C#/source/Yitter.IdGenerator/Contract/IIdGenerator.cs b/C#.NET/source/Yitter.IdGenerator/Contract/IIdGenerator.cs
similarity index 100%
rename from C#/source/Yitter.IdGenerator/Contract/IIdGenerator.cs
rename to C#.NET/source/Yitter.IdGenerator/Contract/IIdGenerator.cs
diff --git a/C#/source/Yitter.IdGenerator/Contract/ISnowWorker.cs b/C#.NET/source/Yitter.IdGenerator/Contract/ISnowWorker.cs
similarity index 100%
rename from C#/source/Yitter.IdGenerator/Contract/ISnowWorker.cs
rename to C#.NET/source/Yitter.IdGenerator/Contract/ISnowWorker.cs
diff --git a/C#/source/Yitter.IdGenerator/Contract/IdGeneratorOptions.cs b/C#.NET/source/Yitter.IdGenerator/Contract/IdGeneratorOptions.cs
similarity index 95%
rename from C#/source/Yitter.IdGenerator/Contract/IdGeneratorOptions.cs
rename to C#.NET/source/Yitter.IdGenerator/Contract/IdGeneratorOptions.cs
index 8b8d24b..cf58fdf 100644
--- a/C#/source/Yitter.IdGenerator/Contract/IdGeneratorOptions.cs
+++ b/C#.NET/source/Yitter.IdGenerator/Contract/IdGeneratorOptions.cs
@@ -22,7 +22,7 @@ namespace Yitter.IdGenerator
public virtual short Method { get; set; } = 1;
///
- /// 开始时间(UTC格式)
+ /// 基础时间(UTC格式)
/// 不能超过当前系统时间
///
public virtual DateTime BaseTime { get; set; } = new DateTime(2020, 2, 20, 2, 20, 2, 20, DateTimeKind.Utc);
diff --git a/C#/source/Yitter.IdGenerator/Contract/OverCostActionArg.cs b/C#.NET/source/Yitter.IdGenerator/Contract/OverCostActionArg.cs
similarity index 100%
rename from C#/source/Yitter.IdGenerator/Contract/OverCostActionArg.cs
rename to C#.NET/source/Yitter.IdGenerator/Contract/OverCostActionArg.cs
diff --git a/C#/source/Yitter.IdGenerator/Core/SnowWorkerM1.cs b/C#.NET/source/Yitter.IdGenerator/Core/SnowWorkerM1.cs
similarity index 100%
rename from C#/source/Yitter.IdGenerator/Core/SnowWorkerM1.cs
rename to C#.NET/source/Yitter.IdGenerator/Core/SnowWorkerM1.cs
diff --git a/C#/source/Yitter.IdGenerator/Core/SnowWorkerM2.cs b/C#.NET/source/Yitter.IdGenerator/Core/SnowWorkerM2.cs
similarity index 100%
rename from C#/source/Yitter.IdGenerator/Core/SnowWorkerM2.cs
rename to C#.NET/source/Yitter.IdGenerator/Core/SnowWorkerM2.cs
diff --git a/C#/source/Yitter.IdGenerator/DefaultIdGenerator.cs b/C#.NET/source/Yitter.IdGenerator/DefaultIdGenerator.cs
similarity index 100%
rename from C#/source/Yitter.IdGenerator/DefaultIdGenerator.cs
rename to C#.NET/source/Yitter.IdGenerator/DefaultIdGenerator.cs
diff --git a/C#/source/Yitter.IdGenerator/YitIdHelper.cs b/C#.NET/source/Yitter.IdGenerator/YitIdHelper.cs
similarity index 100%
rename from C#/source/Yitter.IdGenerator/YitIdHelper.cs
rename to C#.NET/source/Yitter.IdGenerator/YitIdHelper.cs
diff --git a/C#/source/Yitter.IdGenerator/Yitter.IdGenerator.csproj b/C#.NET/source/Yitter.IdGenerator/Yitter.IdGenerator.csproj
similarity index 100%
rename from C#/source/Yitter.IdGenerator/Yitter.IdGenerator.csproj
rename to C#.NET/source/Yitter.IdGenerator/Yitter.IdGenerator.csproj
diff --git a/Go/README.md b/Go/README.md
index aab2eef..8440593 100644
--- a/Go/README.md
+++ b/Go/README.md
@@ -1,4 +1,22 @@
# idgenerator
-something is going on.
+## Go
+1.go 1.16
+2. ĬϲGOROOTʽ룬ΪGo-Modules
+
+
+## Goʾ
+```
+var yid = idgen.YitIdHelper{}
+fmt.Println(yid.NextId())
+
+// Զ
+var options = contract.NewIdGeneratorOptions(1)
+//options.WorkerIdBitLength = 6
+//options.SeqBitLength = 6
+//options.TopOverCostCount = 2000
+//options.BaseTime = time.Date(2020, 2, 20, 2, 20, 2, 20, time.UTC).UnixNano() / 1e6
+yid.SetIdGenerator(options)
+
+```
diff --git a/Go/source/test/main.go b/Go/source/test/main.go
new file mode 100644
index 0000000..0d96aa9
--- /dev/null
+++ b/Go/source/test/main.go
@@ -0,0 +1,36 @@
+package main
+
+import (
+ "../yitidgen/contract"
+ "../yitidgen/idgen"
+ "fmt"
+ "time"
+)
+
+func main() {
+ // 方法一:直接采用默认方法生成一个Id
+ var yid = idgen.YitIdHelper{}
+ fmt.Println(yid.NextId())
+
+ // 方法二:自定义参数
+ var options = contract.NewIdGeneratorOptions(1)
+ //options.WorkerIdBitLength = 6
+ //options.SeqBitLength = 6
+ //options.TopOverCostCount = 2000
+ //options.BaseTime = time.Date(2020, 2, 20, 2, 20, 2, 20, time.UTC).UnixNano() / 1e6
+ yid.SetIdGenerator(options)
+
+ var times = 50000
+
+ for ; ; {
+ var begin = time.Now().UnixNano() / 1e6
+ for i := 0; i < times; i++ {
+ yid.NextId()
+ }
+ var end = time.Now().UnixNano() / 1e6
+
+ fmt.Println(end - begin)
+ time.Sleep(time.Duration(1000) * time.Millisecond)
+ }
+
+}
diff --git a/Go/source/yitidgen/contract/IIdGenerator.go b/Go/source/yitidgen/contract/IIdGenerator.go
new file mode 100644
index 0000000..88f0675
--- /dev/null
+++ b/Go/source/yitidgen/contract/IIdGenerator.go
@@ -0,0 +1,5 @@
+package contract
+
+type IIdGenerator interface {
+ NewLong() uint64
+}
diff --git a/Go/source/yitidgen/contract/ISnowWorker.go b/Go/source/yitidgen/contract/ISnowWorker.go
new file mode 100644
index 0000000..b15b562
--- /dev/null
+++ b/Go/source/yitidgen/contract/ISnowWorker.go
@@ -0,0 +1,5 @@
+package contract
+
+type ISnowWorker interface {
+ NextId() uint64
+}
diff --git a/Go/source/yitidgen/contract/IdGeneratorException.go b/Go/source/yitidgen/contract/IdGeneratorException.go
new file mode 100644
index 0000000..f1b280f
--- /dev/null
+++ b/Go/source/yitidgen/contract/IdGeneratorException.go
@@ -0,0 +1,12 @@
+package contract
+
+import "fmt"
+
+type IdGeneratorException struct {
+ message string
+ error error
+}
+
+func (e IdGeneratorException) IdGeneratorException(message ...interface{}) {
+ fmt.Println(message)
+}
diff --git a/Go/source/yitidgen/contract/IdGeneratorOptions.go b/Go/source/yitidgen/contract/IdGeneratorOptions.go
new file mode 100644
index 0000000..c46e032
--- /dev/null
+++ b/Go/source/yitidgen/contract/IdGeneratorOptions.go
@@ -0,0 +1,25 @@
+package contract
+
+type IdGeneratorOptions struct {
+ Method uint16 // 雪花计算方法,(1-漂移算法|2-传统算法),默认1
+ BaseTime int64 // 基础时间,不能超过当前系统时间
+ WorkerId uint16 // 机器码,与 WorkerIdBitLength 有关系
+ WorkerIdBitLength byte // 机器码位长,范围:1-21(要求:序列数位长+机器码位长不超过22)
+ SeqBitLength byte // 序列数位长,范围:2-21(要求:序列数位长+机器码位长不超过22)
+ MaxSeqNumber uint32 // 最大序列数(含),(由SeqBitLength计算的最大值)
+ MinSeqNumber uint32 // 最小序列数(含),默认5,不小于1,不大于MaxSeqNumber
+ TopOverCostCount uint // 最大漂移次数(含),默认2000,推荐范围500-10000(与计算能力有关)
+}
+
+func NewIdGeneratorOptions(workerId uint16) *IdGeneratorOptions {
+ return &IdGeneratorOptions{
+ Method: 1,
+ WorkerId: workerId,
+ BaseTime: 1582136402000,
+ WorkerIdBitLength: 6,
+ SeqBitLength: 6,
+ MaxSeqNumber: 0,
+ MinSeqNumber: 5,
+ TopOverCostCount: 2000,
+ }
+}
diff --git a/Go/source/yitidgen/contract/OverCostActionArg.go b/Go/source/yitidgen/contract/OverCostActionArg.go
new file mode 100644
index 0000000..405aa05
--- /dev/null
+++ b/Go/source/yitidgen/contract/OverCostActionArg.go
@@ -0,0 +1,19 @@
+package contract
+
+type OverCostActionArg struct {
+ ActionType int
+ TimeTick int64
+ WorkerId int64
+ OverCostCountInOneTerm int
+ GenCountInOneTerm int
+ TermIndex int
+}
+
+func (ocaa OverCostActionArg) OverCostActionArg(workerId int64, timeTick int64, actionType int, overCostCountInOneTerm int, genCountWhenOverCost int, index int) {
+ ocaa.ActionType = actionType
+ ocaa.TimeTick = timeTick
+ ocaa.WorkerId = workerId
+ ocaa.OverCostCountInOneTerm = overCostCountInOneTerm
+ ocaa.GenCountInOneTerm = genCountWhenOverCost
+ ocaa.TermIndex = index
+}
diff --git a/Go/source/yitidgen/core/snowWorkerM1.go b/Go/source/yitidgen/core/snowWorkerM1.go
new file mode 100644
index 0000000..52063dd
--- /dev/null
+++ b/Go/source/yitidgen/core/snowWorkerM1.go
@@ -0,0 +1,203 @@
+package core
+
+import (
+ "../contract"
+ "math"
+ "sync"
+ "time"
+)
+
+type SnowWorkerM1 struct {
+ BaseTime int64 //基础时间
+ WorkerId uint16 //机器码
+ WorkerIdBitLength byte //机器码位长
+ SeqBitLength byte //自增序列数位长
+ MaxSeqNumber uint32 //最大序列数(含)
+ MinSeqNumber uint32 //最小序列数(含)
+ TopOverCostCount uint //最大漂移次数
+ _TimestampShift byte
+ _CurrentSeqNumber uint32
+ _LastTimeTick int64
+ _TurnBackTimeTick int64
+ _TurnBackIndex byte
+ _IsOverCost bool
+ _OverCostCountInOneTerm uint
+ _GenCountInOneTerm uint
+ _TermIndex uint
+ sync.Mutex
+}
+
+func NewSnowWorkerM1(options *contract.IdGeneratorOptions) contract.ISnowWorker {
+ var WorkerIdBitLength byte
+ var SeqBitLength byte
+ var MaxSeqNumber uint32
+
+ var WorkerId = options.WorkerId
+
+ if options.WorkerIdBitLength == 0 {
+ WorkerIdBitLength = 6
+ } else {
+ WorkerIdBitLength = options.WorkerIdBitLength
+ }
+ if options.SeqBitLength == 0 {
+ SeqBitLength = 6
+ } else {
+ SeqBitLength = options.SeqBitLength
+ }
+ if options.MaxSeqNumber > 0 {
+ MaxSeqNumber = options.MaxSeqNumber
+ } else {
+ MaxSeqNumber = uint32(math.Pow(2, float64(options.SeqBitLength))) - 1
+ }
+ var MinSeqNumber = options.MinSeqNumber
+ var TopOverCostCount = options.TopOverCostCount
+
+ var BaseTime int64
+ if options.BaseTime != 0 {
+ BaseTime = options.BaseTime
+ } else {
+ BaseTime = 1582136402000
+ }
+ timestampShift := (byte)(options.WorkerIdBitLength + options.SeqBitLength)
+ currentSeqNumber := options.MinSeqNumber
+ return &SnowWorkerM1{
+ BaseTime: BaseTime,
+ WorkerId: WorkerId,
+ WorkerIdBitLength: WorkerIdBitLength,
+ SeqBitLength: SeqBitLength,
+ MaxSeqNumber: MaxSeqNumber,
+ MinSeqNumber: MinSeqNumber,
+ TopOverCostCount: TopOverCostCount,
+ _TimestampShift: timestampShift,
+ _CurrentSeqNumber: currentSeqNumber}
+}
+
+func (m1 *SnowWorkerM1) DoGenIdAction(arg *contract.OverCostActionArg) {
+
+}
+
+func (m1 *SnowWorkerM1) BeginOverCostAction(useTimeTick int64) {
+
+}
+
+func (m1 *SnowWorkerM1) EndOverCostAction(useTimeTick int64) {
+ if m1._TermIndex > 10000 {
+ m1._TermIndex = 0
+ }
+}
+
+func (m1 *SnowWorkerM1) BeginTurnBackAction(useTimeTick int64) {
+
+}
+
+func (m1 *SnowWorkerM1) EndTurnBackAction(useTimeTick int64) {
+
+}
+
+func (m1 *SnowWorkerM1) NextOverCostId() uint64 {
+ currentTimeTick := m1.GetCurrentTimeTick()
+ if currentTimeTick > m1._LastTimeTick {
+ m1.EndOverCostAction(currentTimeTick)
+ m1._LastTimeTick = currentTimeTick
+ m1._CurrentSeqNumber = m1.MinSeqNumber
+ m1._IsOverCost = false
+ m1._OverCostCountInOneTerm = 0
+ m1._GenCountInOneTerm = 0
+ return m1.CalcId(m1._LastTimeTick)
+ }
+ if m1._OverCostCountInOneTerm >= m1.TopOverCostCount {
+ m1.EndOverCostAction(currentTimeTick)
+ m1._LastTimeTick = m1.GetNextTimeTick()
+ m1._CurrentSeqNumber = m1.MinSeqNumber
+ m1._IsOverCost = false
+ m1._OverCostCountInOneTerm = 0
+ m1._GenCountInOneTerm = 0
+ return m1.CalcId(m1._LastTimeTick)
+ }
+ if m1._CurrentSeqNumber > m1.MaxSeqNumber {
+ m1._LastTimeTick++
+ m1._CurrentSeqNumber = m1.MinSeqNumber
+ m1._IsOverCost = true
+ m1._OverCostCountInOneTerm++
+ m1._GenCountInOneTerm++
+
+ return m1.CalcId(m1._LastTimeTick)
+ }
+ m1._GenCountInOneTerm++
+ return m1.CalcId(m1._LastTimeTick)
+}
+
+func (m1 *SnowWorkerM1) NextNormalId() uint64 {
+ currentTimeTick := m1.GetCurrentTimeTick()
+ if currentTimeTick < m1._LastTimeTick {
+ if m1._TurnBackTimeTick < 1 {
+ m1._TurnBackTimeTick = m1._LastTimeTick - 1
+ m1._TurnBackIndex++
+ // 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序
+ // 最多4次回拨(防止回拨重叠)
+ if m1._TurnBackIndex > 4 {
+ m1._TurnBackIndex = 1
+ }
+ m1.BeginTurnBackAction(m1._TurnBackTimeTick)
+ }
+ time.Sleep(time.Duration(10) * time.Millisecond)
+ return m1.CalcTurnBackId(m1._TurnBackTimeTick)
+ }
+ // 时间追平时,_TurnBackTimeTick清零
+ if m1._TurnBackTimeTick > 0 {
+ m1.EndTurnBackAction(m1._TurnBackTimeTick)
+ m1._TurnBackTimeTick = 0
+ }
+ if currentTimeTick > m1._LastTimeTick {
+ m1._LastTimeTick = currentTimeTick
+ m1._CurrentSeqNumber = m1.MinSeqNumber
+ return m1.CalcId(m1._LastTimeTick)
+ }
+ if m1._CurrentSeqNumber > m1.MaxSeqNumber {
+ m1.BeginOverCostAction(currentTimeTick)
+ m1._TermIndex++
+ m1._LastTimeTick++
+ m1._CurrentSeqNumber = m1.MinSeqNumber
+ m1._IsOverCost = true
+ m1._OverCostCountInOneTerm = 1
+ m1._GenCountInOneTerm = 1
+
+ return m1.CalcId(m1._LastTimeTick)
+ }
+ return m1.CalcId(m1._LastTimeTick)
+}
+
+func (m1 *SnowWorkerM1) CalcId(useTimeTick int64) uint64 {
+ result := uint64(useTimeTick< m2.MaxSeqNumber {
+ atomic.StoreUint32(&m2._CurrentSeqNumber, uint32(m2.MinSeqNumber))
+ currentTimeTick = m2.GetNextTimeTick()
+ }
+ } else {
+ atomic.StoreUint32(&m2._CurrentSeqNumber, uint32(m2.MinSeqNumber))
+ }
+ if currentTimeTick < m2._LastTimeTick {
+ fmt.Println("Time error for {0} milliseconds", strconv.FormatInt(m2._LastTimeTick-currentTimeTick, 10))
+ }
+ m2._LastTimeTick = currentTimeTick
+ result := uint64((currentTimeTick << m2._TimestampShift)) + uint64(m2.WorkerId< time.Now().UnixNano()/1e6 {
+ panic("BaseTime error.")
+ }
+
+ if Options.SeqBitLength+Options.WorkerIdBitLength > 22 {
+ panic("error:WorkerIdBitLength + SeqBitLength <= 22")
+ }
+
+ maxWorkerIdNumber := uint16(math.Pow(float64(2), float64(Options.WorkerIdBitLength))) - 1
+ if Options.WorkerId > maxWorkerIdNumber {
+ panic("WorkerId error. (range:[1, "+ string(maxWorkerIdNumber)+ "]")
+ }
+
+ if Options.SeqBitLength < 2 || Options.SeqBitLength > 21 {
+ panic("SeqBitLength error. (range:[2, 21])")
+ }
+
+ maxSeqNumber := uint32(math.Pow(2, float64(Options.SeqBitLength))) - 1
+ if Options.MaxSeqNumber > maxSeqNumber {
+ panic("MaxSeqNumber error. (range:[1, "+ string(maxSeqNumber)+ "]")
+ }
+
+ if Options.MinSeqNumber > maxSeqNumber {
+ panic("MinSeqNumber error. (range:[1, "+ string(maxSeqNumber)+ "]")
+ }
+
+ var snowWorker contract.ISnowWorker
+
+ switch Options.Method {
+ case 1:
+ snowWorker = core.NewSnowWorkerM1(Options)
+ case 2:
+ snowWorker = core.NewSnowWorkerM2(Options)
+ default:
+ snowWorker = core.NewSnowWorkerM1(Options)
+ }
+
+ if Options.Method == 1 {
+ time.Sleep(time.Duration(500) * time.Microsecond)
+ }
+ return &DefaultIdGenerator{
+ Options: Options,
+ SnowWorker: snowWorker,
+ }
+}
+
+func (dig DefaultIdGenerator) NewLong() uint64 {
+ return dig.SnowWorker.NextId()
+}
diff --git a/Go/source/yitidgen/idgen/YitIdHelper.go b/Go/source/yitidgen/idgen/YitIdHelper.go
new file mode 100644
index 0000000..90f1cd2
--- /dev/null
+++ b/Go/source/yitidgen/idgen/YitIdHelper.go
@@ -0,0 +1,41 @@
+package idgen
+
+import (
+ "../contract"
+ "sync"
+)
+
+var ins *YitIdHelper
+var once sync.Once
+
+type YitIdHelper struct {
+ idGenInstance interface {
+ NewLong() uint64
+ }
+}
+
+func GetIns() *YitIdHelper {
+ once.Do(func() {
+ ins = &YitIdHelper{}
+ })
+ return ins
+}
+
+func (yih *YitIdHelper) GetIdGenInstance() interface{} {
+ return yih.idGenInstance
+}
+
+func (yih *YitIdHelper) SetIdGenerator(options *contract.IdGeneratorOptions) {
+ yih.idGenInstance = NewDefaultIdGenerator(options)
+}
+
+func (yih *YitIdHelper) NextId() uint64 {
+ once.Do(func() {
+ if yih.idGenInstance == nil {
+ options := contract.NewIdGeneratorOptions(1)
+ yih.idGenInstance = NewDefaultIdGenerator(options)
+ }
+ })
+
+ return yih.idGenInstance.NewLong()
+}
diff --git a/Java/source/src/main/java/com/yitter/contract/IdGeneratorOptions.java b/Java/source/src/main/java/com/yitter/contract/IdGeneratorOptions.java
index d34a014..b6dbf89 100644
--- a/Java/source/src/main/java/com/yitter/contract/IdGeneratorOptions.java
+++ b/Java/source/src/main/java/com/yitter/contract/IdGeneratorOptions.java
@@ -17,7 +17,7 @@ public class IdGeneratorOptions {
public short Method = 1;
/**
- * 开始时间
+ * 基础时间
* 不能超过当前系统时间
*/
public long BaseTime = 1582136402000L;
diff --git a/Java/source/src/main/java/com/yitter/test/StartUp.java b/Java/source/src/main/java/com/yitter/test/StartUp.java
index 9cc4a1e..3e01abb 100644
--- a/Java/source/src/main/java/com/yitter/test/StartUp.java
+++ b/Java/source/src/main/java/com/yitter/test/StartUp.java
@@ -34,8 +34,8 @@ public class StartUp {
options.BaseTime = 1582206693000L;
options.WorkerId = 1;
- IIdGenerator IdGen = new DefaultIdGenerator(options);
- GenTest genTest = new GenTest(IdGen, genIdCount, options.WorkerId);
+ IIdGenerator idGen = new DefaultIdGenerator(options);
+ GenTest genTest = new GenTest(idGen, genIdCount, options.WorkerId);
// 首先测试一下 IdHelper 方法,获取单个Id
YitIdHelper.setIdGenerator(options);