初始化项目

This commit is contained in:
皮蛋13361098506
2025-01-06 16:01:02 +08:00
commit 1b77f62820
575 changed files with 69193 additions and 0 deletions

View File

@@ -0,0 +1,136 @@
package idUtil
import (
"testing"
)
func TestNewTimeIdentifierSeedGenerator(t *testing.T) {
generator, err := NewTimeIdentifierSeedGenerator(40, 1, 7, 20)
if err == nil {
t.Errorf("there should be err, but now not.")
}
generator, err = NewTimeIdentifierSeedGenerator(10, int64(1), 7, 20)
if err != nil {
t.Errorf("there should be no err, but now there is.")
}
_, err = generator.GenerateNewId()
if err == nil {
t.Errorf("there should be err, but now not.")
}
generator, err = NewTimeIdentifierSeedGenerator(40, int64(127), 3, 20)
if err == nil {
t.Errorf("there should be err, but now not.")
}
count := 1048575
idMap := make(map[int64]struct{}, count)
for identifier := 0; identifier < 8; identifier++ {
generator, err = NewTimeIdentifierSeedGenerator(40, int64(identifier), 3, 20)
if err != nil {
t.Errorf("There should be no error, but now there is:%s", err)
return
}
for i := 0; i < count; i++ {
id, err := generator.GenerateNewId()
if err != nil {
t.Errorf("There should be no error, but now there is:%s", err)
return
}
if _, exist := idMap[id]; exist {
t.Errorf("Id:%d is duplicated.", id)
return
}
idMap[id] = struct{}{}
}
}
}
func TestNewIdentifierTimeSeedGenerator(t *testing.T) {
generator, err := NewIdentifierTimeSeedGenerator(int64(1), 7, 40, 20)
if err == nil {
t.Errorf("there should be err, but now not.")
}
generator, err = NewIdentifierTimeSeedGenerator(int64(1), 7, 10, 20)
if err != nil {
t.Errorf("there should be no err, but now there is.")
}
_, err = generator.GenerateNewId()
if err == nil {
t.Errorf("there should be err, but now not.")
}
generator, err = NewIdentifierTimeSeedGenerator(int64(127), 3, 40, 20)
if err == nil {
t.Errorf("there should be err, but now not.")
}
count := 1048575
idMap := make(map[int64]struct{}, count)
for identifier := 0; identifier < 8; identifier++ {
generator, err = NewIdentifierTimeSeedGenerator(int64(identifier), 3, 40, 20)
if err != nil {
t.Errorf("There should be no error, but now there is:%s", err)
return
}
for i := 0; i < count; i++ {
id, err := generator.GenerateNewId()
if err != nil {
t.Errorf("There should be no error, but now there is:%s", err)
return
}
if _, exist := idMap[id]; exist {
t.Errorf("Id:%d is duplicated.", id)
return
}
idMap[id] = struct{}{}
}
}
}
func TestNewIdentifierConstructCountSeedGenerator(t *testing.T) {
generator, err := NewIdentifierConstructCountSeedGenerator(int64(1), 27, int64(1), 20, 23)
if err == nil {
t.Errorf("there should be err, but now not.")
}
generator, err = NewIdentifierConstructCountSeedGenerator(int64(32768), 15, int64(1), 18, 30)
if err == nil {
t.Errorf("there should be err, but now not.")
}
count := 1048575
idMap := make(map[int64]struct{}, count)
for identifier := 0; identifier < 8; identifier++ {
for constructCount := 0; constructCount < 5; constructCount++ {
generator, err = NewIdentifierConstructCountSeedGenerator(int64(identifier), 15, int64(constructCount), 18, 30)
if err != nil {
t.Errorf("There should be no error, but now there is:%s", err)
return
}
for i := 0; i < count; i++ {
id, err := generator.GenerateNewId()
if err != nil {
t.Errorf("There should be no error, but now there is:%s", err)
return
}
if _, exist := idMap[id]; exist {
t.Errorf("Id:%d is duplicated.", id)
return
}
idMap[id] = struct{}{}
}
}
}
}

View File

@@ -0,0 +1,108 @@
/*
用于生成唯一的、递增的Id。生成的规则如下
1、生成的Id包含一个固定前缀值
2、为了生成尽可能多的不重复数字所以使用int64来表示一个数字其中
0 000000000000000 0000000000000000000000000000 00000000000000000000
第一部分1位固定为0
第二部分共IdentifierBit位表示固定唯一标识(机器号或者服务器Id等)。范围为[0, math.Pow(2, IdentifierBit))
第三部分共ConstructCountBit位表示对象被构造的次数。范围为[0, math.Pow(2, ConstructCountBit))以2020-1-1 00:00:00为基准
第四部分共SeedBit位表示自增种子。范围为[0, math.Pow(2, SeedBit))
3、总体而言此规则支持总共创建math.Pow(2, ConstructCountBit)次对象并且每次对象构造期间生成math.Pow(2, SeedBit)个不同的数字
*/
/*
修改记录:
2020-03-04 14:30:00 调整了时间和唯一标识在Id中的位置以便生成递增的Id
2020-04-20 21:10:00 同步了C版本的逻辑
*/
package idUtil
import (
"fmt"
"math"
"sync"
)
type IdentifierConstructCountSeedGenerator struct {
identifier int64 // 唯一标识
identifierBit int32 // 唯一标识(机器号或者服务器Id等)所占的位数
identifierBitOffset int32 // 唯一标识的偏移位数
constructCount int64 // 对象构造的次数
constructCountBit int32 // 对象构造的次数所占的位数
constructCountBitOffset int32 // 时间戳对象构造的次数的偏移位数的偏移位数
seed int64 // 当前种子值
seedBit int32 // 自增种子所占的位数
seedBitOffset int32 // 自增种子的偏移位数
maxSeed int64 // 最大的种子值
mutex sync.Mutex // 锁对象
}
func (this *IdentifierConstructCountSeedGenerator) getNewSeed() (int64, error) {
this.mutex.Lock()
defer this.mutex.Unlock()
if this.seed >= this.maxSeed {
return 0, fmt.Errorf("Seed's value is out of scope")
}
this.seed += 1
return this.seed, nil
}
// 生成新的Id
// 返回值:
// 新的Id
// 错误对象
func (this *IdentifierConstructCountSeedGenerator) GenerateNewId() (int64, error) {
seed, err := this.getNewSeed()
if err != nil {
return 0, err
}
id := (this.identifier << this.identifierBitOffset) | (this.constructCount << this.constructCountBitOffset) | (seed << this.seedBitOffset)
return id, nil
}
// 创建新的Id生成器对象为了保证Id的唯一需要保证生成的对象全局唯一
// identifierBit + constructCountBit + seedBit <= 63
// identifier:id唯一标识
// identifierBit:id唯一标识(机器号或者服务器Id等)的位数
// constructCount:对象构造次数
// constructCountBit:对象构造次数的位数
// seedBit:自增种子的位数
// 返回值:
// 新的Id生成器对象
// 错误对象
func NewIdentifierConstructCountSeedGenerator(identifier int64, identifierBit int32, constructCount int64, constructCountBit, seedBit int32) (*IdentifierConstructCountSeedGenerator, error) {
// 之所以使用63位而不是64是为了保证值为正数
if identifierBit+constructCountBit+seedBit > 63 {
return nil, fmt.Errorf("总位数%d超过63位请调整所有值的合理范围。", identifierBit+constructCountBit+seedBit)
}
if identifier < 0 || identifier > int64(math.Pow(2, float64(identifierBit)))-1 {
return nil, fmt.Errorf("唯一标识值溢出有效范围为【0,%d】", int64(math.Pow(2, float64(identifierBit)))-1)
}
if constructCount < 0 || constructCount > int64(math.Pow(2, float64(constructCountBit)))-1 {
return nil, fmt.Errorf("对象构造次数的值溢出有效范围为【0,%d】", int64(math.Pow(2, float64(constructCountBit)))-1)
}
obj := &IdentifierConstructCountSeedGenerator{
identifier: identifier,
identifierBit: identifierBit,
constructCount: constructCount,
constructCountBit: constructCountBit,
seed: 0,
seedBit: seedBit,
maxSeed: int64(math.Pow(2, float64(seedBit)) - 1),
}
obj.seedBitOffset = 0
obj.constructCountBitOffset = obj.seedBitOffset + obj.seedBit
obj.identifierBitOffset = obj.constructCountBitOffset + obj.constructCountBit
return obj, nil
}

View File

@@ -0,0 +1,121 @@
/*
用于生成唯一的、递增的Id。生成的规则如下
1、生成的Id包含一个固定前缀值
2、为了生成尽可能多的不重复数字所以使用int64来表示一个数字其中
0 000000000000000 0000000000000000000000000000 00000000000000000000
第一部分1位固定为0
第二部分共IdentifierBit位表示固定唯一标识(机器号或者服务器Id等)。范围为[0, math.Pow(2, IdentifierBit))
第三部分共TimeBit位表示当前时间距离基础时间的秒数。范围为[0, math.Pow(2, TimeBit))以2020-1-1 00:00:00为基准
第四部分共SeedBit位表示自增种子。范围为[0, math.Pow(2, SeedBit))
3、总体而言此规则支持每秒生成math.Pow(2, SeedBit)个不同的数字并且在math.Pow(2, TimeBit)/60/60/24/365年的时间范围内有效
*/
/*
修改记录:
2020-03-04 14:30:00 调整了时间和唯一标识在Id中的位置以便生成递增的Id
2020-04-20 21:10:00 同步了C版本的逻辑
*/
package idUtil
import (
"fmt"
"math"
"sync"
"time"
)
type IdentifierTimeSeedGenerator struct {
identifier int64 // 唯一标识
identifierBit int32 // 唯一标识(机器号或者服务器Id等)所占的位数
identifierBitOffset int32 // 唯一标识的偏移位数
timeBit int32 // 时间戳所占的位数
timeBitOffset int32 // 时间戳的偏移位数
startTimeStamp int64 // 起始时间戳
endTimeStamp int64 // 结束时间戳
seedBit int32 // 自增种子所占的位数
seedBitOffset int32 // 自增种子的偏移位数
minSeed int64 // 最小的种子值
maxSeed int64 // 最大的种子值
currSeed int64 // 当前种子值
mutex sync.Mutex // 锁对象
}
func (this *IdentifierTimeSeedGenerator) getTimeStamp() (int64, error) {
if time.Now().Unix() > this.endTimeStamp {
return 0, fmt.Errorf("Time's value is out of scope")
}
return time.Now().Unix() - this.startTimeStamp, nil
}
func (this *IdentifierTimeSeedGenerator) getNewSeed() int64 {
this.mutex.Lock()
defer this.mutex.Unlock()
if this.currSeed >= this.maxSeed {
this.currSeed = this.minSeed
} else {
this.currSeed = this.currSeed + 1
}
return this.currSeed
}
// 生成新的Id
// identifierId的唯一标识值。取值范围必须可以用创建对象时指定的唯一标识值的位数来表示否则会返回参数超出范围的错误
// 返回值:
// 新的Id
// 错误对象
func (this *IdentifierTimeSeedGenerator) GenerateNewId() (int64, error) {
timestamp, err := this.getTimeStamp()
if err != nil {
return 0, err
}
seed := this.getNewSeed()
id := (this.identifier << this.identifierBitOffset) | (timestamp << this.timeBitOffset) | (seed << this.seedBitOffset)
return id, nil
}
// 创建新的Id生成器对象为了保证Id的唯一需要保证生成的对象全局唯一
// identifierBit + timeBit + seedBit <= 63
// identifier:id唯一标识
// identifierBit:id唯一标识(机器号或者服务器Id等)的位数
// timeBit:时间的位数
// seedBit:自增种子的位数
// 返回值:
// 新的Id生成器对象
// 错误对象
func NewIdentifierTimeSeedGenerator(identifier int64, identifierBit, timeBit, seedBit int32) (*IdentifierTimeSeedGenerator, error) {
// 之所以使用63位而不是64是为了保证值为正数
if identifierBit+timeBit+seedBit > 63 {
return nil, fmt.Errorf("总位数%d超过63位请调整所有值的合理范围。", identifierBit+timeBit+seedBit)
}
if identifier < 0 || identifier > int64(math.Pow(2, float64(identifierBit)))-1 {
return nil, fmt.Errorf("唯一标识值溢出有效范围为【0,%d】", int64(math.Pow(2, float64(identifierBit)))-1)
}
startTimeStamp := time.Date(2019, time.January, 1, 0, 0, 0, 0, time.Local).Unix()
obj := &IdentifierTimeSeedGenerator{
identifier: identifier,
identifierBit: identifierBit,
timeBit: timeBit,
startTimeStamp: startTimeStamp,
endTimeStamp: startTimeStamp + int64(math.Pow(2, float64(timeBit))) - 1,
seedBit: seedBit,
minSeed: 0,
maxSeed: int64(math.Pow(2, float64(seedBit))) - 1,
currSeed: 0,
}
obj.seedBitOffset = 0
obj.timeBitOffset = obj.seedBitOffset + obj.seedBit
obj.identifierBitOffset = obj.timeBitOffset + obj.timeBit
return obj, nil
}

View File

@@ -0,0 +1,121 @@
/*
用于生成唯一的、递增的Id。生成的规则如下
1、生成的Id包含一个固定前缀值
2、为了生成尽可能多的不重复数字所以使用int64来表示一个数字其中
0 000000000000000 0000000000000000000000000000 00000000000000000000
第一部分1位固定为0
第二部分共TimeBit位表示当前时间距离基础时间的秒数。范围为[0, math.Pow(2, TimeBit))以2020-1-1 00:00:00为基准
第三部分共IdentifierBit位表示固定唯一标识(机器号或者服务器Id等)。范围为[0, math.Pow(2, IdentifierBit))
第四部分共SeedBit位表示自增种子。范围为[0, math.Pow(2, SeedBit))
3、总体而言此规则支持每秒生成math.Pow(2, SeedBit)个不同的数字并且在math.Pow(2, TimeBit)/60/60/24/365年的时间范围内有效
*/
/*
修改记录:
2020-03-04 14:30:00 调整了时间和唯一标识在Id中的位置以便生成递增的Id
2020-04-20 21:10:00 同步了C版本的逻辑
*/
package idUtil
import (
"fmt"
"math"
"sync"
"time"
)
type TimeIdentifierSeedGenerator struct {
timeBit int32 // 时间戳所占的位数
timeBitOffset int32 // 时间戳的偏移位数
startTimeStamp int64 // 起始时间戳
endTimeStamp int64 // 结束时间戳
identifier int64 // 唯一标识
identifierBit int32 // 唯一标识(机器号或者服务器Id等)所占的位数
identifierBitOffset int32 // 唯一标识的偏移位数
seedBit int32 // 自增种子所占的位数
seedBitOffset int32 // 自增种子的偏移位数
minSeed int64 // 最小的种子值
maxSeed int64 // 最大的种子值
currSeed int64 // 当前种子值
mutex sync.Mutex // 锁对象
}
func (this *TimeIdentifierSeedGenerator) getTimeStamp() (int64, error) {
if time.Now().Unix() > this.endTimeStamp {
return 0, fmt.Errorf("Time's value is out of scope")
}
return time.Now().Unix() - this.startTimeStamp, nil
}
func (this *TimeIdentifierSeedGenerator) getNewSeed() int64 {
this.mutex.Lock()
defer this.mutex.Unlock()
if this.currSeed >= this.maxSeed {
this.currSeed = this.minSeed
} else {
this.currSeed = this.currSeed + 1
}
return this.currSeed
}
// 生成新的Id
// identifierId的唯一标识值。取值范围必须可以用创建对象时指定的唯一标识值的位数来表示否则会返回参数超出范围的错误
// 返回值:
// 新的Id
// 错误对象
func (this *TimeIdentifierSeedGenerator) GenerateNewId() (int64, error) {
timestamp, err := this.getTimeStamp()
if err != nil {
return 0, err
}
seed := this.getNewSeed()
id := (timestamp << this.timeBitOffset) | (this.identifier << this.identifierBitOffset) | (seed << this.seedBitOffset)
return id, nil
}
// 创建新的Id生成器对象为了保证Id的唯一需要保证生成的对象全局唯一
// timeBit + identifierBit + seedBit <= 63
// timeBit:时间的位数
// identifier:id唯一标识
// identifierBit:id唯一标识(机器号或者服务器Id等)的位数
// seedBit:自增种子的位数
// 返回值:
// 新的Id生成器对象
// 错误对象
func NewTimeIdentifierSeedGenerator(timeBit int32, identifier int64, identifierBit, seedBit int32) (*TimeIdentifierSeedGenerator, error) {
// 之所以使用63位而不是64是为了保证值为正数
if timeBit+identifierBit+seedBit > 63 {
return nil, fmt.Errorf("总位数%d超过63位请调整所有值的合理范围。", timeBit+identifierBit+seedBit)
}
if identifier < 0 || identifier > int64(math.Pow(2, float64(identifierBit)))-1 {
return nil, fmt.Errorf("唯一标识值溢出有效范围为【0,%d】", int64(math.Pow(2, float64(identifierBit)))-1)
}
startTimeStamp := time.Date(2019, time.January, 1, 0, 0, 0, 0, time.Local).Unix()
obj := &TimeIdentifierSeedGenerator{
timeBit: timeBit,
startTimeStamp: startTimeStamp,
endTimeStamp: startTimeStamp + int64(math.Pow(2, float64(timeBit))) - 1,
identifier: identifier,
identifierBit: identifierBit,
seedBit: seedBit,
minSeed: 0,
maxSeed: int64(math.Pow(2, float64(seedBit))) - 1,
currSeed: 0,
}
obj.seedBitOffset = 0
obj.identifierBitOffset = obj.seedBitOffset + obj.seedBit
obj.timeBitOffset = obj.identifierBitOffset + obj.identifierBit
return obj, nil
}