Browse Source

Merge remote-tracking branch 'upstream/master'

# Conflicts:
#	Go/regworkerid/regworkerid/reghelper.go
#	Go/source/main.go
pull/19/MERGE
lifushen 2 years ago
parent
commit
66f5196810
53 changed files with 1657 additions and 617 deletions
  1. +1
    -0
      .gitignore
  2. +2
    -2
      C#.NET/source/Yitter.IdGen.sln
  3. +110
    -17
      C#.NET/source/Yitter.IdGenTest/Program.cs
  4. +1
    -1
      C#.NET/source/Yitter.IdGenTest/Yitter.IdGenTest.csproj
  5. +0
    -1
      C#.NET/source/Yitter.IdGenerator/Contract/IdGeneratorOptions.cs
  6. +5
    -4
      C#.NET/source/Yitter.IdGenerator/Core/SnowWorkerM1.cs
  7. +6
    -0
      C#.NET/source/Yitter.IdGenerator/DefaultIdGenerator.cs
  8. +14
    -7
      C#.NET/source/Yitter.IdGenerator/YitIdHelper.cs
  9. +3
    -1
      C#.NET/source/Yitter.IdGenerator/Yitter.IdGenerator.csproj
  10. +4
    -2
      C/source/.gitignore
  11. +9
    -10
      C/source/CMakeLists.txt
  12. +72
    -32
      C/source/idgen/IdGenerator.c
  13. +1
    -0
      C/source/idgen/SnowWorkerM1.c
  14. +27
    -16
      C/source/main.c
  15. +1
    -1
      Go/README.md
  16. +262
    -0
      Go/regworkerid/.gitignore
  17. +10
    -0
      Go/regworkerid/go.mod
  18. +106
    -0
      Go/regworkerid/go.sum
  19. +69
    -0
      Go/regworkerid/main.go
  20. +5
    -0
      Go/regworkerid/reg.go
  21. +0
    -0
      Go/regworkerid/regworkerid/reghelper.go
  22. +262
    -0
      Go/source/.gitignore
  23. +8
    -5
      Go/source/go.mod
  24. +34
    -31
      Go/source/go.sum
  25. +10
    -0
      Go/source/idgen/DefaultIdGenerator.go
  26. +14
    -11
      Go/source/idgen/SnowWorkerM1.go
  27. +21
    -7
      Go/source/idgen/YitIdHelper.go
  28. +19
    -103
      Go/source/main.go
  29. +3
    -1
      Java/source/.gitignore
  30. +3
    -3
      Java/source/pom.xml
  31. +12
    -7
      Java/source/src/main/java/com/github/yitter/core/SnowWorkerM1.java
  32. +7
    -2
      Java/source/src/main/java/com/github/yitter/idgen/DefaultIdGenerator.java
  33. +6
    -4
      Java/source/src/main/java/com/github/yitter/idgen/YitIdHelper.java
  34. +1
    -1
      Java/source/src/test/java/com/github/yitter/test/GenTest.java
  35. +5
    -4
      Java/source/src/test/java/com/github/yitter/test/StartUp.java
  36. BIN
      PHP/Release/php7.3nts-vc15-php_snowdrift.zip
  37. BIN
      PHP/Release/php7.4nts-vc15-php_snowdrift.zip
  38. BIN
      PHP/Release/php8.0nts-vs16-php_snowdrift.zip
  39. +4
    -9
      PHP/config.w32
  40. +2
    -4
      PHP/snowdrift.c
  41. +79
    -38
      PHP/src/snowflake/shm.c
  42. +230
    -207
      PHP/src/snowflake/snowflake.c
  43. +61
    -35
      PHP/src/snowflake/spinlock.c
  44. +12
    -0
      Python/README.md
  45. +31
    -0
      Python/source/DefaultIdGenerator.py
  46. +30
    -0
      Python/source/IdGeneratorOptions.py
  47. +11
    -0
      Python/source/SnowFlake.py
  48. +12
    -0
      Python/source/SnowFlakeM1.py
  49. +1
    -3
      README.md
  50. +2
    -1
      Rust/source/.gitignore
  51. +44
    -19
      Rust/source/src/idgen/snow_worker_m1.rs
  52. +24
    -22
      Rust/source/src/main.rs
  53. +1
    -6
      Tools/AutoRegisterWorkerId/lib/yitidgengo.h

+ 1
- 0
.gitignore View File

@@ -7,6 +7,7 @@
*.userosscache
*.sln.docstates
*.editorconfig
__*.bat

# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs


+ 2
- 2
C#.NET/source/Yitter.IdGen.sln View File

@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31005.135
# Visual Studio Version 17
VisualStudioVersion = 17.2.32602.215
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yitter.IdGenerator", "Yitter.IdGenerator\Yitter.IdGenerator.csproj", "{FF8DAF11-34E7-4842-ADF2-3722A1A5FBB2}"
EndProject


+ 110
- 17
C#.NET/source/Yitter.IdGenTest/Program.cs View File

@@ -1,5 +1,6 @@
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
@@ -11,7 +12,7 @@ namespace Yitter.OrgSystem.TestA
class Program
{
// 测试参数(默认配置下,最佳性能是10W/s)
static int genIdCount = 2;//50000; // 计算ID数量(如果要验证50W效率,请将TopOverCostCount设置为20000或适当增加SeqBitLength)
static int genIdCount = 50000;//5000; // 计算ID数量(如果要验证50W效率,请将TopOverCostCount设置为2000或适当增加SeqBitLength)
static short method = 1; // 1-漂移算法,2-传统算法
@@ -26,23 +27,24 @@ namespace Yitter.OrgSystem.TestA
static void Main(string[] args)
{
RunSingle();
return;
Console.WriteLine("Hello World! C#");
var options = new IdGeneratorOptions()
{
Method = method,
Method = 1,
WorkerId = 1,
WorkerIdBitLength = 6,
SeqBitLength = 6,
DataCenterIdBitLength = 10,
DataCenterIdBitLength = 0,
TopOverCostCount = 2000,
//TimestampType = 1,
// MinSeqNumber = 1,
// MaxSeqNumber = 200,
// BaseTime = DateTime.Now.AddYears(-10),
};
@@ -55,27 +57,118 @@ namespace Yitter.OrgSystem.TestA
Console.WriteLine("=====================================");
Console.WriteLine("这是用方法 " + method + " 生成的 Id:" + newId);
while (true)
var seed1 = 50;
var seed2 = 1000;
var finish = 0;
var next = IdGen.NewLong();
var hashSet = new HashSet<long>(seed1 * seed2);
ConcurrentBag<long> bags = new ConcurrentBag<long>();
for (int i = 0; i < seed1; i++)
{
(new Thread(_ =>
{
for (int j = 0; j < seed2; j++)
{
var me = IdGen.NewLong();
hashSet.Add(me);
bags.Add(me);
}
Interlocked.Increment(ref finish);
})
{ IsBackground = true }).Start();
}
while (finish < seed1)
{
RunSingle();
//CallDll();
//Go(options);
Thread.Sleep(1000); // 每隔1秒执行一次Go
Console.WriteLine("等待执行结束");
Thread.Sleep(2000);
}
Console.WriteLine($"hashSet 共计:{hashSet.Count} 实际应该:{seed1 * seed2}");
Console.WriteLine($"bags 共计:{bags.Count} 实际应该:{seed1 * seed2}");
var IdArray = bags.ToArray();
int totalCount = 0;
for (int i = 0; i < seed1 * seed2; i++)
{
var me = IdArray[i];
int j = 0;
int count = 0;
while (j < seed1 * seed2)
{
if (IdArray[j] == me)
{
count++;
}
j++;
}
if (count > 1)
{
totalCount++;
Console.WriteLine($"{IdArray[i]},重复:{count}");
}
}
if (totalCount == 0)
{
Console.WriteLine($"重复数为 0 ");
}
Console.Read();
//while (true)
//{
// //RunSingle();
// //CallDll();
// //Go(options);
// Thread.Sleep(1000); // 每隔1秒执行一次Go
//}
}
private static void RunSingle()
{
DateTime start = DateTime.Now;
for (int i = 0; i < genIdCount; i++)
var options = new IdGeneratorOptions()
{
var id = IdGen.NewLong();
}
Method = 1,
WorkerId = 1,
//WorkerIdBitLength = 6,
SeqBitLength = 6,
//TopOverCostCount = 2000,
//DataCenterIdBitLength = 0,
//TimestampType = 1,
// MinSeqNumber = 1,
// MaxSeqNumber = 200,
// BaseTime = DateTime.Now.AddYears(-10),
};
DateTime end = DateTime.Now;
Console.WriteLine($"++++++++++++++++++++++++++++++++++++++++, total: {(end - start).TotalMilliseconds} ms");
Interlocked.Increment(ref Program.Count);
//IdGen = new DefaultIdGenerator(options);
YitIdHelper.SetIdGenerator(options);
while (true)
{
DateTime start = DateTime.Now;
for (int i = 0; i < genIdCount; i++)
{
//var id = IdGen.NewLong();
var id = YitIdHelper.NextId();
}
DateTime end = DateTime.Now;
Console.WriteLine($"++++++++++++++++++++++++++++++++++++++++, total: {(end - start).TotalMilliseconds} ms");
Thread.Sleep(1000);
}
//Interlocked.Increment(ref Program.Count);
}
private static void Go(IdGeneratorOptions options)


+ 1
- 1
C#.NET/source/Yitter.IdGenTest/Yitter.IdGenTest.csproj View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>


+ 0
- 1
C#.NET/source/Yitter.IdGenerator/Contract/IdGeneratorOptions.cs View File

@@ -63,7 +63,6 @@ namespace Yitter.IdGenerator
/// </summary>
public virtual int TopOverCostCount { get; set; } = 2000;
/// <summary>
/// 数据中心ID(默认0)
/// </summary>


+ 5
- 4
C#.NET/source/Yitter.IdGenerator/Core/SnowWorkerM1.cs View File

@@ -118,10 +118,10 @@ namespace Yitter.IdGenerator
// 7.Others
TopOverCostCount = options.TopOverCostCount;
if (TopOverCostCount == 0)
{
TopOverCostCount = 2000;
}
//if (TopOverCostCount == 0)
//{
// TopOverCostCount = 2000;
//}
_TimestampShift = (byte)(WorkerIdBitLength + SeqBitLength);
_CurrentSeqNumber = options.MinSeqNumber;
@@ -351,6 +351,7 @@ namespace Yitter.IdGenerator
while (tempTimeTicker <= _LastTimeTick)
{
Thread.Sleep(1);
tempTimeTicker = GetCurrentTimeTick();
}


+ 6
- 0
C#.NET/source/Yitter.IdGenerator/DefaultIdGenerator.cs View File

@@ -92,6 +92,12 @@ namespace Yitter.IdGenerator
throw new ApplicationException("MinSeqNumber error. (range:[5, " + maxSeqNumber + "]");
}
// 7.TopOverCostCount
if (options.TopOverCostCount < 0 || options.TopOverCostCount > 10000)
{
throw new ApplicationException("TopOverCostCount error. (range:[0, 10000]");
}
switch (options.Method)
{
case 2:


+ 14
- 7
C#.NET/source/Yitter.IdGenerator/YitIdHelper.cs View File

@@ -34,17 +34,24 @@ namespace Yitter.IdGenerator
/// <summary>
/// 生成新的Id
/// 调用本方法前,请确保调用了 SetIdGenerator 方法做初始化。
/// 否则将会初始化一个WorkerId为1的对象。
/// </summary>
/// <returns></returns>
public static long NextId()
{
if (_IdGenInstance == null)
{
_IdGenInstance = new DefaultIdGenerator(
new IdGeneratorOptions() { WorkerId = 0 }
);
}
//if (_IdGenInstance == null)
//{
// lock (_IdGenInstance)
// {
// if (_IdGenInstance == null)
// {
// _IdGenInstance = new DefaultIdGenerator(
// new IdGeneratorOptions() { WorkerId = 0 }
// );
// }
// }
//}
if (_IdGenInstance == null) throw new ApplicationException("Please initialize Yitter.IdGeneratorOptions first.");
return _IdGenInstance.NewLong();
}


+ 3
- 1
C#.NET/source/Yitter.IdGenerator/Yitter.IdGenerator.csproj View File

@@ -18,8 +18,10 @@
<Copyright>Yitter</Copyright>
<PackageProjectUrl>https://github.com/yitter/idgenerator</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Version>1.0.12</Version>
<Version>1.0.14</Version>
<PackageReleaseNotes></PackageReleaseNotes>
<AssemblyVersion>1.0.0.*</AssemblyVersion>
<FileVersion>1.0.0.*</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">


+ 4
- 2
C/source/.gitignore View File

@@ -1,7 +1,7 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.

build/*
build

# User-specific files
*.suo
@@ -29,6 +29,7 @@ bld/
**/.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
.vscode

# MSTest test Results
[Tt]est[Rr]esult*/
@@ -254,7 +255,8 @@ paket-files/
.idea/
*.sln.iml
target/
cmake-build*/
cmake-build-*
source.code-*

# macOS
.DS_Store

+ 9
- 10
C/source/CMakeLists.txt View File

@@ -8,18 +8,17 @@ set(CMAKE_C_STANDARD 11)
aux_source_directory(. DIR_SRCS)
add_subdirectory(idgen)


#编译动态库
#set(LIB_SRC YitIdHelper.h YitIdHelper.c)
#add_library(YitIdGenLib SHARED ${LIB_SRC})
#target_link_libraries(YitIdGenLib idgen)
#set_target_properties(YitIdGenLib PROPERTIES
# LINKER_LANGUAGE C
# OUTPUT_NAME "yitidgenc"
# PREFIX "")

##编译执行文件
set(LIB_SRC YitIdHelper.h YitIdHelper.c)
add_library(YitIdGenLib SHARED ${LIB_SRC})
target_link_libraries(YitIdGenLib idgen)
set_target_properties(YitIdGenLib PROPERTIES
LINKER_LANGUAGE C
OUTPUT_NAME "yitidgenc"
PREFIX "")

# 编译执行文件
# set(LIB_SRC YitIdHelper.h YitIdHelper.c)
add_library(YitIdHelper ${LIB_SRC})
add_executable(YitIdGen main.c)
target_link_libraries(YitIdGen YitIdHelper pthread)


+ 72
- 32
C/source/idgen/IdGenerator.c View File

@@ -9,107 +9,147 @@
#include <unistd.h>
#include "IdGenerator.h"
static inline uint64_t WorkerM1Id() {
static inline uint64_t WorkerM1Id()
{
return WorkerM1NextId(_idGenerator->Worker);
}
static inline uint64_t WorkerM2Id() {
static inline uint64_t WorkerM2Id()
{
return WorkerM2NextId(_idGenerator->Worker);
}
extern IdGenerator *GetIdGenInstance() {
extern IdGenerator *GetIdGenInstance()
{
if (_idGenerator != NULL)
return _idGenerator;
else {
_idGenerator = (IdGenerator *) malloc(sizeof(IdGenerator));
else
{
_idGenerator = (IdGenerator *)malloc(sizeof(IdGenerator));
_idGenerator->Worker = NewSnowFlakeWorker();
return _idGenerator;
}
}
extern void SetOptions(IdGeneratorOptions options) {
if (GetIdGenInstance() == NULL) {
extern void SetOptions(IdGeneratorOptions options)
{
if (GetIdGenInstance() == NULL)
{
exit(1);
}
// 1.BaseTime
if (options.BaseTime == 0) {
if (options.BaseTime == 0)
{
_idGenerator->Worker->BaseTime = 1582136402000;
} else if (options.BaseTime < 631123200000 || options.BaseTime > GetCurrentTime()) {
}
else if (options.BaseTime < 631123200000 || options.BaseTime > GetCurrentTime())
{
perror("BaseTime error.");
exit(1);
} else {
}
else
{
_idGenerator->Worker->BaseTime = options.BaseTime;
}
// 2.WorkerIdBitLength
if (options.WorkerIdBitLength <= 0) {
if (options.WorkerIdBitLength <= 0)
{
perror("WorkerIdBitLength error.(range:[1, 21])");
exit(1);
}
if (options.SeqBitLength + options.WorkerIdBitLength > 22) {
if (options.SeqBitLength + options.WorkerIdBitLength > 22)
{
perror("error:WorkerIdBitLength + SeqBitLength <= 22");
exit(1);
} else {
}
else
{
// _idGenerator->Worker->WorkerIdBitLength = options.WorkerIdBitLength;
_idGenerator->Worker->WorkerIdBitLength = options.WorkerIdBitLength <= 0 ? 6 : options.WorkerIdBitLength;
}
// 3.WorkerId
uint32_t maxWorkerIdNumber = (1 << options.WorkerIdBitLength) - 1;
if (maxWorkerIdNumber == 0) {
if (maxWorkerIdNumber == 0)
{
maxWorkerIdNumber = 63;
}
if (options.WorkerId < 0 || options.WorkerId > maxWorkerIdNumber) {
if (options.WorkerId < 0 || options.WorkerId > maxWorkerIdNumber)
{
perror("WorkerId error. (range:[0, {2^options.WorkerIdBitLength-1]}");
exit(1);
} else {
}
else
{
_idGenerator->Worker->WorkerId = options.WorkerId;
}
// 4.SeqBitLength
if (options.SeqBitLength < 2 || options.SeqBitLength > 21) {
if (options.SeqBitLength < 2 || options.SeqBitLength > 21)
{
perror("SeqBitLength error. (range:[2, 21])");
exit(1);
} else {
}
else
{
// _idGenerator->Worker->SeqBitLength = options.SeqBitLength;
_idGenerator->Worker->SeqBitLength = options.SeqBitLength <= 0 ? 6 : options.SeqBitLength;
}
// 5.MaxSeqNumber
uint32_t maxSeqNumber = (1 << options.SeqBitLength) - 1;
if (maxSeqNumber == 0) {
if (maxSeqNumber == 0)
{
maxSeqNumber = 63;
}
if (options.MaxSeqNumber > maxSeqNumber) {
if (options.MaxSeqNumber > maxSeqNumber)
{
perror("MaxSeqNumber error. (range:[1, {2^options.SeqBitLength-1}]");
exit(1);
} else {
}
else
{
_idGenerator->Worker->MaxSeqNumber = options.MaxSeqNumber <= 0 ? maxSeqNumber : options.MaxSeqNumber;
}
// 6.MinSeqNumber
if (options.MinSeqNumber < 5 || options.MinSeqNumber > maxSeqNumber) {
if (options.MinSeqNumber < 5 || options.MinSeqNumber > maxSeqNumber)
{
perror("MinSeqNumber error. (range:[5, {options.MinSeqNumber}]");
exit(1);
} else {
}
else
{
_idGenerator->Worker->MinSeqNumber = options.MinSeqNumber <= 0 ? 5 : options.MinSeqNumber;
}
// 7.Others
_idGenerator->Worker->TopOverCostCount = options.TopOverCostCount <= 0 ? 2000 : options.TopOverCostCount;
// 7.TopOverCostCount
if (options.TopOverCostCount < 0 || options.TopOverCostCount > 10000)
{
perror("TopOverCostCount error. (range:[0, 10000]");
exit(1);
}
else
{
//_idGenerator->Worker->TopOverCostCount = options.TopOverCostCount <= 0 ? 2000 : options.TopOverCostCount;
_idGenerator->Worker->TopOverCostCount = options.TopOverCostCount;
}
// 8.Others
_idGenerator->Worker->_TimestampShift =
_idGenerator->Worker->WorkerIdBitLength + _idGenerator->Worker->SeqBitLength;
_idGenerator->Worker->WorkerIdBitLength + _idGenerator->Worker->SeqBitLength;
_idGenerator->Worker->_CurrentSeqNumber = _idGenerator->Worker->MinSeqNumber;
_idGenerator->Worker->Method = options.Method;
if (options.Method == 2) {
if (options.Method == 2)
{
_idGenerator->NextId = WorkerM2Id;
} else {
}
else
{
_idGenerator->NextId = WorkerM1Id;
sleep(1);
usleep(500 * 1000); // 暂停500ms
}
}

+ 1
- 0
C/source/idgen/SnowWorkerM1.c View File

@@ -162,6 +162,7 @@ extern int64_t GetCurrentMicroTime() {
extern int64_t GetNextTimeTick(SnowFlakeWorker *worker) {
uint64_t tempTimeTicker = GetCurrentTimeTick(worker);
while (tempTimeTicker <= worker->_LastTimeTick) {
usleep(1000); // 暂停1ms
tempTimeTicker = GetCurrentTimeTick(worker);
}
return tempTimeTicker;


+ 27
- 16
C/source/main.c View File

@@ -13,51 +13,62 @@
#include "idgen/IdGenerator.h"
#include "YitIdHelper.h"
const int GenIdCount = 50000;
const int GenIdCount = 500000;
const bool multiThread = false;
const int threadCount = 50;
const int method = 1;
void RunMultiThread() {
//int64_t start = GetCurrentMicroTime();
for (int i = 0; i < GenIdCount / threadCount; i++) {
void RunMultiThread()
{
// int64_t start = GetCurrentMicroTime();
for (int i = 0; i < GenIdCount / threadCount; i++)
{
int64_t id = NextId();
printf("ID: %D\n", id);
}
int64_t end = GetCurrentMicroTime();
//printf("%s,total:%d μs\n", method == 1 ? "1" : "2", (end - start));
// printf("%s,total:%d μs\n", method == 1 ? "1" : "2", (end - start));
}
void RunSingle() {
void RunSingle()
{
int64_t start = GetCurrentMicroTime();
for (int i = 0; i < GenIdCount; i++) {
for (int i = 0; i < GenIdCount; i++)
{
int64_t id = NextId();
// printf("ID: %ld\n", id);
// printf("ID: %ld\n", id);
}
int64_t end = GetCurrentMicroTime();
printf("%s, total: %d us\n", method == 1 ? "1" : "2", (end - start));
}
int main() {
int main()
{
IdGeneratorOptions options = BuildIdGenOptions(1);
options.Method = method;
options.WorkerId = 1;
options.SeqBitLength = 6;
options.SeqBitLength = 10;
// options.TopOverCostCount = 2000;
SetIdGenerator(options);
pthread_t tid[threadCount];
while (1) {
if (multiThread) {
for (int i = 0; i < threadCount; i++) {
if (pthread_create(&tid[i], NULL, (void *) RunMultiThread, NULL) != 0) {
while (1)
{
if (multiThread)
{
for (int i = 0; i < threadCount; i++)
{
if (pthread_create(&tid[i], NULL, (void *)RunMultiThread, NULL) != 0)
{
printf("thread creation failed\n");
exit(1);
}
}
} else {
}
else
{
RunSingle();
}


+ 1
- 1
Go/README.md View File

@@ -31,7 +31,7 @@ var newId = idgen.NextId()
## 关于Go环境
1.SDK,go1.14
1.SDK,go1.16
2.启用 Go-Modules
```


+ 262
- 0
Go/regworkerid/.gitignore View File

@@ -0,0 +1,262 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.

# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
*.editorconfig
.vscode
__commit.bat
__download.bat
target

# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/

# Visual Studio 2015 cache/options directory
**/.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/

# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

# NUNIT
*.VisualState.xml
TestResult.xml

# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c

# DNX
project.lock.json
artifacts/

*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc

# Chutzpah Test files
_Chutzpah*

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb

# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap

# TFS 2012 Local Workspace
$tf/

# Guidance Automation Toolkit
*.gpState

# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user

# JustCode is a .NET coding add-in
.JustCode

# TeamCity is a build add-in
_TeamCity*

# DotCover is a Code Coverage Tool
*.dotCover

# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*

# MightyMoose
*.mm.*
AutoTest.Net/

# Web workbench (sass)
.sass-cache/

# Installshield output folder
[Ee]xpress/

# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html

# Click-Once directory
publish/

# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj

# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/

# NuGet Packages
*.nupkg
*.snupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets

# Microsoft Azure Build Output
csx/
*.build.csdef

# Microsoft Azure Emulator
ecf/
rcf/

# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt

# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/

# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs

# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/

# RIA/Silverlight projects
Generated_Code/

# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm

# SQL Server files
*.mdf
*.ldf

# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings

# Microsoft Fakes
FakesAssemblies/

# GhostDoc plugin setting file
*.GhostDoc.xml

# Node.js Tools for Visual Studio
.ntvs_analysis.dat

# Visual Studio 6 build log
*.plg

# Visual Studio 6 workspace options file
*.opt

# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions

# Paket dependency manager
.paket/paket.exe
paket-files/

# FAKE - F# Make
.fake/

# JetBrains Rider
.idea/
*.sln.iml


# macOS
.DS_Store

+ 10
- 0
Go/regworkerid/go.mod View File

@@ -0,0 +1,10 @@
module github.com/yitter/idgenerator-go
go 1.17
require github.com/go-redis/redis/v8 v8.11.5
require (
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
)

+ 106
- 0
Go/regworkerid/go.sum View File

@@ -0,0 +1,106 @@
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
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/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
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.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
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/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
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.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
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.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
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-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
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-20191204072324-ce4227a45e2e/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-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/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/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/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
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.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
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=

+ 69
- 0
Go/regworkerid/main.go View File

@@ -0,0 +1,69 @@
package main

import (
"C"
"fmt"
"time"

"github.com/yitter/idgenerator-go/regworkerid"
)

func main() {
ip := "localhost"
password := ""

ipChar := C.CString(ip)
passChar := C.CString(password)

workerIdList := RegisterMany(ipChar, 6379, passChar, 4, 3, 0)
for _, value := range workerIdList {
fmt.Println("注册的WorkerId:", value)
}

id := RegisterOne(ipChar, 6379, passChar, 4, 0)
fmt.Println("注册的WorkerId:", id)

// var workerId = regworkerid.RegisterOne(ip, 6379, "", 4)
// fmt.Println("注册的WorkerId:", workerId)

fmt.Println("end")
time.Sleep(time.Duration(300) * time.Second)
}

//export RegisterOne
// 注册一个 WorkerId
func RegisterOne(ip *C.char, port int32, password *C.char, maxWorkerId int32, database int) int32 {
return regworkerid.RegisterOne(C.GoString(ip), port, C.GoString(password), maxWorkerId, database)
}

//export UnRegister
// 注销本机已注册的 WorkerId
func UnRegister() {
regworkerid.UnRegister()
}

// export Validate
// 检查本地WorkerId是否有效(0-有效,其它-无效)
func Validate(workerId int32) int32 {
return regworkerid.Validate(workerId)
}

// RegisterMany
// 注册多个 WorkerId,会先注销所有本机已注册的记录
func RegisterMany(ip *C.char, port int32, password *C.char, maxWorkerId, totalCount int32, database int) []int32 {
// return (*C.int)(unsafe.Pointer(&values))
//return regworkerid.RegisterMany(ip, port, password, maxWorkerId, totalCount, database)
return regworkerid.RegisterMany(C.GoString(ip), port, C.GoString(password), maxWorkerId, totalCount, database)
}

// To Build a dll/so:

// windows:
// go build -o ./target/yitidgengo.dll -buildmode=c-shared main.go
// // go build -o ./target/yitidgengo.dll -buildmode=c-shared main.go reg.go

// linux init: go install -buildmode=shared -linkshared std
// go build -o ./target/yitidgengo.so -buildmode=c-shared main.go
// go build -o ./target/yitidgengo.so -buildmode=c-shared main.go reg.go

// https://books.studygolang.com/advanced-go-programming-book/ch2-cgo/ch2-09-static-shared-lib.html

+ 5
- 0
Go/regworkerid/reg.go View File

@@ -0,0 +1,5 @@
package main

import (
"C"
)

Go/source/regworkerid/reghelper.go → Go/regworkerid/regworkerid/reghelper.go View File


+ 262
- 0
Go/source/.gitignore View File

@@ -0,0 +1,262 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.

# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
*.editorconfig
.vscode
__commit.bat
__download.bat
target

# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/

# Visual Studio 2015 cache/options directory
**/.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/

# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

# NUNIT
*.VisualState.xml
TestResult.xml

# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c

# DNX
project.lock.json
artifacts/

*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc

# Chutzpah Test files
_Chutzpah*

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb

# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap

# TFS 2012 Local Workspace
$tf/

# Guidance Automation Toolkit
*.gpState

# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user

# JustCode is a .NET coding add-in
.JustCode

# TeamCity is a build add-in
_TeamCity*

# DotCover is a Code Coverage Tool
*.dotCover

# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*

# MightyMoose
*.mm.*
AutoTest.Net/

# Web workbench (sass)
.sass-cache/

# Installshield output folder
[Ee]xpress/

# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html

# Click-Once directory
publish/

# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj

# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/

# NuGet Packages
*.nupkg
*.snupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets

# Microsoft Azure Build Output
csx/
*.build.csdef

# Microsoft Azure Emulator
ecf/
rcf/

# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt

# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/

# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs

# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/

# RIA/Silverlight projects
Generated_Code/

# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm

# SQL Server files
*.mdf
*.ldf

# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings

# Microsoft Fakes
FakesAssemblies/

# GhostDoc plugin setting file
*.GhostDoc.xml

# Node.js Tools for Visual Studio
.ntvs_analysis.dat

# Visual Studio 6 build log
*.plg

# Visual Studio 6 workspace options file
*.opt

# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions

# Paket dependency manager
.paket/paket.exe
paket-files/

# FAKE - F# Make
.fake/

# JetBrains Rider
.idea/
*.sln.iml


# macOS
.DS_Store

+ 8
- 5
Go/source/go.mod View File

@@ -1,5 +1,8 @@
module yitidgen

go 1.16

require github.com/go-redis/redis/v8 v8.8.0 // indirect
module github.com/yitter/idgenerator-go
go 1.17
require (
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
)

+ 34
- 31
Go/source/go.sum View File

@@ -1,15 +1,18 @@
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
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/go-redis/redis/v8 v8.8.0 h1:fDZP58UN/1RD3DjtTXP/fFZ04TFohSYhjZDkcDe2dnw=
github.com/go-redis/redis/v8 v8.8.0/go.mod h1:F7resOH5Kdug49Otu24RjHWwgK7u9AmtqWMnCV1iP5Y=
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
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=
@@ -17,38 +20,33 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU
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/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
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/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
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.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg=
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/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
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.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48=
github.com/onsi/gomega v1.11.0 h1:+CqWgvj0OZycCaqclBD1pxKHAU+tOkHmQIWvDHq2aug=
github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.opentelemetry.io/otel v0.19.0 h1:Lenfy7QHRXPZVsw/12CWpxX6d/JkrX8wrx2vO8G80Ng=
go.opentelemetry.io/otel v0.19.0/go.mod h1:j9bF567N9EfomkSidSfmMwIwIBuP37AMAIzVW85OxSg=
go.opentelemetry.io/otel/metric v0.19.0 h1:dtZ1Ju44gkJkYvo+3qGqVXmf88tc+a42edOywypengg=
go.opentelemetry.io/otel/metric v0.19.0/go.mod h1:8f9fglJPRnXuskQmKpnad31lcLJ2VmNNqIsx/uIwBSc=
go.opentelemetry.io/otel/oteltest v0.19.0/go.mod h1:tI4yxwh8U21v7JD6R3BcA/2+RBoTKFexE/PJ/nSO7IA=
go.opentelemetry.io/otel/trace v0.19.0 h1:1ucYlenXIDA1OlHVLDZKX0ObXV5RLaq06DtUKz5e5zc=
go.opentelemetry.io/otel/trace v0.19.0/go.mod h1:4IXiNextNOpPnRlI4ryK69mn5iC84bjBWZQA5DXz/qg=
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=
@@ -58,8 +56,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
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/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
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=
@@ -69,35 +67,40 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
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-20191204072324-ce4227a45e2e/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-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
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/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/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=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
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.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
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=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

+ 10
- 0
Go/source/idgen/DefaultIdGenerator.go View File

@@ -4,6 +4,7 @@
* 代码修订:yitter
* 开源地址:https://github.com/yitter/idgenerator
*/

package idgen

import (
@@ -64,6 +65,11 @@ func NewDefaultIdGenerator(options *IdGeneratorOptions) *DefaultIdGenerator {
panic("MinSeqNumber error. (range:[5, " + strconv.FormatUint(uint64(maxSeqNumber), 10) + "]")
}

// 7.TopOverCostCount
if options.TopOverCostCount < 0 || options.TopOverCostCount > 10000 {
panic("TopOverCostCount error. (range:[0, 10000]")
}

var snowWorker ISnowWorker
switch options.Method {
case 1:
@@ -87,3 +93,7 @@ func NewDefaultIdGenerator(options *IdGeneratorOptions) *DefaultIdGenerator {
func (dig DefaultIdGenerator) NewLong() int64 {
return dig.SnowWorker.NextId()
}

func (dig DefaultIdGenerator) ExtractTime(id int64) time.Time {
return time.UnixMilli(id>>(dig.Options.WorkerIdBitLength+dig.Options.SeqBitLength) + dig.Options.BaseTime)
}

+ 14
- 11
Go/source/idgen/SnowWorkerM1.go View File

@@ -4,6 +4,7 @@
* 代码修订:yitter
* 开源地址:https://github.com/yitter/idgenerator
*/

package idgen

import (
@@ -13,13 +14,13 @@ import (

// SnowWorkerM1 .
type SnowWorkerM1 struct {
BaseTime int64 //基础时间
WorkerId uint16 //机器码
WorkerIdBitLength byte //机器码位长
SeqBitLength byte //自增序列数位长
MaxSeqNumber uint32 //最大序列数(含)
MinSeqNumber uint32 //最小序列数(含)
TopOverCostCount uint32 //最大漂移次数
BaseTime int64 // 基础时间
WorkerId uint16 // 机器码
WorkerIdBitLength byte // 机器码位长
SeqBitLength byte // 自增序列数位长
MaxSeqNumber uint32 // 最大序列数(含)
MinSeqNumber uint32 // 最小序列数(含)
TopOverCostCount uint32 // 最大漂移次数
_TimestampShift byte
_CurrentSeqNumber uint32

@@ -75,12 +76,13 @@ func NewSnowWorkerM1(options *IdGeneratorOptions) ISnowWorker {
// 6.MinSeqNumber
var minSeqNumber = options.MinSeqNumber

// 7.Others
// 7.TopOverCostCount
var topOverCostCount = options.TopOverCostCount
if topOverCostCount == 0 {
topOverCostCount = 2000
}
// if topOverCostCount == 0 {
// topOverCostCount = 2000
// }

// 8.Others
timestampShift := (byte)(workerIdBitLength + seqBitLength)
currentSeqNumber := minSeqNumber

@@ -232,6 +234,7 @@ func (m1 *SnowWorkerM1) GetCurrentTimeTick() int64 {
func (m1 *SnowWorkerM1) GetNextTimeTick() int64 {
tempTimeTicker := m1.GetCurrentTimeTick()
for tempTimeTicker <= m1._LastTimeTick {
time.Sleep(time.Duration(1) * time.Millisecond)
tempTimeTicker = m1.GetCurrentTimeTick()
}
return tempTimeTicker


+ 21
- 7
Go/source/idgen/YitIdHelper.go View File

@@ -1,7 +1,15 @@
/*
* 版权属于:yitter(yitter@126.com)
* 代码编辑:guoyahao
* 代码修订:yitter
* 开源地址:https://github.com/yitter/idgenerator
*/

package idgen

import (
"sync"
"time"
)

var singletonMutex sync.Mutex
@@ -16,14 +24,20 @@ func SetIdGenerator(options *IdGeneratorOptions) {

// NextId .
func NextId() int64 {
//if idGenerator == nil {
// singletonMutex.Lock()
// defer singletonMutex.Unlock()
// if idGenerator == nil {
// options := NewIdGeneratorOptions(1)
// idGenerator = NewDefaultIdGenerator(options)
// }
//}
if idGenerator == nil {
singletonMutex.Lock()
defer singletonMutex.Unlock()
if idGenerator == nil {
options := NewIdGeneratorOptions(1)
idGenerator = NewDefaultIdGenerator(options)
}
panic("Please initialize Yitter.IdGeneratorOptions first.")
}

return idGenerator.NewLong()
}

func ExtractTime(id int64) time.Time {
return idGenerator.ExtractTime(id)
}

+ 19
- 103
Go/source/main.go View File

@@ -1,136 +1,52 @@
package main

import (
"C"
"fmt"
"time"
"yitidgen/idgen"
"yitidgen/regworkerid"
"github.com/yitter/idgenerator-go/idgen"
)

//export SetOptions
func SetOptions(workerId uint16) {
var options = idgen.NewIdGeneratorOptions(workerId)
idgen.SetIdGenerator(options)
}

//export NextId
func NextId() int64 {
return idgen.NextId()
}

// RegisterOne 注册一个 WorkerId,会先注销所有本机已注册的记录
// address: Redis连接地址,单机模式示例:127.0.0.1:6379,哨兵/集群模式示例:127.0.0.1:26380,127.0.0.1:26381,127.0.0.1:26382
// password: Redis连接密码
// db: Redis指定存储库,示例:1
// sentinelMasterName: Redis 哨兵模式下的服务名称,示例:mymaster
// maxWorkerId: WorkerId 最大值,示例:63
//export RegisterOne
func RegisterOne(address *C.char, password *C.char, db int, sentinelMasterName *C.char, maxWorkerId int32) int32 {
return regworkerid.RegisterOne(regworkerid.RegisterConf{
Address: C.GoString(address),
Password: C.GoString(password),
DB: db,
MasterName: C.GoString(sentinelMasterName),
MaxWorkerId: maxWorkerId,
})
}

// RegisterMany 注册多个 WorkerId,会先注销所有本机已注册的记录
// address: Redis连接地址,单机模式示例:127.0.0.1:6379,哨兵/集群模式示例:127.0.0.1:26380,127.0.0.1:26381,127.0.0.1:26382
// password: Redis连接密码
// db: Redis指定存储库,示例:1
// sentinelMasterName: Redis 哨兵模式下的服务名称,示例:mymaster
// maxWorkerId: WorkerId 最大值,示例:63
// totalCount: 获取N个WorkerId,示例:5
//export RegisterMany
func RegisterMany(address *C.char, password *C.char, db int, sentinelMasterName *C.char, maxWorkerId int32, totalCount int32) []int32 {
return regworkerid.RegisterMany(regworkerid.RegisterConf{
Address: C.GoString(address),
Password: C.GoString(password),
DB: db,
MasterName: C.GoString(sentinelMasterName),
MaxWorkerId: maxWorkerId,
TotalCount: totalCount,
})
}

// UnRegister 注销本机已注册的 WorkerId
//export UnRegister
func UnRegister() {
regworkerid.UnRegister()
}

// Validate 检查本地WorkerId是否有效(0-有效,其它-无效)
//export Validate
func Validate(workerId int32) int32 {
return regworkerid.Validate(workerId)
}

func main() {
const testGenId = true // 测试设置

if testGenId {
// 自定义参数
var options = idgen.NewIdGeneratorOptions(1)
options.WorkerIdBitLength = 6
options.SeqBitLength = 6
options.BaseTime = time.Date(2020, 2, 20, 2, 20, 2, 20, time.UTC).UnixNano() / 1e6
idgen.SetIdGenerator(options)
// 自定义参数
var options = idgen.NewIdGeneratorOptions(1)
options.WorkerIdBitLength = 6
options.SeqBitLength = 10
options.BaseTime = time.Date(2020, 2, 20, 2, 20, 2, 20, time.UTC).UnixNano() / 1e6
idgen.SetIdGenerator(options)

var genCount = 50000
var genCount = 500000
for j := 0; j < 100000; j++ {
for {
var begin = time.Now().UnixNano() / 1e3
var begin = time.Now().UnixNano() / 1e6
for i := 0; i < genCount; i++ {
// 生成ID
id := idgen.NextId()
fmt.Println(id)
idgen.NextId()
// fmt.Println(id)
}
var end = time.Now().UnixNano() / 1e3
var end = time.Now().UnixNano() / 1e6

fmt.Println(end - begin)
fmt.Println("耗时:", (end - begin), "ms")
time.Sleep(time.Duration(1000) * time.Millisecond)
}
} else {

//// Redis单机模式下,获取多个WorkerId
//workerIdList := regworkerid.RegisterMany(regworkerid.RegisterConf{
// Address: "127.0.0.1:6379",
// Password: "",
// DB: 0,
// MaxWorkerId: 4,
// TotalCount: 3,
//})
//for _, value := range workerIdList {
// fmt.Println("RegisterMany--注册的WorkerId:", value)
//}

// Redis单机模式下,获取一个WorkerId
var workerId = regworkerid.RegisterOne(regworkerid.RegisterConf{
Address: "127.0.0.1:6379",
Password: "",
DB: 0,
MaxWorkerId: 4,
})
fmt.Println("RegisterOne--注册的WorkerId:", workerId)

//// Redis哨兵模式下,获取一个WorkerId
//var workerId = regworkerid.RegisterOne(regworkerid.RegisterConf{
// //Address: "127.0.0.1:26380,127.0.0.1:26381,127.0.0.1:26382",
// Password: "",
// DB: 0,
// MasterName: "mymaster", // 哨兵模式下的服务名称
// MaxWorkerId: 4,
//})
//fmt.Println("RegisterOne--注册的WorkerId:", workerId)

fmt.Println("end")
time.Sleep(time.Duration(300) * time.Second)
}
}

// To Build a dll/so:

// windows:
// go build -o ./target/yitidgengo.dll -buildmode=c-shared main.go

// linux init: go install -buildmode=shared -linkshared std
// go build -o ./target/yitidgengo.so -buildmode=c-shared main.go

// https://books.studygolang.com/advanced-go-programming-book/ch2-cgo/ch2-09-static-shared-lib.html

+ 3
- 1
Java/source/.gitignore View File

@@ -19,7 +19,9 @@
*.zip
*.tar.gz
*.rar
target/
target
.vscode
*.code-workspace

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

+ 3
- 3
Java/source/pom.xml View File

@@ -41,9 +41,9 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<java.version>1.8</java.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>


+ 12
- 7
Java/source/src/main/java/com/github/yitter/core/SnowWorkerM1.java View File

@@ -66,7 +66,8 @@ public class SnowWorkerM1 implements ISnowWorker {
SeqBitLength = options.SeqBitLength == 0 ? 6 : options.SeqBitLength;
MaxSeqNumber = options.MaxSeqNumber <= 0 ? (1 << SeqBitLength) - 1 : options.MaxSeqNumber;
MinSeqNumber = options.MinSeqNumber;
TopOverCostCount = options.TopOverCostCount == 0 ? 2000 : options.TopOverCostCount;
// TopOverCostCount = options.TopOverCostCount == 0 ? 2000 : options.TopOverCostCount;
TopOverCostCount = options.TopOverCostCount;
_TimestampShift = (byte) (WorkerIdBitLength + SeqBitLength);
_CurrentSeqNumber = MinSeqNumber;
}
@@ -150,11 +151,11 @@ public class SnowWorkerM1 implements ISnowWorker {
BeginTurnBackAction(_TurnBackTimeTick);
}
// try {
// Thread.sleep(1);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// try {
// Thread.sleep(1);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
return CalcTurnBackId(_TurnBackTimeTick);
}
@@ -214,6 +215,11 @@ public class SnowWorkerM1 implements ISnowWorker {
long tempTimeTicker = GetCurrentTimeTick();
while (tempTimeTicker <= _LastTimeTick) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
tempTimeTicker = GetCurrentTimeTick();
}
@@ -227,4 +233,3 @@ public class SnowWorkerM1 implements ISnowWorker {
}
}
}

+ 7
- 2
Java/source/src/main/java/com/github/yitter/idgen/DefaultIdGenerator.java View File

@@ -11,7 +11,6 @@ import com.github.yitter.contract.IdGeneratorOptions;
import com.github.yitter.core.SnowWorkerM1;
import com.github.yitter.core.SnowWorkerM2;
public class DefaultIdGenerator implements IIdGenerator {
private static ISnowWorker _SnowWorker = null;
@@ -40,7 +39,8 @@ public class DefaultIdGenerator implements IIdGenerator {
maxWorkerIdNumber = 63;
}
if (options.WorkerId < 0 || options.WorkerId > maxWorkerIdNumber) {
throw new IdGeneratorException("WorkerId error. (range:[0, " + (maxWorkerIdNumber > 0 ? maxWorkerIdNumber : 63) + "]");
throw new IdGeneratorException(
"WorkerId error. (range:[0, " + (maxWorkerIdNumber > 0 ? maxWorkerIdNumber : 63) + "]");
}
// 4.SeqBitLength
@@ -62,6 +62,11 @@ public class DefaultIdGenerator implements IIdGenerator {
throw new IdGeneratorException("MinSeqNumber error. (range:[5, " + maxSeqNumber + "]");
}
// 7.TopOverCostCount
if (options.TopOverCostCount < 0 || options.TopOverCostCount > 10000) {
throw new IdGeneratorException("TopOverCostCount error. (range:[0, 10000]");
}
switch (options.Method) {
case 2:
_SnowWorker = new SnowWorkerM2(options);


+ 6
- 4
Java/source/src/main/java/com/github/yitter/idgen/YitIdHelper.java View File

@@ -19,7 +19,6 @@ public class YitIdHelper {
return idGenInstance;
}
/**
* 设置参数,建议程序初始化时执行一次
*/
@@ -34,9 +33,12 @@ public class YitIdHelper {
* @return
*/
public static long nextId() throws IdGeneratorException {
if (idGenInstance == null) {
idGenInstance = new DefaultIdGenerator(new IdGeneratorOptions((short) 1));
}
// if (idGenInstance == null) {
// idGenInstance = new DefaultIdGenerator(new IdGeneratorOptions((short) 1));
// }
if (idGenInstance == null)
throw new IdGeneratorException("Please initialize Yitter.IdGeneratorOptions first.");
return idGenInstance.newLong();
}


+ 1
- 1
Java/source/src/test/java/com/github/yitter/test/GenTest.java View File

@@ -26,7 +26,7 @@ public class GenTest {
long end = System.currentTimeMillis();
long time = end - start;
System.out.println(id);
// System.out.println(id);
System.out.println("++++++++++++++++++++++++++++++++++++++++WorkerId: "
+ WorkerId + ", total: " + time + " ms");


+ 5
- 4
Java/source/src/test/java/com/github/yitter/test/StartUp.java View File

@@ -12,7 +12,7 @@ public class StartUp {
* [不同CPU可能结果有差异,但相对大小不变]
* 默认配置下,最佳性能是5W/s-8W/s
*/
final static int genIdCount = 50000;
final static int genIdCount = 500000;
//1-漂移算法,2-传统算法
final static short method = 1;
@@ -20,11 +20,12 @@ public class StartUp {
public static void main(String[] args) {
IdGeneratorOptions options = new IdGeneratorOptions();
// options.WorkerIdBitLength = 6;
// options.SeqBitLength = 6;
// options.WorkerIdBitLength = 6; // 默认6
options.SeqBitLength = 10; // 默认6
// options.BaseTime = 1582206693000L;
options.Method = method;
options.WorkerId = 1;
// options.TopOverCostCount=2000;
// 首先测试一下 IdHelper 方法,获取单个Id
YitIdHelper.setIdGenerator(options);
@@ -38,7 +39,7 @@ public class StartUp {
while (true) {
genTest.GenStart();
Thread.sleep(1000); // 每隔1秒执行一次GenStart
System.out.println("Hello World! Java");
// System.out.println("Hello World! Java");
}
} catch (InterruptedException e) {
e.printStackTrace();


BIN
PHP/Release/php7.3nts-vc15-php_snowdrift.zip View File


BIN
PHP/Release/php7.4nts-vc15-php_snowdrift.zip View File


BIN
PHP/Release/php8.0nts-vs16-php_snowdrift.zip View File


+ 4
- 9
PHP/config.w32 View File

@@ -1,18 +1,13 @@
// $Id$
// vim:ft=javascript

// If your extension references something external, use ARG_WITH
// ARG_WITH("snowdrift", "for snowdrift support", "no");

// Otherwise, use ARG_ENABLE
ARG_ENABLE("snowdrift", "enable snowdrift support", "no");
ARG_ENABLE('snowdrift', 'snowdrift support', 'no');

if (PHP_SNOWDRIFT != "no") {
AC_DEFINE('HAVE_SNOWDRIFT', 1, 'snowdrift support enabled');
snowdrift_source_file="snowdrift.c\
src/snowflake/snowflake.c\
src/snowflake/shm.c\
src/snowflake/spinlock.c
"
EXTENSION("snowdrift", $snowdrift_source_file, PHP_EXTNAME_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
src/snowflake/spinlock.c"
EXTENSION("snowdrift", snowdrift_source_file, null, '/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1');
}


+ 2
- 4
PHP/snowdrift.c View File

@@ -66,9 +66,8 @@ static int snowdrift_init()
shmctx.size = wid_num * sizeof(snowflake);
if (shm_alloc(&shmctx) == -1)
{
return FAILURE;
return FAILURE;
}
bzero(shmctx.addr, wid_num * sizeof(snowflake));
sf = (snowflake *)shmctx.addr;
int i;
for (i = 0; i < wid_num; i++)
@@ -92,7 +91,6 @@ static int snowdrift_init()
{
return FAILURE;
}
bzero(shmctx.addr, sizeof(snowflake));
sf = (snowflake *)shmctx.addr;
sf->Method = SD_G(Method);
sf->BaseTime = SD_G(BaseTime);
@@ -138,7 +136,7 @@ PHP_METHOD(snowdrift, NextNumId)
{
zend_long num = 1;
zend_long wid = SD_G(WorkerId);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l", &num, &wid) == FAILURE)
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|ll", &num, &wid) == FAILURE)
{
RETURN_FALSE;
}


+ 79
- 38
PHP/src/snowflake/shm.c View File

@@ -1,65 +1,106 @@
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#ifdef WIN32
#include "windows.h"
#else
#include <sys/mman.h>
#include <strings.h>
#endif
#include "shm.h"

#ifdef MAP_ANON
#ifdef WIN32
#define NAME "SnowDrift"
static HANDLE hMapFile;

int shm_alloc(struct shm *shm)
{
shm->addr = (void *)mmap(NULL, shm->size,
PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_SHARED, -1, 0);
int shm_alloc(struct shm* shm) {
hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
shm->size,
NAME
);

if (hMapFile == NULL)
{
return 0;
}

LPVOID pBuffer = (LPTSTR)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, shm->size);

if (pBuffer == NULL)
{
CloseHandle(hMapFile);
return 0;
}
memset((char*)pBuffer, 0, shm->size);
shm->addr = (void*)pBuffer;
return 1;
}

void shm_free(struct shm* shm) {
UnmapViewOfFile(shm->addr);
CloseHandle(hMapFile);
}

if (shm->addr == NULL)
{
return -1;
}
#elif defined(MAP_ANON)

return 0;
int shm_alloc(struct shm* shm)
{
shm->addr = (void*)mmap(NULL, shm->size,
PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_SHARED, -1, 0);

if (shm->addr == NULL)
{
return -1;
}
bzero(shm->addr, shm->size);
return 0;
}

void shm_free(struct shm *shm)
void shm_free(struct shm* shm)
{
if (shm->addr)
{
munmap((void *)shm->addr, shm->size);
}
if (shm->addr)
{
munmap((void*)shm->addr, shm->size);
}
}

#else

int shm_alloc(struct shm *shm)
int shm_alloc(struct shm* shm)
{
int fd;

fd = open("/dev/zero", O_RDWR);
if (fd == -1)
{
return -1;
}
int fd;

shm->addr = (void *)mmap(NULL, shm->size,
PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
fd = open("/dev/zero", O_RDWR);
if (fd == -1)
{
return -1;
}

close(fd);
shm->addr = (void*)mmap(NULL, shm->size,
PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);

if (shm->addr == NULL)
{
return -1;
}
close(fd);

return 0;
if (shm->addr == NULL)
{
return -1;
}
bzero(shm->addr, shm->size);
return 0;
}

void shm_free(struct shm *shm)
void shm_free(struct shm* shm)
{
if (shm->addr)
{
munmap((void *)shm->addr, shm->size);
}
if (shm->addr)
{
munmap((void*)shm->addr, shm->size);
}
}

#endif

+ 230
- 207
PHP/src/snowflake/snowflake.c View File

@@ -1,14 +1,16 @@
#ifdef WIN32
#include "windows.h"
#include <sys/timeb.h>
#else
#include <unistd.h>
#include <sys/time.h>
#include <time.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include "snowflake.h"
#include "spinlock.h"

#if defined(WIN32)
#include "windows.h"
#endif

// static void EndOverCostAction(uint64_t useTimeTick, snowflake *flake);
static inline uint64_t NextOverCostId(snowflake *flake);
static inline uint64_t NextNormalId(snowflake *flake);
@@ -16,7 +18,7 @@ static inline uint64_t GetCurrentTimeTick(snowflake *flake);
static inline uint64_t GetNextTimeTick(snowflake *flake);
static inline uint64_t CalcId(snowflake *flake);
static inline uint64_t CalcTurnBackId(snowflake *flake);
static inline uint64_t GetCurrentTime();
static inline uint64_t GetSysCurrentTime();

int ncpu;
uint16_t spin = 2048;
@@ -24,102 +26,103 @@ uint32_t pid = 0;

void Config(snowflake *flake)
{
if (pid == 0)
{
pid = (uint32_t)getpid();
#if defined(WIN32)
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
ncpu = sysInfo.dwNumberOfProcessors;
if (pid == 0)
{
#ifdef WIN32
pid = (uint32_t)GetCurrentProcessId();
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
ncpu = sysInfo.dwNumberOfProcessors;
#else
ncpu = sysconf(_SC_NPROCESSORS_ONLN);
pid = (uint32_t)getpid();
ncpu = sysconf(_SC_NPROCESSORS_ONLN);
#endif
if (ncpu <= 0)
{
ncpu = 1;
}
}
if (flake->BaseTime == 0)
{
flake->BaseTime = 1582136402000;
}
else if (flake->BaseTime < 631123200000 || flake->BaseTime > GetCurrentTime())
{
perror("BaseTime error.");
exit(1);
}
if (ncpu <= 0)
{
ncpu = 1;
}
}
if (flake->BaseTime == 0)
{
flake->BaseTime = 1582136402000;
}
else if (flake->BaseTime < 631123200000 || flake->BaseTime > GetSysCurrentTime())
{
perror("BaseTime error.");
exit(1);
}

// 2.WorkerIdBitLength
if (flake->WorkerIdBitLength <= 0)
{
perror("WorkerIdBitLength error.(range:[1, 21])");
exit(1);
}
if (flake->SeqBitLength + flake->WorkerIdBitLength > 22)
{
perror("error:WorkerIdBitLength + SeqBitLength <= 22");
exit(1);
}
else
{
flake->WorkerIdBitLength = flake->WorkerIdBitLength <= 0 ? 6 : flake->WorkerIdBitLength;
}
// 2.WorkerIdBitLength
if (flake->WorkerIdBitLength <= 0)
{
perror("WorkerIdBitLength error.(range:[1, 21])");
exit(1);
}
if (flake->SeqBitLength + flake->WorkerIdBitLength > 22)
{
perror("error:WorkerIdBitLength + SeqBitLength <= 22");
exit(1);
}
else
{
flake->WorkerIdBitLength = flake->WorkerIdBitLength <= 0 ? 6 : flake->WorkerIdBitLength;
}

// 3.WorkerId
uint32_t maxWorkerIdNumber = (1 << flake->WorkerIdBitLength) - 1;
if (maxWorkerIdNumber == 0)
{
maxWorkerIdNumber = 63;
}
if (flake->WorkerId < 0 || flake->WorkerId > maxWorkerIdNumber)
{
perror("WorkerId error. (range:[0, {2^WorkerIdBitLength-1]}");
exit(1);
}
// 3.WorkerId
uint32_t maxWorkerIdNumber = (1 << flake->WorkerIdBitLength) - 1;
if (maxWorkerIdNumber == 0)
{
maxWorkerIdNumber = 63;
}
if (flake->WorkerId < 0 || flake->WorkerId > maxWorkerIdNumber)
{
perror("WorkerId error. (range:[0, {2^WorkerIdBitLength-1]}");
exit(1);
}

// 4.SeqBitLength
if (flake->SeqBitLength < 2 || flake->SeqBitLength > 21)
{
perror("SeqBitLength error. (range:[2, 21])");
exit(1);
}
else
{
flake->SeqBitLength = flake->SeqBitLength <= 0 ? 6 : flake->SeqBitLength;
}
// 4.SeqBitLength
if (flake->SeqBitLength < 2 || flake->SeqBitLength > 21)
{
perror("SeqBitLength error. (range:[2, 21])");
exit(1);
}
else
{
flake->SeqBitLength = flake->SeqBitLength <= 0 ? 6 : flake->SeqBitLength;
}

// 5.MaxSeqNumber
uint32_t maxSeqNumber = (1 << flake->SeqBitLength) - 1;
if (maxSeqNumber == 0)
{
maxSeqNumber = 63;
}
if (flake->MaxSeqNumber > maxSeqNumber)
{
perror("MaxSeqNumber error. (range:[1, {2^SeqBitLength-1}]");
exit(1);
}
else
{
flake->MaxSeqNumber = flake->MaxSeqNumber <= 0 ? maxSeqNumber : flake->MaxSeqNumber;
}
// 5.MaxSeqNumber
uint32_t maxSeqNumber = (1 << flake->SeqBitLength) - 1;
if (maxSeqNumber == 0)
{
maxSeqNumber = 63;
}
if (flake->MaxSeqNumber > maxSeqNumber)
{
perror("MaxSeqNumber error. (range:[1, {2^SeqBitLength-1}]");
exit(1);
}
else
{
flake->MaxSeqNumber = flake->MaxSeqNumber <= 0 ? maxSeqNumber : flake->MaxSeqNumber;
}

// 6.MinSeqNumber
if (flake->MinSeqNumber < 5 || flake->MinSeqNumber > maxSeqNumber)
{
perror("MinSeqNumber error. (range:[5, {MinSeqNumber}]");
exit(1);
}
else
{
flake->MinSeqNumber = flake->MinSeqNumber <= 0 ? 5 : flake->MinSeqNumber;
}
// 6.MinSeqNumber
if (flake->MinSeqNumber < 5 || flake->MinSeqNumber > maxSeqNumber)
{
perror("MinSeqNumber error. (range:[5, {MinSeqNumber}]");
exit(1);
}
else
{
flake->MinSeqNumber = flake->MinSeqNumber <= 0 ? 5 : flake->MinSeqNumber;
}

// 7.Others
flake->TopOverCostCount = flake->TopOverCostCount <= 0 ? 2000 : flake->TopOverCostCount;
flake->_TimestampShift = flake->WorkerIdBitLength + flake->SeqBitLength;
flake->_CurrentSeqNumber = flake->MinSeqNumber;
flake->Method = flake->Method;
// 7.Others
flake->TopOverCostCount = flake->TopOverCostCount <= 0 ? 2000 : flake->TopOverCostCount;
flake->_TimestampShift = flake->WorkerIdBitLength + flake->SeqBitLength;
flake->_CurrentSeqNumber = flake->MinSeqNumber;
flake->Method = flake->Method;
}

// static inline void EndOverCostAction(uint64_t useTimeTick, snowflake *flake)
@@ -132,158 +135,178 @@ void Config(snowflake *flake)

static inline uint64_t NextOverCostId(snowflake *flake)
{
uint64_t currentTimeTick = GetCurrentTimeTick(flake);
if (currentTimeTick > flake->_LastTimeTick)
{
// EndOverCostAction(currentTimeTick, flake);
flake->_LastTimeTick = currentTimeTick;
flake->_CurrentSeqNumber = flake->MinSeqNumber;
flake->_IsOverCost = 0;
flake->_OverCostCountInOneTerm = 0;
// flake->_GenCountInOneTerm = 0;
return CalcId(flake);
}
if (flake->_OverCostCountInOneTerm > flake->TopOverCostCount)
{
// EndOverCostAction(currentTimeTick, flake);
flake->_LastTimeTick = GetNextTimeTick(flake);
flake->_CurrentSeqNumber = flake->MinSeqNumber;
flake->_IsOverCost = 0;
flake->_OverCostCountInOneTerm = 0;
// flake->_GenCountInOneTerm = 0;
return CalcId(flake);
}
if (flake->_CurrentSeqNumber > flake->MaxSeqNumber)
{
flake->_LastTimeTick++;
flake->_CurrentSeqNumber = flake->MinSeqNumber;
flake->_IsOverCost = 1;
flake->_OverCostCountInOneTerm++;
// flake->_GenCountInOneTerm++;
return CalcId(flake);
}
uint64_t currentTimeTick = GetCurrentTimeTick(flake);
if (currentTimeTick > flake->_LastTimeTick)
{
// EndOverCostAction(currentTimeTick, flake);
flake->_LastTimeTick = currentTimeTick;
flake->_CurrentSeqNumber = flake->MinSeqNumber;
flake->_IsOverCost = 0;
flake->_OverCostCountInOneTerm = 0;
// flake->_GenCountInOneTerm = 0;
return CalcId(flake);
}
if (flake->_OverCostCountInOneTerm > flake->TopOverCostCount)
{
// EndOverCostAction(currentTimeTick, flake);
flake->_LastTimeTick = GetNextTimeTick(flake);
flake->_CurrentSeqNumber = flake->MinSeqNumber;
flake->_IsOverCost = 0;
flake->_OverCostCountInOneTerm = 0;
// flake->_GenCountInOneTerm = 0;
return CalcId(flake);
}
if (flake->_CurrentSeqNumber > flake->MaxSeqNumber)
{
flake->_LastTimeTick++;
flake->_CurrentSeqNumber = flake->MinSeqNumber;
flake->_IsOverCost = 1;
flake->_OverCostCountInOneTerm++;
// flake->_GenCountInOneTerm++;
return CalcId(flake);
}

// flake->_GenCountInOneTerm++;
return CalcId(flake);
// flake->_GenCountInOneTerm++;
return CalcId(flake);
}

static inline uint64_t NextNormalId(snowflake *flake)
{
uint64_t currentTimeTick = GetCurrentTimeTick(flake);
if (currentTimeTick < flake->_LastTimeTick)
{
if (flake->_TurnBackTimeTick < 1)
{
flake->_TurnBackTimeTick = flake->_LastTimeTick - 1;
flake->_TurnBackIndex++;
if (flake->_TurnBackIndex > 4)
{
flake->_TurnBackIndex = 1;
}
}
return CalcTurnBackId(flake);
}
if (flake->_TurnBackTimeTick > 0)
{
flake->_TurnBackTimeTick = 0;
}
if (currentTimeTick > flake->_LastTimeTick)
{
flake->_LastTimeTick = currentTimeTick;
flake->_CurrentSeqNumber = flake->MinSeqNumber;
return CalcId(flake);
}
if (flake->_CurrentSeqNumber > flake->MaxSeqNumber)
{
// flake->_TermIndex++;
flake->_LastTimeTick++;
flake->_CurrentSeqNumber = flake->MinSeqNumber;
flake->_IsOverCost = 1;
flake->_OverCostCountInOneTerm = 1;
// flake->_GenCountInOneTerm = 1;
return CalcId(flake);
}
return CalcId(flake);
uint64_t currentTimeTick = GetCurrentTimeTick(flake);
if (currentTimeTick < flake->_LastTimeTick)
{
if (flake->_TurnBackTimeTick < 1)
{
flake->_TurnBackTimeTick = flake->_LastTimeTick - 1;
flake->_TurnBackIndex++;
if (flake->_TurnBackIndex > 4)
{
flake->_TurnBackIndex = 1;
}
}
return CalcTurnBackId(flake);
}
if (flake->_TurnBackTimeTick > 0)
{
flake->_TurnBackTimeTick = 0;
}
if (currentTimeTick > flake->_LastTimeTick)
{
flake->_LastTimeTick = currentTimeTick;
flake->_CurrentSeqNumber = flake->MinSeqNumber;
return CalcId(flake);
}
if (flake->_CurrentSeqNumber > flake->MaxSeqNumber)
{
// flake->_TermIndex++;
flake->_LastTimeTick++;
flake->_CurrentSeqNumber = flake->MinSeqNumber;
flake->_IsOverCost = 1;
flake->_OverCostCountInOneTerm = 1;
// flake->_GenCountInOneTerm = 1;
return CalcId(flake);
}
return CalcId(flake);
}

static inline uint64_t GetCurrentTime()
static inline uint64_t GetSysCurrentTime()
{
struct timeval t;
gettimeofday(&t, NULL);
return (uint64_t)(t.tv_sec * 1000 + t.tv_usec / 1000);
#ifdef WIN32
FILETIME file_time;
GetSystemTimeAsFileTime(&file_time);
uint64_t time = ((uint64_t)file_time.dwLowDateTime) + ((uint64_t)file_time.dwHighDateTime << 32);
static const uint64_t EPOCH = ((uint64_t)116444736000000000ULL);
return (uint64_t)((time - EPOCH) / 10000LL);
#else
struct timeval t;
gettimeofday(&t, NULL);
return (uint64_t)(t.tv_sec * 1000 + t.tv_usec / 1000);
#endif
}

static inline uint64_t GetCurrentTimeTick(snowflake *flake)
{
return GetCurrentTime() - flake->BaseTime;
return GetSysCurrentTime() - flake->BaseTime;
}

static inline uint64_t GetNextTimeTick(snowflake *flake)
{
uint64_t tempTimeTicker = GetCurrentTimeTick(flake);
while (tempTimeTicker <= flake->_LastTimeTick)
{
tempTimeTicker = GetCurrentTimeTick(flake);
}
return tempTimeTicker;
uint64_t tempTimeTicker = GetCurrentTimeTick(flake);
struct timespec delay;
delay.tv_sec = 0;
delay.tv_nsec = 500000;
while (1)
{
tempTimeTicker = GetCurrentTimeTick(flake);
if (tempTimeTicker > flake->_LastTimeTick)
{
break;
}
#ifdef WIN32
SwitchToThread();
#else
nanosleep(&delay, NULL);
#endif
}
return tempTimeTicker;
}

static inline uint64_t CalcId(snowflake *flake)
{
uint64_t result = (flake->_LastTimeTick << flake->_TimestampShift) + (flake->WorkerId << flake->SeqBitLength) + (flake->_CurrentSeqNumber);
flake->_CurrentSeqNumber++;
return result;
uint64_t result = (flake->_LastTimeTick << flake->_TimestampShift) + (flake->WorkerId << flake->SeqBitLength) + (flake->_CurrentSeqNumber);
flake->_CurrentSeqNumber++;
return result;
}

static inline uint64_t CalcTurnBackId(snowflake *flake)
{
uint64_t result = (flake->_LastTimeTick << flake->_TimestampShift) + (flake->WorkerId << flake->SeqBitLength) + (flake->_TurnBackTimeTick);
flake->_TurnBackTimeTick--;
return result;
uint64_t result = (flake->_LastTimeTick << flake->_TimestampShift) + (flake->WorkerId << flake->SeqBitLength) + (flake->_TurnBackTimeTick);
flake->_TurnBackTimeTick--;
return result;
}

static inline uint64_t NextSonwId(snowflake *flake)
{
uint64_t currentTimeTick = GetCurrentTimeTick(flake);
if (flake->_LastTimeTick == currentTimeTick)
{
flake->_CurrentSeqNumber++;
if (flake->_CurrentSeqNumber > flake->MaxSeqNumber)
{
flake->_CurrentSeqNumber = flake->MinSeqNumber;
currentTimeTick = GetNextTimeTick(flake);
}
}
else
{
flake->_CurrentSeqNumber = flake->MinSeqNumber;
}
flake->_LastTimeTick = currentTimeTick;
return (uint64_t)((currentTimeTick << flake->_TimestampShift) | (flake->WorkerId << flake->SeqBitLength) | flake->_CurrentSeqNumber);
uint64_t currentTimeTick = GetCurrentTimeTick(flake);
if (flake->_LastTimeTick == currentTimeTick)
{
flake->_CurrentSeqNumber++;
if (flake->_CurrentSeqNumber > flake->MaxSeqNumber)
{
flake->_CurrentSeqNumber = flake->MinSeqNumber;
currentTimeTick = GetNextTimeTick(flake);
}
}
else
{
flake->_CurrentSeqNumber = flake->MinSeqNumber;
}
flake->_LastTimeTick = currentTimeTick;
return (uint64_t)((currentTimeTick << flake->_TimestampShift) | (flake->WorkerId << flake->SeqBitLength) | flake->_CurrentSeqNumber);
}

static inline uint64_t GetId(snowflake *flake)
{
return flake->Method == 1 ? (flake->_IsOverCost != 0 ? NextOverCostId(flake) : NextNormalId(flake)) : NextSonwId(flake);
return flake->Method == 1 ? (flake->_IsOverCost != 0 ? NextOverCostId(flake) : NextNormalId(flake)) : NextSonwId(flake);
}

uint64_t NextId(snowflake *flake)
{
spin_lock(&flake->_Lock, pid);
uint64_t id = GetId(flake);
spin_unlock(&flake->_Lock, pid);
return id;
spin_lock(&flake->_Lock, pid);
uint64_t id = GetId(flake);
spin_unlock(&flake->_Lock, pid);
return id;
}

uint64_t *NextNumId(snowflake *flake, uint32_t num)
{
uint64_t *arr = (uint64_t *)malloc(sizeof(uint64_t) * num);
spin_lock(&flake->_Lock, pid);
uint32_t i;
for (i = 0; i < num; i++)
{
arr[i] = GetId(flake);
}
spin_unlock(&flake->_Lock, pid);
return arr;
uint64_t *arr = (uint64_t *)malloc(sizeof(uint64_t) * num);
spin_lock(&flake->_Lock, pid);
uint32_t i;
for (i = 0; i < num; i++)
{
arr[i] = GetId(flake);
}
spin_unlock(&flake->_Lock, pid);
return arr;
}

+ 61
- 35
PHP/src/snowflake/spinlock.c View File

@@ -1,47 +1,73 @@
#include <stdlib.h>
#ifdef WIN32
#include "windows.h"
#else
#include <sched.h>
#endif

#include "spinlock.h"

extern int ncpu;
extern int spin;

void spin_lock(atomic_t *lock, uint32_t pid)
void spin_lock(atomic_t* lock, uint32_t pid)
{
int i, n;

for (;;)
{

if (*lock == 0 &&
__sync_bool_compare_and_swap(lock, 0, pid))
{
return;
}

if (ncpu > 1)
{

for (n = 1; n < spin; n <<= 1)
{

for (i = 0; i < n; i++)
{
__asm("pause");
}

if (*lock == 0 &&
__sync_bool_compare_and_swap(lock, 0, pid))
{
return;
}
}
}

sched_yield();
}
int i, n;

for (;;)
{

if (*lock == 0 &&
#ifdef WIN32
InterlockedCompareExchange(lock, pid, 0) == 0
#else
__sync_bool_compare_and_swap(lock, 0, pid)
#endif
)
{
return;
}

if (ncpu > 1)
{

for (n = 1; n < spin; n <<= 1)
{

for (i = 0; i < n; i++)
{
#ifdef WIN32
MemoryBarrier();
#else
__asm("pause");
#endif
}

if (*lock == 0 &&
#ifdef WIN32
InterlockedCompareExchange(lock, pid, 0) == 0
#else
__sync_bool_compare_and_swap(lock, 0, pid)
#endif
)
{
return;
}
}
}
#ifdef WIN32
SwitchToThread();
#else
sched_yield();
#endif
}
}

void spin_unlock(atomic_t *lock, uint32_t pid)
void spin_unlock(atomic_t* lock, uint32_t pid)
{
__sync_bool_compare_and_swap(lock, pid, 0);
#ifdef WIN32
InterlockedCompareExchange(lock, 0, pid);
#else
__sync_bool_compare_and_swap(lock, pid, 0);
#endif
}

+ 12
- 0
Python/README.md View File

@@ -0,0 +1,12 @@
# ❄ idgenerator-Python(未完成)
## 运行环境
Python 3.6+
## 引用 包
## 调用示例

+ 31
- 0
Python/source/DefaultIdGenerator.py View File

@@ -0,0 +1,31 @@
import time
import traceback
from IdGeneratorOptions import IdGeneratorOptions
from SnowFlake import SnowFlake
from SnowFlakeM1 import SnowFlakeM1

class DefaultIdGenerator(object):
def SetIdGernerator(self, options) :
if options.BaseTime < 100000 :
raise ValueError ("BaseTime error.")
self.SnowFlake= SnowFlakeM1(options)

def NextId(self):
return self.SnowFlake.NextId()

if __name__ == '__main__':
try:
options = IdGeneratorOptions(23)
options.BaseTime = 1231111111
idgen = DefaultIdGenerator()
idgen.SetIdGernerator(options)
print (idgen.NextId())
print (options.__dict__)
except ValueError as e:
print(e)



+ 30
- 0
Python/source/IdGeneratorOptions.py View File

@@ -0,0 +1,30 @@
import time

class IdGeneratorOptions(object):
def __init__(self, workerId = 0, workerIdBitLength = 6, seqBitLength = 6):
# 雪花计算方法,(1-漂移算法|2-传统算法),默认1。目前只实现了1。
self.Method = 1
# 基础时间(ms单位),不能超过当前系统时间
self.BaseTime = 1288834974657
# 机器码,必须由外部设定,最大值 2^WorkerIdBitLength-1
self.WorkerId = workerId
# 机器码位长,默认值6,取值范围 [1, 15](要求:序列数位长+机器码位长不超过22)
self.WorkerIdBitLength = workerIdBitLength
# 序列数位长,默认值6,取值范围 [3, 21](要求:序列数位长+机器码位长不超过22)
self.SeqBitLength = seqBitLength
# 最大序列数(含),设置范围 [MinSeqNumber, 2^SeqBitLength-1],默认值0,表示最大序列数取最大值(2^SeqBitLength-1])
self.MaxSeqNumber = 0
# 最小序列数(含),默认值5,取值范围 [5, MaxSeqNumber],每毫秒的前5个序列数对应编号0-4是保留位,其中1-4是时间回拨相应预留位,0是手工新值预留位
self.MinSeqNumber = 5
# 最大漂移次数(含),默认2000,推荐范围500-10000(与计算能力有关)
self.TopOverCostCount = 2000



+ 11
- 0
Python/source/SnowFlake.py View File

@@ -0,0 +1,11 @@
#!/usr/bin/python
# coding=UTF-8

# 组件编号生成器
class SnowFlake(object):
def __init__(self, options):
self.Options = options
def NextId(self):
return 0

+ 12
- 0
Python/source/SnowFlakeM1.py View File

@@ -0,0 +1,12 @@
#!/usr/bin/python
# coding=UTF-8
from SnowFlake import SnowFlake

# 组件编号生成器
class SnowFlakeM1(SnowFlake):
def __init__(self, options):
self.Options = options
def NextId(self):
return self.Options.WorkerId

+ 1
- 3
README.md View File

@@ -222,9 +222,7 @@ QQ群:646049993
#### 动态库下载
下载链接1:https://github.com/yitter/IdGenerator/releases/download/reg_v1.0/regworkerid_lib_v1.0.zip
下载链接2:https://gitee.com/yitter/idgenerator/attach_files/662372/download/regworkerid_lib_v1.0.zip
下载链接1:https://github.com/yitter/IdGenerator/releases/download/v1.3.1/regworkerid_lib_v1.3.1.zip
#### 动态库接口定义
```


+ 2
- 1
Rust/source/.gitignore View File

@@ -27,6 +27,7 @@ bld/
**/.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
.vscode

# MSTest test Results
[Tt]est[Rr]esult*/
@@ -254,4 +255,4 @@ paket-files/
target/

# macOS
.DS_Store
.DS_Store,

+ 44
- 19
Rust/source/src/idgen/snow_worker_m1.rs View File

@@ -2,10 +2,10 @@
* 版权属于:yitter(yitter@126.com)
* 开源地址:https://github.com/yitter/idgenerator
*/
use std::{thread};
use crate::idgen::*;
use chrono::Utc;
use std::thread;
use std::thread::sleep;
use crate::idgen::*;
// use lazy_static::lazy_static;
pub struct SnowWorkerM1 {
@@ -42,26 +42,30 @@ impl SnowWorkerM1 {
}
pub fn SetOptions(&mut self, options: IdGeneratorOptions) {
// 1.BaseTime
if options.BaseTime == 0 {
self.BaseTime = 1582136402000;
} else if options.BaseTime < 631123200000 || options.BaseTime > Utc::now().timestamp_millis() {
} else if options.BaseTime < 631123200000
|| options.BaseTime > Utc::now().timestamp_millis()
{
panic!("BaseTime error.");
} else {
self.BaseTime = options.BaseTime;
}
// 2.WorkerIdBitLength
if options.WorkerIdBitLength <= 0
{
if options.WorkerIdBitLength <= 0 {
panic!("WorkerIdBitLength error.(range:[1, 21])");
}
if options.SeqBitLength + options.WorkerIdBitLength > 22 {
panic!("error:WorkerIdBitLength + SeqBitLength <= 22");
} else {
// self.WorkerIdBitLength = options.WorkerIdBitLength;
self.WorkerIdBitLength = if options.WorkerIdBitLength <= 0 { 6 } else { options.WorkerIdBitLength };
self.WorkerIdBitLength = if options.WorkerIdBitLength <= 0 {
6
} else {
options.WorkerIdBitLength
};
}
// 3.WorkerId
@@ -80,7 +84,11 @@ impl SnowWorkerM1 {
panic!("SeqBitLength error. (range:[2, 21])");
} else {
// self.SeqBitLength = options.SeqBitLength;
self.SeqBitLength = if options.SeqBitLength <= 0 { 6 } else { options.SeqBitLength };
self.SeqBitLength = if options.SeqBitLength <= 0 {
6
} else {
options.SeqBitLength
};
}
// 5.MaxSeqNumber
@@ -91,7 +99,11 @@ impl SnowWorkerM1 {
if options.MaxSeqNumber < 0 || options.MaxSeqNumber > maxSeqNumber {
panic!("MaxSeqNumber error. (range:[1, {}]", maxSeqNumber);
} else {
self.MaxSeqNumber = if options.MaxSeqNumber == 0 { maxSeqNumber } else { options.MaxSeqNumber };
self.MaxSeqNumber = if options.MaxSeqNumber == 0 {
maxSeqNumber
} else {
options.MaxSeqNumber
};
}
// 6.MinSeqNumber
@@ -102,8 +114,15 @@ impl SnowWorkerM1 {
// self.MinSeqNumber = if options.MinSeqNumber <= 0 { 5 } else { options.MinSeqNumber };
}
// 7.Others
self.TopOverCostCount = if options.TopOverCostCount == 0 { 2000 } else { options.TopOverCostCount };
// 7.TopOverCostCount
//self.TopOverCostCount = if options.TopOverCostCount == 0 { 2000 } else { options.TopOverCostCount };
if options.TopOverCostCount < 0 || options.TopOverCostCount > 10000 {
panic!("TopOverCostCount error. (range:[0, 10000]");
} else {
self.TopOverCostCount = options.TopOverCostCount;
}
// 8.Others
self._TimestampShift = self.WorkerIdBitLength + self.SeqBitLength;
self._CurrentSeqNumber = self.MinSeqNumber;
@@ -139,7 +158,11 @@ impl SnowWorkerM1 {
pub fn NextId(&mut self) -> i64 {
// println!("SeqBitLength: {}", self.SeqBitLength);
if self._IsOverCost { self.NextOverCostId() } else { self.NextNormalId() }
if self._IsOverCost {
self.NextOverCostId()
} else {
self.NextNormalId()
}
}
fn DoGenIdAction(&self, arg: OverCostActionArg) {}
@@ -247,17 +270,17 @@ impl SnowWorkerM1 {
}
fn CalcId(&mut self, useTimeTick: i64) -> i64 {
let result = (useTimeTick << self._TimestampShift) +
(self.WorkerId << self.SeqBitLength) as i64 +
(self._CurrentSeqNumber) as i64;
let result = (useTimeTick << self._TimestampShift)
+ (self.WorkerId << self.SeqBitLength) as i64
+ (self._CurrentSeqNumber) as i64;
self._CurrentSeqNumber += 1;
return result;
}
fn CalcTurnBackId(&mut self, useTimeTick: i64) -> i64 {
let result = (useTimeTick << self._TimestampShift) +
(self.WorkerId << self.SeqBitLength) as i64 +
(self._TurnBackIndex) as i64;
let result = (useTimeTick << self._TimestampShift)
+ (self.WorkerId << self.SeqBitLength) as i64
+ (self._TurnBackIndex) as i64;
self._TurnBackTimeTick -= 1;
return result;
}
@@ -270,9 +293,11 @@ impl SnowWorkerM1 {
let mut tempTimeTicker = self.GetCurrentTimeTick();
while tempTimeTicker <= self._LastTimeTick {
// 暂停1ms
sleep(std::time::Duration::from_millis(1));
tempTimeTicker = self.GetCurrentTimeTick();
}
return tempTimeTicker;
}
}
}

+ 24
- 22
Rust/source/src/main.rs View File

@@ -1,16 +1,15 @@
mod idgen;

use chrono::Utc;
use idgen::*;
use std::thread;
use chrono::Utc;
use std::time::Duration;


fn main() {
println!("Hello, world! Rust");

// 总执行次数
let times = 50000;
let times = 500000;

// 是否启用多线程测试
let multiThread = false;
@@ -18,7 +17,7 @@ fn main() {
// 全局设置一次运行参数
let mut options = IdGeneratorOptions::New(1);
options.WorkerIdBitLength = 6;
options.SeqBitLength = 6;
options.SeqBitLength = 10;
//... 可以继续设置其它 options 参数
YitIdHelper::SetIdGenerator(options);

@@ -32,24 +31,29 @@ fn main() {

while i < times {
i += 1;
if multiThread { // 这是多线程
thread::spawn(move || {
id = YitIdHelper::NextId();
println!("{}, id: {}", i, id);
});
} else { // 这是单线程
id = YitIdHelper::NextId();
}
}
YitIdHelper::NextId();

println!("最后生成的id: {}", id);
if !multiThread {
// 多线程情况下,时间统计不准确
let end = Utc::now().timestamp_millis();
println!("单线程用时 {} ms", end - start);
// if multiThread { // 这是多线程
// thread::spawn(move || {
// id = YitIdHelper::NextId();
// println!("{}, id: {}", i, id);
// });
// } else { // 这是单线程
// id = YitIdHelper::NextId();
// }
}

thread::sleep(std::time::Duration::from_millis(2000));
let end = Utc::now().timestamp_millis();
println!("单线程用时 {} ms", end - start);

// println!("最后生成的id: {}", id);
// if !multiThread {
// // 多线程情况下,时间统计不准确
// let end = Utc::now().timestamp_millis();
// println!("单线程用时 {} ms", end - start);
// }

thread::sleep(std::time::Duration::from_millis(1000));
}
}

@@ -71,6 +75,4 @@ fn set_redis() {
// },
// Err(error) => println!("Unable to create Redis client: {}", error)
// }

}

}

+ 1
- 6
Tools/AutoRegisterWorkerId/lib/yitidgengo.h View File

@@ -68,14 +68,9 @@ typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
extern "C" {
#endif

extern __declspec(dllexport) void SetOptions(GoUint16 workerId);
extern __declspec(dllexport) GoUint64 NextId();

// 注册一个 WorkerId,会先注销所有本机已注册的记录
extern __declspec(dllexport) GoInt32 RegisterOne(char* ip, GoInt32 port, char* password, GoInt32 maxWorkerId);

// 注册多个 WorkerId,会先注销所有本机已注册的记录
extern __declspec(dllexport) int* RegisterMany(char* ip, GoInt32 port, char* password, GoInt32 maxWorkerId, GoInt32 totalCount);
extern __declspec(dllexport) GoInt32 RegisterOne(char* ip, GoInt32 port, char* password, GoInt32 maxWorkerId, GoInt database);

// 注销本机已注册的 WorkerId
extern __declspec(dllexport) void UnRegister();


Loading…
Cancel
Save