diff --git a/C#.NET/source/YitIdGen.WinFormApp/Program.cs b/C#.NET/source/YitIdGen.WinFormApp/Program.cs
new file mode 100644
index 0000000..21301c5
--- /dev/null
+++ b/C#.NET/source/YitIdGen.WinFormApp/Program.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace WInFormApp
+{
+ static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ Application.SetHighDpiMode(HighDpiMode.SystemAware);
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new StartForm());
+ }
+ }
+}
diff --git a/C#.NET/source/YitIdGen.WinFormApp/StartForm.Designer.cs b/C#.NET/source/YitIdGen.WinFormApp/StartForm.Designer.cs
new file mode 100644
index 0000000..84e63f7
--- /dev/null
+++ b/C#.NET/source/YitIdGen.WinFormApp/StartForm.Designer.cs
@@ -0,0 +1,90 @@
+
+namespace WInFormApp
+{
+ partial class StartForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.btnGen = new System.Windows.Forms.Button();
+ this.txtIdList = new System.Windows.Forms.TextBox();
+ this.button1 = new System.Windows.Forms.Button();
+ this.SuspendLayout();
+ //
+ // btnGen
+ //
+ this.btnGen.Location = new System.Drawing.Point(12, 385);
+ this.btnGen.Name = "btnGen";
+ this.btnGen.Size = new System.Drawing.Size(170, 64);
+ this.btnGen.TabIndex = 0;
+ this.btnGen.Text = "注册";
+ this.btnGen.UseVisualStyleBackColor = true;
+ this.btnGen.Click += new System.EventHandler(this.btnGen_Click);
+ //
+ // txtIdList
+ //
+ this.txtIdList.Location = new System.Drawing.Point(12, 12);
+ this.txtIdList.Multiline = true;
+ this.txtIdList.Name = "txtIdList";
+ this.txtIdList.ScrollBars = System.Windows.Forms.ScrollBars.Both;
+ this.txtIdList.Size = new System.Drawing.Size(443, 346);
+ this.txtIdList.TabIndex = 1;
+ //
+ // button1
+ //
+ this.button1.Location = new System.Drawing.Point(286, 385);
+ this.button1.Name = "button1";
+ this.button1.Size = new System.Drawing.Size(170, 64);
+ this.button1.TabIndex = 2;
+ this.button1.Text = "注销";
+ this.button1.UseVisualStyleBackColor = true;
+ this.button1.Click += new System.EventHandler(this.button1_Click);
+ //
+ // StartForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(11F, 24F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(468, 514);
+ this.Controls.Add(this.button1);
+ this.Controls.Add(this.txtIdList);
+ this.Controls.Add(this.btnGen);
+ this.Name = "StartForm";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+ this.Text = "TestForm";
+ this.Load += new System.EventHandler(this.Form1_Load);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Button btnGen;
+ private System.Windows.Forms.TextBox txtIdList;
+ private System.Windows.Forms.Button button1;
+ }
+}
+
diff --git a/C#.NET/source/YitIdGen.WinFormApp/StartForm.cs b/C#.NET/source/YitIdGen.WinFormApp/StartForm.cs
new file mode 100644
index 0000000..5bf016b
--- /dev/null
+++ b/C#.NET/source/YitIdGen.WinFormApp/StartForm.cs
@@ -0,0 +1,74 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace WInFormApp
+{
+ public partial class StartForm : Form
+ {
+ public StartForm()
+ {
+ InitializeComponent();
+ }
+
+ [DllImport("yitidgengo.dll", CallingConvention = CallingConvention.StdCall)]
+ public static extern long NextId();
+
+ [DllImport("yitidgengo.dll", CallingConvention = CallingConvention.StdCall)]
+ public static extern long NextId2();
+
+ [DllImport("yitidgengo.dll", CallingConvention = CallingConvention.StdCall)]
+ public static extern long RegisterWorkerId(string ip, int port, string password, int maxWorkerIdNumber);
+ //public static extern ulong RegisterWorkerId2();
+
+ [DllImport("yitidgengo.dll", CallingConvention = CallingConvention.StdCall)]
+ public static extern long UnRegisterWorkerId();
+
+
+ [DllImport("yitidgen.dll", CallingConvention = CallingConvention.StdCall)]
+ public static extern void SetWorkerId(uint workerId);
+
+ [DllImport("yitidgen.dll", CallingConvention = CallingConvention.StdCall)]
+ public static extern int Test();
+
+ [DllImport("yitidgen.dll", CallingConvention = CallingConvention.StdCall)]
+ public static extern int GetWorkerId(string ip, int port);
+
+
+ private void Form1_Load(object sender, EventArgs e)
+ {
+
+ }
+
+ private void btnGen_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ var ip = "localhost";
+
+ //txtIdList.Text += RegisterWorkerId(Encoding.UTF8.GetBytes(ip), 6379) + "\r\n";
+ txtIdList.Text += RegisterWorkerId(ip, 6379, "", 4) + "\r\n";
+ //txtIdList.Text += RegisterWorkerId() + "\r\n";
+
+ //txtIdList.Text += Test() + "\r\n";
+ }
+ catch (Exception ex)
+ {
+ txtIdList.Text = ex.Message;
+ }
+ }
+
+ private void button1_Click(object sender, EventArgs e)
+ {
+ UnRegisterWorkerId();
+ // GetWorkerId("localhost", 6379);
+ }
+ }
+}
diff --git a/C#.NET/source/YitIdGen.WinFormApp/StartForm.resx b/C#.NET/source/YitIdGen.WinFormApp/StartForm.resx
new file mode 100644
index 0000000..b5ae26c
--- /dev/null
+++ b/C#.NET/source/YitIdGen.WinFormApp/StartForm.resx
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/C#.NET/source/YitIdGen.WinFormApp/YitIdGen.WinFormApp.csproj b/C#.NET/source/YitIdGen.WinFormApp/YitIdGen.WinFormApp.csproj
new file mode 100644
index 0000000..2bbc716
--- /dev/null
+++ b/C#.NET/source/YitIdGen.WinFormApp/YitIdGen.WinFormApp.csproj
@@ -0,0 +1,19 @@
+
+
+
+ WinExe
+ net5.0-windows
+ true
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+
+
\ No newline at end of file
diff --git a/C#.NET/source/YitIdGen.WinFormApp/yitidgen.dll b/C#.NET/source/YitIdGen.WinFormApp/yitidgen.dll
new file mode 100644
index 0000000..b3b9a92
Binary files /dev/null and b/C#.NET/source/YitIdGen.WinFormApp/yitidgen.dll differ
diff --git a/C#.NET/source/Yitter.IdGen.sln b/C#.NET/source/Yitter.IdGen.sln
index 2cbc6ea..2daaa91 100644
--- a/C#.NET/source/Yitter.IdGen.sln
+++ b/C#.NET/source/Yitter.IdGen.sln
@@ -7,6 +7,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yitter.IdGenerator", "Yitte
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yitter.IdGenTest", "Yitter.IdGenTest\Yitter.IdGenTest.csproj", "{67426F7D-0A3B-4645-B4D7-5487215D3E2B}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "YitIdGen.WinFormApp", "YitIdGen.WinFormApp\YitIdGen.WinFormApp.csproj", "{1035D82E-3F37-4940-AA32-5D1E0E53AFA5}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -21,6 +23,10 @@ Global
{67426F7D-0A3B-4645-B4D7-5487215D3E2B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{67426F7D-0A3B-4645-B4D7-5487215D3E2B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{67426F7D-0A3B-4645-B4D7-5487215D3E2B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1035D82E-3F37-4940-AA32-5D1E0E53AFA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1035D82E-3F37-4940-AA32-5D1E0E53AFA5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1035D82E-3F37-4940-AA32-5D1E0E53AFA5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1035D82E-3F37-4940-AA32-5D1E0E53AFA5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/C#.NET/source/Yitter.IdGenTest/GenTest.cs b/C#.NET/source/Yitter.IdGenTest/GenTest.cs
index b5383c4..5ebf05e 100644
--- a/C#.NET/source/Yitter.IdGenTest/GenTest.cs
+++ b/C#.NET/source/Yitter.IdGenTest/GenTest.cs
@@ -15,7 +15,6 @@ namespace Yitter.OrgSystem.TestA
public IList idList = new List();
private int GenIdCount;
private int WorkerId;
-
public GenTest(IIdGenerator idGen, int genIdCount, int workerId)
{
diff --git a/C#.NET/source/Yitter.IdGenTest/Program.cs b/C#.NET/source/Yitter.IdGenTest/Program.cs
index 3f57391..42e9d69 100644
--- a/C#.NET/source/Yitter.IdGenTest/Program.cs
+++ b/C#.NET/source/Yitter.IdGenTest/Program.cs
@@ -55,9 +55,9 @@ namespace Yitter.OrgSystem.TestA
while (true)
{
- //RunSingle();
+ RunSingle();
+ //CallDll();
//Go(options);
- CallDll();
Thread.Sleep(1000); // 每隔1秒执行一次Go
}
}
@@ -65,13 +65,13 @@ namespace Yitter.OrgSystem.TestA
//[DllImport("yitidgenc.dll", CallingConvention = CallingConvention.StdCall)]
//public static extern long NextId();
- [DllImport("yitidgenc.dll", CallingConvention = CallingConvention.StdCall)]
+ [DllImport("yitidgengo.dll", CallingConvention = CallingConvention.StdCall)]
public static extern long NextId();
- [DllImport("yitidgenc.dll", CallingConvention = CallingConvention.StdCall)]
+ [DllImport("yitidgen.dll", CallingConvention = CallingConvention.StdCall)]
public static extern void SetWorkerId(uint workerId);
- [DllImport("yitidgenc.dll", CallingConvention = CallingConvention.StdCall)]
+ [DllImport("yitidgen.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int TestId();
private static void CallDll()
diff --git a/Go/source/gen/YitIdHelper.go b/Go/source/gen/YitIdHelper.go
deleted file mode 100644
index fc93df8..0000000
--- a/Go/source/gen/YitIdHelper.go
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 版权属于:yitter(yitter@126.com)
- * 代码编辑:guoyahao
- * 代码修订:yitter
- * 开源地址:https://gitee.com/yitter/idgenerator
- */
-package gen
-
-import (
- "sync"
- "yitidgen/contract"
-)
-
-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/Go/source/go.mod b/Go/source/go.mod
index 8eafd7d..c1c9b3c 100644
--- a/Go/source/go.mod
+++ b/Go/source/go.mod
@@ -1 +1,9 @@
-module "yitidgen"
\ No newline at end of file
+module yitidgen
+
+go 1.16
+
+require (
+ github.com/go-redis/redis v6.15.9+incompatible
+ github.com/onsi/ginkgo v1.15.2 // indirect
+ github.com/onsi/gomega v1.11.0 // indirect
+)
diff --git a/Go/source/go.sum b/Go/source/go.sum
new file mode 100644
index 0000000..b98c3ea
--- /dev/null
+++ b/Go/source/go.sum
@@ -0,0 +1,82 @@
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
+github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
+github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
+github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
+github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
+github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
+github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
+github.com/onsi/ginkgo v1.15.2 h1:l77YT15o814C2qVL47NOyjV/6RbaP7kKdrvZnxQ3Org=
+github.com/onsi/ginkgo v1.15.2/go.mod h1:Dd6YFfwBW84ETqqtL0CPyPXillHgY6XhQH3uuCCTr/o=
+github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
+github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
+github.com/onsi/gomega v1.11.0 h1:+CqWgvj0OZycCaqclBD1pxKHAU+tOkHmQIWvDHq2aug=
+github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U=
+golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210112080510-489259a85091 h1:DMyOG0U+gKfu8JZzg2UQe9MeaC1X+xQWlAKcRnjxjCw=
+golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
diff --git a/Go/source/gen/DefaultIdGenerator.go b/Go/source/idgen/DefaultIdGenerator.go
similarity index 99%
rename from Go/source/gen/DefaultIdGenerator.go
rename to Go/source/idgen/DefaultIdGenerator.go
index 8d89138..5176980 100644
--- a/Go/source/gen/DefaultIdGenerator.go
+++ b/Go/source/idgen/DefaultIdGenerator.go
@@ -4,7 +4,7 @@
* 代码修订:yitter
* 开源地址:https://gitee.com/yitter/idgenerator
*/
-package gen
+package idgen
import (
"time"
diff --git a/Go/source/idgen/YitIdHelper.go b/Go/source/idgen/YitIdHelper.go
new file mode 100644
index 0000000..a7540c9
--- /dev/null
+++ b/Go/source/idgen/YitIdHelper.go
@@ -0,0 +1,68 @@
+/*
+ * 版权属于:yitter(yitter@126.com)
+ * 代码编辑:guoyahao
+ * 代码修订:yitter
+ * 开源地址:https://gitee.com/yitter/idgenerator
+ */
+package idgen
+
+import (
+ "sync"
+ "yitidgen/contract"
+)
+
+//var yitIdHelper *YitIdHelper
+//var once sync.Once
+
+var idGenerator *DefaultIdGenerator
+var singletonMutex sync.Mutex
+
+type YitIdHelper struct {
+ idGenInstance interface {
+ NewLong() uint64
+ }
+}
+
+//
+//func GetIns() *YitIdHelper {
+// once.Do(func() {
+// yitIdHelper = &YitIdHelper{}
+// })
+// return yitIdHelper
+//}
+//
+//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()
+//}
+
+func SetIdGenerator(options *contract.IdGeneratorOptions) {
+ singletonMutex.Lock()
+ idGenerator = NewDefaultIdGenerator(options)
+ singletonMutex.Unlock()
+}
+
+func NextId() uint64 {
+ if idGenerator == nil {
+ singletonMutex.Lock()
+ options := contract.NewIdGeneratorOptions(1)
+ idGenerator = NewDefaultIdGenerator(options)
+ singletonMutex.Unlock()
+ }
+
+ return idGenerator.NewLong()
+}
diff --git a/Go/source/main.go b/Go/source/main.go
new file mode 100644
index 0000000..4eb085f
--- /dev/null
+++ b/Go/source/main.go
@@ -0,0 +1,67 @@
+package main
+
+import (
+ "C"
+ "fmt"
+ "time"
+ "yitidgen/contract"
+ "yitidgen/idgen"
+ "yitidgen/regworkerid"
+)
+
+//export SetOptions
+func SetOptions(workerId uint16) {
+ var options = contract.NewIdGeneratorOptions(workerId)
+ idgen.SetIdGenerator(options)
+}
+
+//export NextId
+func NextId() uint64 {
+ return idgen.NextId()
+}
+
+//export RegisterWorkerId
+func RegisterWorkerId(ip *C.char, port int, password *C.char, maxWorkerId int) int {
+ return regworkerid.RegisterWorkerId(C.GoString(ip), port, C.GoString(password), maxWorkerId)
+}
+
+//export UnRegisterWorkerId
+func UnRegisterWorkerId() {
+ regworkerid.UnRegisterWorkerId()
+}
+
+func main() {
+ // 方法一:直接采用默认方法生成一个Id
+ fmt.Println("生成的Id:", idgen.NextId())
+
+ fmt.Println("生成的Id:", regworkerid.RegisterWorkerId("localhost", 6379, "", 4))
+
+ return
+ // 方法二:自定义参数
+ 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
+ idgen.SetIdGenerator(options)
+
+ var genCount = 50000
+
+ for {
+ var begin = time.Now().UnixNano() / 1e6
+ for i := 0; i < genCount; i++ {
+ idgen.NextId()
+ }
+ var end = time.Now().UnixNano() / 1e6
+
+ fmt.Println(end - begin)
+ time.Sleep(time.Duration(1000) * time.Millisecond)
+ }
+
+}
+
+// go build -o target\yitidgengo.dll -buildmode=c-shared main.go
+
+//var yid = idgen.YitIdHelper{}
+//yid.SetIdGenerator(options)
+//fmt.Println(yid.NextId())
diff --git a/Go/source/regworkerid/reghelper.go b/Go/source/regworkerid/reghelper.go
new file mode 100644
index 0000000..642aca6
--- /dev/null
+++ b/Go/source/regworkerid/reghelper.go
@@ -0,0 +1,230 @@
+package regworkerid
+
+import (
+ "fmt"
+ "github.com/go-redis/redis"
+ "strconv"
+ "sync"
+ "time"
+)
+
+var Client *redis.Client
+
+var _usingWorkerId int = -1
+var _maxWorkerId int = 0
+var _loopCount int = 0
+var _liftIndex int = -1
+var _workerIdLock sync.Mutex
+
+const CurrentWidIndexKey string = "IdGen:WorkerId:Index"
+const WidKeyPrefix string = "IdGen:WorkerId:Value:"
+const WorkerIdFlag = "Y" // WorkerId 存储标记
+const WorkerIdLifeTimeSeconds = 15 // WorkerIdFlag 有效期(单位秒,最好是3的倍数)
+const Log = false
+
+func UnRegisterWorkerId() {
+ if _usingWorkerId < 0 {
+ return
+ }
+ _workerIdLock.Lock()
+ Client.Del(WidKeyPrefix + strconv.Itoa(_usingWorkerId))
+ _usingWorkerId = -1
+ _liftIndex = -1
+ _workerIdLock.Unlock()
+}
+
+func RegisterWorkerId(ip string, port int, password string, maxWorkerId int) int {
+ // maxWorkerId不能小于0
+ if maxWorkerId < 0 {
+ return -1
+ }
+
+ // 如果当前已注册过 WorkerId,则先注销,并终止先前的自动续期线程
+ if _usingWorkerId > -1 {
+ UnRegisterWorkerId()
+ }
+
+ _maxWorkerId = maxWorkerId
+ Client = redis.NewClient(&redis.Options{
+ Addr: string(ip) + ":" + strconv.Itoa(port),
+ PoolSize: 1000,
+ ReadTimeout: time.Millisecond * time.Duration(100),
+ WriteTimeout: time.Millisecond * time.Duration(100),
+ IdleTimeout: time.Second * time.Duration(60),
+ Password: password,
+ })
+ _, err := Client.Ping().Result()
+ if err != nil {
+ panic("init redis error")
+ } else {
+ if Log {
+ fmt.Println("init redis ok")
+ }
+ }
+
+ _loopCount = 0
+ return getNextWorkerId()
+}
+
+func getNextWorkerId() int {
+ // 获取当前 WorkerIdIndex
+ // var currentId = int(Client.Incr(CurrentWidIndexKey).Val())
+ r, err := Client.Incr(CurrentWidIndexKey).Result()
+ if err != nil {
+ return 0
+ }
+
+ currentId := int(r)
+ if Log {
+ fmt.Println("Begin currentId:" + strconv.Itoa(currentId))
+ }
+
+ // 如果 Index 大于最大值,则重置
+ if currentId > _maxWorkerId {
+ if canReset() {
+ // 当前应用获得重置 WorkerIdIndex 的权限
+ setWorkerIdIndex(-1)
+ endReset() // 此步有可能不被执行?
+ _loopCount++
+ // 超过一定次数,直接终止操作
+ if _loopCount > 10 {
+ return -1
+ }
+
+ // if _loopCount > 2 {
+ // 如果超过2个循环,则暂停1s
+ time.Sleep(time.Duration(500*_loopCount) * time.Millisecond)
+ //_loopCount = 0
+ //}
+
+ if Log {
+ fmt.Println("canReset loop")
+ }
+
+ return getNextWorkerId()
+ } else {
+ // 如果有其它应用正在编辑,则本应用暂停1s后,再继续
+ time.Sleep(time.Duration(1000) * time.Millisecond)
+
+ if Log {
+ fmt.Println("not canReset loop")
+ }
+
+ return getNextWorkerId()
+ }
+ }
+
+ if Log {
+ fmt.Println("currentId:" + strconv.Itoa(currentId))
+ }
+
+ if isAvailable(currentId) {
+ if Log {
+ fmt.Println("AA: isAvailable:" + strconv.Itoa(currentId))
+ }
+
+ // 最新获得的 WorkerIdIndex,在 redis 中是可用状态
+ setWorkerIdFlag(currentId)
+ _usingWorkerId = currentId
+
+ // 获取到可用 WorkerId 后,启用新线程,每隔 1/3个 WorkerIdLifeTimeSeconds 时间,向服务器续期(延长一次 LifeTime)
+ _liftIndex++
+ go extendWorkerIdLifeTime(_liftIndex)
+
+ return currentId
+ } else {
+ if Log {
+ fmt.Println("BB: not isAvailable:" + strconv.Itoa(currentId))
+ }
+ // 最新获得的 WorkerIdIndex,在 redis 中是不可用状态,则继续下一个 WorkerIdIndex
+ return getNextWorkerId()
+ }
+}
+
+func extendWorkerIdLifeTime(lifeIndex int) {
+ var index = lifeIndex
+ for {
+ time.Sleep(time.Duration(WorkerIdLifeTimeSeconds/3) * time.Millisecond)
+
+ _workerIdLock.Lock()
+ if index != _liftIndex {
+ // 如果临时变量 index 不等于 全局变量 _liftIndex,表明全局状态被修改,当前线程可终止
+ break
+ }
+
+ // 已经被注销,则终止(此步是上一步的二次验证)
+ if _usingWorkerId < 0 {
+ break
+ }
+
+ extendWorkerIdFlag(_usingWorkerId)
+ _workerIdLock.Unlock()
+ }
+}
+
+func get(key string) (string, bool) {
+ r, err := Client.Get(key).Result()
+ if err != nil {
+ return "", false
+ }
+ return r, true
+}
+
+func set(key string, val string, expTime int32) {
+ Client.Set(key, val, time.Duration(expTime)*time.Second)
+}
+
+func setWorkerIdIndex(val int) {
+ Client.Set(CurrentWidIndexKey, val, 0)
+}
+
+func setWorkerIdFlag(index int) {
+ Client.Set(WidKeyPrefix+strconv.Itoa(index), WorkerIdFlag, time.Duration(WorkerIdLifeTimeSeconds)*time.Second)
+}
+
+func extendWorkerIdFlag(index int) {
+ Client.Expire(WidKeyPrefix+strconv.Itoa(index), time.Duration(WorkerIdLifeTimeSeconds)*time.Second)
+}
+
+func canReset() bool {
+ r, err := Client.Incr(WidKeyPrefix + "Edit").Result()
+ if err != nil {
+ return false
+ }
+
+ if Log {
+ fmt.Println("canReset:" + string(r))
+ }
+
+ return r != 1
+}
+
+func endReset() {
+ // Client.Set(WidKeyPrefix+"Edit", 0, time.Duration(2)*time.Second)
+ Client.Set(WidKeyPrefix+"Edit", 0, 0)
+}
+
+func getWorkerIdFlag(index int) (string, bool) {
+ r, err := Client.Get(WidKeyPrefix + strconv.Itoa(index)).Result()
+ if err != nil {
+ return "", false
+ }
+ return r, true
+}
+
+func isAvailable(index int) bool {
+ r, err := Client.Get(WidKeyPrefix + strconv.Itoa(index)).Result()
+
+ if Log {
+ fmt.Println("XX isAvailable:" + r)
+ fmt.Println("YY isAvailable:" + err.Error())
+ }
+
+ if err != nil {
+ if err.Error() == "redis: nil" {
+ return true
+ }
+ return false
+ }
+ return r != WorkerIdFlag
+}
diff --git a/Go/source/target/go_build_main_go.exe b/Go/source/target/go_build_main_go.exe
new file mode 100644
index 0000000..76cc0b7
Binary files /dev/null and b/Go/source/target/go_build_main_go.exe differ
diff --git a/Go/source/target/main.dll b/Go/source/target/main.dll
new file mode 100644
index 0000000..bc7f4b2
Binary files /dev/null and b/Go/source/target/main.dll differ
diff --git a/Go/source/target/main.h b/Go/source/target/main.h
new file mode 100644
index 0000000..8eb543c
--- /dev/null
+++ b/Go/source/target/main.h
@@ -0,0 +1,75 @@
+/* Code generated by cmd/cgo; DO NOT EDIT. */
+
+/* package command-line-arguments */
+
+
+#line 1 "cgo-builtin-export-prolog"
+
+#include /* for ptrdiff_t below */
+
+#ifndef GO_CGO_EXPORT_PROLOGUE_H
+#define GO_CGO_EXPORT_PROLOGUE_H
+
+#ifndef GO_CGO_GOSTRING_TYPEDEF
+typedef struct { const char *p; ptrdiff_t n; } _GoString_;
+#endif
+
+#endif
+
+/* Start of preamble from import "C" comments. */
+
+
+
+
+/* End of preamble from import "C" comments. */
+
+
+/* Start of boilerplate cgo prologue. */
+#line 1 "cgo-gcc-export-header-prolog"
+
+#ifndef GO_CGO_PROLOGUE_H
+#define GO_CGO_PROLOGUE_H
+
+typedef signed char GoInt8;
+typedef unsigned char GoUint8;
+typedef short GoInt16;
+typedef unsigned short GoUint16;
+typedef int GoInt32;
+typedef unsigned int GoUint32;
+typedef long long GoInt64;
+typedef unsigned long long GoUint64;
+typedef GoInt64 GoInt;
+typedef GoUint64 GoUint;
+typedef __SIZE_TYPE__ GoUintptr;
+typedef float GoFloat32;
+typedef double GoFloat64;
+typedef float _Complex GoComplex64;
+typedef double _Complex GoComplex128;
+
+/*
+ static assertion to make sure the file is being used on architecture
+ at least with matching size of GoInt.
+*/
+typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
+
+#ifndef GO_CGO_GOSTRING_TYPEDEF
+typedef _GoString_ GoString;
+#endif
+typedef void *GoMap;
+typedef void *GoChan;
+typedef struct { void *t; void *v; } GoInterface;
+typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
+
+#endif
+
+/* End of boilerplate cgo prologue. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern __declspec(dllexport) GoUint64 NextId();
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/Go/source/target/yitidgen.dll b/Go/source/target/yitidgen.dll
new file mode 100644
index 0000000..2f42ebe
Binary files /dev/null and b/Go/source/target/yitidgen.dll differ
diff --git a/Go/source/target/yitidgen.h b/Go/source/target/yitidgen.h
new file mode 100644
index 0000000..8eb543c
--- /dev/null
+++ b/Go/source/target/yitidgen.h
@@ -0,0 +1,75 @@
+/* Code generated by cmd/cgo; DO NOT EDIT. */
+
+/* package command-line-arguments */
+
+
+#line 1 "cgo-builtin-export-prolog"
+
+#include /* for ptrdiff_t below */
+
+#ifndef GO_CGO_EXPORT_PROLOGUE_H
+#define GO_CGO_EXPORT_PROLOGUE_H
+
+#ifndef GO_CGO_GOSTRING_TYPEDEF
+typedef struct { const char *p; ptrdiff_t n; } _GoString_;
+#endif
+
+#endif
+
+/* Start of preamble from import "C" comments. */
+
+
+
+
+/* End of preamble from import "C" comments. */
+
+
+/* Start of boilerplate cgo prologue. */
+#line 1 "cgo-gcc-export-header-prolog"
+
+#ifndef GO_CGO_PROLOGUE_H
+#define GO_CGO_PROLOGUE_H
+
+typedef signed char GoInt8;
+typedef unsigned char GoUint8;
+typedef short GoInt16;
+typedef unsigned short GoUint16;
+typedef int GoInt32;
+typedef unsigned int GoUint32;
+typedef long long GoInt64;
+typedef unsigned long long GoUint64;
+typedef GoInt64 GoInt;
+typedef GoUint64 GoUint;
+typedef __SIZE_TYPE__ GoUintptr;
+typedef float GoFloat32;
+typedef double GoFloat64;
+typedef float _Complex GoComplex64;
+typedef double _Complex GoComplex128;
+
+/*
+ static assertion to make sure the file is being used on architecture
+ at least with matching size of GoInt.
+*/
+typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
+
+#ifndef GO_CGO_GOSTRING_TYPEDEF
+typedef _GoString_ GoString;
+#endif
+typedef void *GoMap;
+typedef void *GoChan;
+typedef struct { void *t; void *v; } GoInterface;
+typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
+
+#endif
+
+/* End of boilerplate cgo prologue. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern __declspec(dllexport) GoUint64 NextId();
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/Go/source/target/yitidgengo.dll b/Go/source/target/yitidgengo.dll
new file mode 100644
index 0000000..87c7cd6
Binary files /dev/null and b/Go/source/target/yitidgengo.dll differ
diff --git a/Go/source/target/yitidgengo.h b/Go/source/target/yitidgengo.h
new file mode 100644
index 0000000..1b2f837
--- /dev/null
+++ b/Go/source/target/yitidgengo.h
@@ -0,0 +1,78 @@
+/* Code generated by cmd/cgo; DO NOT EDIT. */
+
+/* package command-line-arguments */
+
+
+#line 1 "cgo-builtin-export-prolog"
+
+#include /* for ptrdiff_t below */
+
+#ifndef GO_CGO_EXPORT_PROLOGUE_H
+#define GO_CGO_EXPORT_PROLOGUE_H
+
+#ifndef GO_CGO_GOSTRING_TYPEDEF
+typedef struct { const char *p; ptrdiff_t n; } _GoString_;
+#endif
+
+#endif
+
+/* Start of preamble from import "C" comments. */
+
+
+
+
+/* End of preamble from import "C" comments. */
+
+
+/* Start of boilerplate cgo prologue. */
+#line 1 "cgo-gcc-export-header-prolog"
+
+#ifndef GO_CGO_PROLOGUE_H
+#define GO_CGO_PROLOGUE_H
+
+typedef signed char GoInt8;
+typedef unsigned char GoUint8;
+typedef short GoInt16;
+typedef unsigned short GoUint16;
+typedef int GoInt32;
+typedef unsigned int GoUint32;
+typedef long long GoInt64;
+typedef unsigned long long GoUint64;
+typedef GoInt64 GoInt;
+typedef GoUint64 GoUint;
+typedef __SIZE_TYPE__ GoUintptr;
+typedef float GoFloat32;
+typedef double GoFloat64;
+typedef float _Complex GoComplex64;
+typedef double _Complex GoComplex128;
+
+/*
+ static assertion to make sure the file is being used on architecture
+ at least with matching size of GoInt.
+*/
+typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
+
+#ifndef GO_CGO_GOSTRING_TYPEDEF
+typedef _GoString_ GoString;
+#endif
+typedef void *GoMap;
+typedef void *GoChan;
+typedef struct { void *t; void *v; } GoInterface;
+typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
+
+#endif
+
+/* End of boilerplate cgo prologue. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern __declspec(dllexport) void SetOptions(GoUint16 workerId);
+extern __declspec(dllexport) GoUint64 NextId();
+extern __declspec(dllexport) GoInt RegisterWorkerId(char* ip, GoInt port, char* password, GoInt maxWorkerId);
+extern __declspec(dllexport) void UnRegisterWorkerId();
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/Go/source/test/main.go b/Go/source/test/main.go
deleted file mode 100644
index f1263c5..0000000
--- a/Go/source/test/main.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package main
-
-import (
- "C"
- "fmt"
- "time"
- "yitidgen/contract"
- "yitidgen/gen"
-)
-
-
-//export NextId
-func NextId() uint64{
- return gen.GetIns().NextId()
-}
-
-func main() {
- // 方法一:直接采用默认方法生成一个Id
- var yid = gen.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/PHP/README.md b/PHP/README.md
deleted file mode 100644
index aab2eef..0000000
--- a/PHP/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# idgenerator
-
-something is going on.
-
diff --git a/README.md b/README.md
index 6ff69a5..6acb34b 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# IdGenerator SnowFlake 雪花算法 原生多语言版本 顶尖优化 超强效能
+# 唯一ID生成器 IdGenerator SnowFlake 雪花算法 原生多语言源码
## 介绍
@@ -8,6 +8,8 @@
3.原生支持 C#/Java/Go/Rust/C 等语言,并由 Rust 提供 PHP、Python、Node.js、Ruby 等语言多线程安全调用库(FFI)。
+4.支持单服务部署、多服务部署、容器自动化服务
+
## 技术支持
@@ -27,13 +29,13 @@ QQ群:646049993
4.如果这样的主键值太长,超过前端 JS Number 类型最大值,须把 Long 型转换为 String 型,你会觉得有点沮丧。
-5.哪怕 Guid 能自增,但占用空间大,索引速度慢,所以你也不想用它。
+5.尽管 Guid 能自增,但占用空间大,索引速度慢,你也不想用它。
-6.你的应用实例可能超过50个,每个并发请求可达10W/s。
+6.应用实例可能超过50个,每个并发请求可达10W/s。
7.在容器环境部署应用(水平扩展、自动伸缩)。
-8.你可不想 Id 生成器依赖 redis 的自增操作。
+8.不想依赖 redis 的自增操作。
9.你希望系统运行 100 年以上。
@@ -164,7 +166,15 @@ ID示例(基于默认配置):
7.不要修改核心算法。本算法内部参数较多,逻辑较为复杂,在你尚未掌握核心逻辑时,请勿尝试修改核心代码且用于生产环境,除非通过大量细致、科学的测试验证。
-#### 大型分布式集成
+#### 自动/手动 设置 WorkerId
+
+1.如果Id生成服务是明确的,可在初始化时,手动设置 WorkerId。
+
+2.如果Id生成服务是不明确的,如容器环境:动态的、自动执行、生命周期完全自动化,可在初始化时通过Redis,自动申请 WorkerId,详见“Tools/AutoRegisterWorkerId”
+
+
+
+#### 其它分布式集成
1.可增加 WorkerIdBitLength 到最大20,支持 1,048,576 个节点,且不影响上述并发性能。[算法支持]
diff --git a/Rust/source/Cargo.lock b/Rust/source/Cargo.lock
index 6a8c0af..33c508a 100644
--- a/Rust/source/Cargo.lock
+++ b/Rust/source/Cargo.lock
@@ -1,11 +1,28 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
+[[package]]
+name = "async-trait"
+version = "0.1.48"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "36ea56748e10732c49404c153638a15ec3d6211ec5ff35d9bb20e13b93576adf"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
+[[package]]
+name = "bytes"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
+
[[package]]
name = "chrono"
version = "0.4.19"
@@ -19,6 +36,49 @@ dependencies = [
"winapi",
]
+[[package]]
+name = "combine"
+version = "4.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc4369b5e4c0cddf64ad8981c0111e7df4f7078f4d6ba98fb31f2e17c4c57b7e"
+dependencies = [
+ "bytes",
+ "memchr",
+]
+
+[[package]]
+name = "dtoa"
+version = "0.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0"
+
+[[package]]
+name = "form_urlencoded"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
+dependencies = [
+ "matches",
+ "percent-encoding",
+]
+
+[[package]]
+name = "idna"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89829a5d69c23d348314a7ac337fe39173b61149a9864deabd260983aed48c21"
+dependencies = [
+ "matches",
+ "unicode-bidi",
+ "unicode-normalization",
+]
+
+[[package]]
+name = "itoa"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
+
[[package]]
name = "lazy_static"
version = "1.4.0"
@@ -31,6 +91,18 @@ version = "0.2.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba4aede83fc3617411dc6993bc8c70919750c1c257c6ca6a502aed6e0e2394ae"
+[[package]]
+name = "matches"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
+
+[[package]]
+name = "memchr"
+version = "2.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
+
[[package]]
name = "num-integer"
version = "0.1.44"
@@ -50,6 +122,62 @@ dependencies = [
"autocfg",
]
+[[package]]
+name = "percent-encoding"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
+dependencies = [
+ "unicode-xid",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "redis"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eeb8f8d059ead7805e171fc22de8348a3d611c0f985aaa4f5cf6c0dfc7645407"
+dependencies = [
+ "async-trait",
+ "combine",
+ "dtoa",
+ "itoa",
+ "percent-encoding",
+ "sha1",
+ "url",
+]
+
+[[package]]
+name = "sha1"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
+
+[[package]]
+name = "syn"
+version = "1.0.67"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6498a9efc342871f91cc2d0d694c674368b4ceb40f62b65a7a08c3792935e702"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-xid",
+]
+
[[package]]
name = "time"
version = "0.1.44"
@@ -61,6 +189,57 @@ dependencies = [
"winapi",
]
+[[package]]
+name = "tinyvec"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "317cca572a0e89c3ce0ca1f1bdc9369547fe318a683418e42ac8f59d14701023"
+dependencies = [
+ "tinyvec_macros",
+]
+
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
+
+[[package]]
+name = "unicode-bidi"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
+dependencies = [
+ "matches",
+]
+
+[[package]]
+name = "unicode-normalization"
+version = "0.1.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07fbfce1c8a97d547e8b5334978438d9d6ec8c20e38f56d4a4374d181493eaef"
+dependencies = [
+ "tinyvec",
+]
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
+
+[[package]]
+name = "url"
+version = "2.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ccd964113622c8e9322cfac19eb1004a07e636c545f325da085d5cdde6f1f8b"
+dependencies = [
+ "form_urlencoded",
+ "idna",
+ "matches",
+ "percent-encoding",
+]
+
[[package]]
name = "wasi"
version = "0.10.0+wasi-snapshot-preview1"
@@ -95,4 +274,6 @@ version = "1.0.0"
dependencies = [
"chrono",
"lazy_static",
+ "libc",
+ "redis",
]
diff --git a/Rust/source/Cargo.toml b/Rust/source/Cargo.toml
index 8664c2f..64350e1 100644
--- a/Rust/source/Cargo.toml
+++ b/Rust/source/Cargo.toml
@@ -9,6 +9,15 @@ edition = "2018"
[dependencies]
chrono = "0.4.10"
lazy_static = "1.4.0"
+#simple_redis = "*"
+redis = "0.20.0"
+libc="*"
+
+#actix = "0.9.0"
+#actix-web = "2.0"
+#actix-rt = "1.0"
+#actix-redis = "0.8.0"
+#redis-async = "0.6.1"
[lib]
name = "yitidgen"
diff --git a/Rust/source/src/lib.rs b/Rust/source/src/lib.rs
index 080215e..b1e797b 100644
--- a/Rust/source/src/lib.rs
+++ b/Rust/source/src/lib.rs
@@ -3,6 +3,23 @@ mod yitgen;
use yitgen::gen::YitIdHelper;
use yitgen::contract::*;
+#[macro_use]
+extern crate lazy_static;
+extern crate redis;
+extern crate libc;
+
+use redis::Commands;
+
+use libc::{c_char, uint32_t};
+use std::ffi::{CStr, CString};
+use std::str;
+
+lazy_static! {
+ //static ref TestValue: Vec = vec!(0);
+ // static ref MAP: HashMap = HashMap::new();
+ }
+
+
// #[export_name = "SetIdGenerator"]
#[no_mangle]
pub extern "C" fn SetIdGenerator(options: IdGeneratorOptions) {
@@ -19,3 +36,64 @@ pub extern "C" fn NextId() -> i64 {
YitIdHelper::NextId()
}
+static mut TestValue: i32 = 0;
+
+#[no_mangle]
+pub extern "C" fn Test() -> i32 {
+ unsafe {
+ TestValue += 1;
+ return TestValue;
+ }
+}
+
+#[no_mangle]
+pub extern "C" fn GetWorkerId(ip: *const c_char, port: i32) -> redis::RedisResult {
+ // let c_str = unsafe {
+ // assert!(!ip.is_null());
+ // CStr::from_ptr(ip)
+ // };
+ //
+ // let r_str = c_str.to_str();
+
+ // connect to redis
+ // let client = redis::Client::open(format!("redis://{}:{}/", String::from(r_str).to_string(), port))?;
+ let client = redis::Client::open(format!("redis://localhost:{}/", port))?;
+
+ let mut con = client.get_connection()?;
+ // throw away the result, just make sure it does not fail
+ unsafe {
+ let _: () = con.set("my_key111", TestValue.clone())?;
+ }
+ con.get("my_key")
+// read back the key and return it. Because the return value
+// from the function is a result for integer this will automatically
+// convert into one.
+//
+
+// match simple_redis::create(&format!("redis://{}:{}/", ip, port)) {
+// Ok(mut client) => {
+// println!("Created Redis Client");
+//
+// let valueString = TestValue.to_string();
+// let valueString2 = (*TestValue).to_string();
+//
+// match client.set("my_key", valueString) {
+// Err(error) => println!("Unable to set value in Redis: {}", error),
+// _ => println!("Value set in Redis")
+// };
+//
+// match client.set("my_key2", valueString2) {
+// Err(error) => println!("Unable to set value in Redis: {}", error),
+// _ => println!("Value set in Redis")
+// };
+//
+// match client.quit() {
+// Err(error) => println!("Error: {}", error),
+// _ => println!("Connection Closed.")
+// }
+// }
+// Err(error) => println!("Unable to create Redis client: {}", error)
+// }
+
+//return 1;
+}
\ No newline at end of file
diff --git a/Rust/source/src/main.rs b/Rust/source/src/main.rs
index 88ab0ff..9870a12 100644
--- a/Rust/source/src/main.rs
+++ b/Rust/source/src/main.rs
@@ -6,6 +6,7 @@ use std::thread;
use chrono::Utc;
use std::time::Duration;
+
fn main() {
println!("Hello, world! Rust");
@@ -22,6 +23,8 @@ fn main() {
//... 可以继续设置其它 options 参数
YitIdHelper::SetIdGenerator(options);
+ set_redis();
+
// 以下开始测试生成数据,默认5W,单线程,可以修改 multiThread=true 启用多线程。
loop {
let mut i = 0;
@@ -51,3 +54,24 @@ fn main() {
}
}
+fn set_redis() {
+
+ // match simple_redis::create("redis://127.0.0.1:6379/") {
+ // Ok(mut client) => {
+ // println!("Created Redis Client");
+ //
+ // match client.set("my_key", "my_value") {
+ // Err(error) => println!("Unable to set value in Redis: {}", error),
+ // _ => println!("Value set in Redis")
+ // };
+ //
+ // match client.quit() {
+ // Err(error) => println!("Error: {}", error),
+ // _ => println!("Connection Closed.")
+ // }
+ // },
+ // Err(error) => println!("Unable to create Redis client: {}", error)
+ // }
+
+ }
+
diff --git a/Rust/source/src/yitgen/core/snow_worker_m1.rs b/Rust/source/src/yitgen/core/snow_worker_m1.rs
index 7ed297e..742a7e9 100644
--- a/Rust/source/src/yitgen/core/snow_worker_m1.rs
+++ b/Rust/source/src/yitgen/core/snow_worker_m1.rs
@@ -6,7 +6,7 @@ use super::super::contract::*;
use std::{thread};
use chrono::Utc;
use std::thread::sleep;
-use lazy_static::lazy_static;
+// use lazy_static::lazy_static;
pub struct SnowWorkerM1 {
///基础时间
diff --git a/Rust/source/src/yitgen/gen/default_id_generator.rs b/Rust/source/src/yitgen/gen/default_id_generator.rs
index c566b5a..50fa71b 100644
--- a/Rust/source/src/yitgen/gen/default_id_generator.rs
+++ b/Rust/source/src/yitgen/gen/default_id_generator.rs
@@ -12,7 +12,7 @@ use std::sync::Mutex;
use std::sync::Arc;
use std::borrow::BorrowMut;
-static mut instance2: Option>> = None;
+// static mut instance2: Option>> = None;
pub struct DefaultIdGenerator {
pub Worker: SnowWorkerM1,
diff --git a/Tools/AutoRegisterWorkerId/README.md b/Tools/AutoRegisterWorkerId/README.md
new file mode 100644
index 0000000..8e57b14
--- /dev/null
+++ b/Tools/AutoRegisterWorkerId/README.md
@@ -0,0 +1,16 @@
+# idgenerator
+
+## AutoRegisterWorkerId
+
+Զע WorkerId Ĺߡ¼ʹá
+
+
+## 輯
+
+ȫִһΣ
+
+1.Redisӡ
+
+2.ȡ WorkerIdֵ IdGenerator
+
+
diff --git a/Tools/FFI for Python-Node-PHP/README.md b/Tools/FFI for Python-Node-PHP/README.md
new file mode 100644
index 0000000..24ab2f6
--- /dev/null
+++ b/Tools/FFI for Python-Node-PHP/README.md
@@ -0,0 +1,7 @@
+# idgenerator
+
+## FFI
+
+Pytonnode.jsPHP ȿͨ FFI ʽö̬ ID
+
+ォṩͬϵͳĶ̬
\ No newline at end of file
diff --git a/ZeOthers/README.md b/Tools/OtherLanguages/README.md
similarity index 100%
rename from ZeOthers/README.md
rename to Tools/OtherLanguages/README.md
diff --git a/ZeOthers/Vlang/README.md b/Tools/OtherLanguages/Vlang/README.md
similarity index 100%
rename from ZeOthers/Vlang/README.md
rename to Tools/OtherLanguages/Vlang/README.md
diff --git a/ZeOthers/Vlang/source/contract/IIdGenerator.v b/Tools/OtherLanguages/Vlang/source/contract/IIdGenerator.v
similarity index 100%
rename from ZeOthers/Vlang/source/contract/IIdGenerator.v
rename to Tools/OtherLanguages/Vlang/source/contract/IIdGenerator.v
diff --git a/ZeOthers/Vlang/source/contract/ISnowWorker.v b/Tools/OtherLanguages/Vlang/source/contract/ISnowWorker.v
similarity index 100%
rename from ZeOthers/Vlang/source/contract/ISnowWorker.v
rename to Tools/OtherLanguages/Vlang/source/contract/ISnowWorker.v
diff --git a/ZeOthers/Vlang/source/contract/IdGeneratorOptions.v b/Tools/OtherLanguages/Vlang/source/contract/IdGeneratorOptions.v
similarity index 100%
rename from ZeOthers/Vlang/source/contract/IdGeneratorOptions.v
rename to Tools/OtherLanguages/Vlang/source/contract/IdGeneratorOptions.v
diff --git a/ZeOthers/Vlang/source/core/SnowWorkerM1.v b/Tools/OtherLanguages/Vlang/source/core/SnowWorkerM1.v
similarity index 100%
rename from ZeOthers/Vlang/source/core/SnowWorkerM1.v
rename to Tools/OtherLanguages/Vlang/source/core/SnowWorkerM1.v
diff --git a/ZeOthers/Vlang/source/core/SnowWorkerM2.v b/Tools/OtherLanguages/Vlang/source/core/SnowWorkerM2.v
similarity index 100%
rename from ZeOthers/Vlang/source/core/SnowWorkerM2.v
rename to Tools/OtherLanguages/Vlang/source/core/SnowWorkerM2.v
diff --git a/ZeOthers/Vlang/source/gen/DefaultIdGenerator.v b/Tools/OtherLanguages/Vlang/source/gen/DefaultIdGenerator.v
similarity index 100%
rename from ZeOthers/Vlang/source/gen/DefaultIdGenerator.v
rename to Tools/OtherLanguages/Vlang/source/gen/DefaultIdGenerator.v
diff --git a/ZeOthers/Vlang/source/gen/YitIdHelper.v b/Tools/OtherLanguages/Vlang/source/gen/YitIdHelper.v
similarity index 100%
rename from ZeOthers/Vlang/source/gen/YitIdHelper.v
rename to Tools/OtherLanguages/Vlang/source/gen/YitIdHelper.v
diff --git a/ZeOthers/Vlang/source/test b/Tools/OtherLanguages/Vlang/source/test
similarity index 100%
rename from ZeOthers/Vlang/source/test
rename to Tools/OtherLanguages/Vlang/source/test
diff --git a/ZeOthers/Vlang/source/test.v b/Tools/OtherLanguages/Vlang/source/test.v
similarity index 100%
rename from ZeOthers/Vlang/source/test.v
rename to Tools/OtherLanguages/Vlang/source/test.v
diff --git a/tester/csharp_call_rust.png b/Tools/Testing Data/csharp_call_rust.png
similarity index 100%
rename from tester/csharp_call_rust.png
rename to Tools/Testing Data/csharp_call_rust.png
diff --git a/tester/每次5W并发(循环).png b/Tools/Testing Data/每次5W并发(循环).png
similarity index 100%
rename from tester/每次5W并发(循环).png
rename to Tools/Testing Data/每次5W并发(循环).png
diff --git a/tester/综合测试.png b/Tools/Testing Data/综合测试.png
similarity index 100%
rename from tester/综合测试.png
rename to Tools/Testing Data/综合测试.png