1
0
mirror of synced 2025-12-10 23:28:16 +08:00

!8 更新readme文件,优化vlang的lock

This commit is contained in:
微希夷
2021-04-12 20:25:56 +08:00
committed by yitter
parent 123508fe14
commit ddaa1d628a
11 changed files with 163 additions and 121 deletions

View File

@@ -25,9 +25,8 @@ make install
//snowdrift.ini //snowdrift.ini
snowdrift.Method=1 //1 漂移算法 2 传统算法 snowdrift.Method=1 //1 漂移算法 2 传统算法
snowdrift.BaseTime=1582136402000 snowdrift.BaseTime=1582136402000
snowdrift.WorkerId=1 //默认workerid snowdrift.WorkerId=1 //默认workerid支持参数传递改变实际使用的值范围1~(-1L << snowdrift.WorkerIdBitLength) ^ -1L
snowdrift.WorkerIdNum=1 //支持的WorkerId数,默认1不超过(-1L << snowdrift.WorkerIdBitLength) ^ -1L snowdrift.WorkerIdBitLength=6 //WorkerId数,默认6。
snowdrift.WorkerIdBitLength=6
snowdrift.SeqBitLength=6 //自增序号位数 snowdrift.SeqBitLength=6 //自增序号位数
snowdrift.MaxSeqNumber=0 snowdrift.MaxSeqNumber=0
snowdrift.MinSeqNumber=0 snowdrift.MinSeqNumber=0

View File

@@ -1,3 +1,40 @@
# ❄ idgenerator-V # ❄ idgenerator-V
## 介绍
项目更多介绍参照https://github.com/yitter/idgenerator
## 运行环境
```sh
$ v --enable-globals run test.v
```
## 调用示例V
第1步**全局** 初始化(应用程序启动时执行一次):
```v ignore
// 定义全局变量
__global ( idgen gen.YitIdHelper ) //定义全局变量
// 使用默认参数配置
idgen = gen.YitIdHelper{
id_gen: gen.make_generator(&contract.IdGeneratorOptions{})
}
// 更改配置参数
idgen.set_id_generator(&contract.IdGeneratorOptions{
method: 1
base_time: 1582136402000
workerid_bitlength: 6
seq_bitlength: 10
})
//以上配置全局一次
```
第2步生成ID
```v ignore
// 初始化以后即可在任何需要生成ID的地方调用以下方法
newId := idgen.next_id()
```

View File

@@ -2,4 +2,4 @@ module contract
pub interface IIdGenerator { pub interface IIdGenerator {
new_long() u64 new_long() u64
} }

View File

@@ -1,5 +1,5 @@
module contract module contract
pub interface ISnowWorker { pub interface ISnowWorker {
next_id() u64 next_id() u64
} }

View File

@@ -2,12 +2,12 @@ module contract
pub struct IdGeneratorOptions { pub struct IdGeneratorOptions {
pub mut: pub mut:
method u16 =1// 雪花计算方法,1-漂移算法|2-传统算法默认1 method u16 = 1 // 雪花计算方法,1-漂移算法|2-传统算法默认1
base_time i64// 基础时间不能超过当前系统时间 base_time i64 = 1582136402000 // 基础时间不能超过当前系统时间
worker_id u16 =1// 机器码 workerid_bitlength 有关系 worker_id u16 = 1 // 机器码 workerid_bitlength 有关系
workerid_bitlength byte=6// 机器码位长范围1-21要求序列数位长+机器码位长不超过22 workerid_bitlength byte = 6 // 机器码位长范围1-21要求序列数位长+机器码位长不超过22
seq_bitlength byte=6// 序列数位长范围2-21要求序列数位长+机器码位长不超过22 seq_bitlength byte = 6 // 序列数位长范围2-21要求序列数位长+机器码位长不超过22
max_seqnumber u32// 最大序列数由seq_bitlength计算的最大值 max_seqnumber u32 = 0 // 最大序列数由seq_bitlength计算的最大值
min_seqnumber u32// 最小序列数默认5不小于1不大于max_seqnumber min_seqnumber u32 = 0 // 最小序列数默认5不小于1不大于max_seqnumber
top_over_cost_count u32 =2000// 最大漂移次数默认2000推荐范围500-10000与计算能力有关 top_over_cost_count u32 = 2000 // 最大漂移次数默认2000推荐范围500-10000与计算能力有关
} }

View File

@@ -2,52 +2,50 @@ module core
import contract import contract
import time import time
import sync
pub struct SnowWorkerM1{ pub struct SnowWorkerM1 {
mut: mut:
method u16 // 雪花计算方法,1-漂移算法|2-传统算法默认1 method u16 // 雪花计算方法,1-漂移算法|2-传统算法默认1
base_time i64 // 基础时间不能超过当前系统时间 base_time i64 // 基础时间不能超过当前系统时间
worker_id u16 // 机器码 workerid_bitlength 有关系 worker_id u16 // 机器码 workerid_bitlength 有关系
workerid_bitlength byte// 机器码位长范围1-21要求序列数位长+机器码位长不超过22 workerid_bitlength byte // 机器码位长范围1-21要求序列数位长+机器码位长不超过22
seq_bitlength byte// 序列数位长范围2-21要求序列数位长+机器码位长不超过22 seq_bitlength byte // 序列数位长范围2-21要求序列数位长+机器码位长不超过22
max_seqnumber u32 // 最大序列数由seq_bitlength计算的最大值 max_seqnumber u32 // 最大序列数由seq_bitlength计算的最大值
min_seqnumber u32 // 最小序列数默认5不小于1不大于max_seqnumber min_seqnumber u32 // 最小序列数默认5不小于1不大于max_seqnumber
top_over_cost_count u32 // 最大漂移次数默认2000推荐范围500-10000与计算能力有关 top_over_cost_count u32 // 最大漂移次数默认2000推荐范围500-10000与计算能力有关
timestamp_shift byte timestamp_shift byte
current_seqnumber u32 current_seqnumber u32
last_time_tick i64 last_time_tick i64
turn_back_timetick i64 turn_back_timetick i64
turnback_index byte turnback_index byte
is_over_cost bool is_over_cost bool
overcostcount_inoneterm u32 overcostcount_inoneterm u32
gencount_inoneterm u32 gencount_inoneterm u32
term_index u32 term_index u32
mu sync.Mutex
} }
pub fn make_sf_m1(options &contract.IdGeneratorOptions) &contract.ISnowWorker{ pub fn make_sf_m1(options &contract.IdGeneratorOptions) &contract.ISnowWorker {
worker_id := options.worker_id worker_id := options.worker_id
mut workerid_bitlength:=byte(6) mut workerid_bitlength := byte(6)
if options.workerid_bitlength != 0 { if options.workerid_bitlength != 0 {
workerid_bitlength = options.workerid_bitlength workerid_bitlength = options.workerid_bitlength
} }
mut seq_bitlength:=byte(6) mut seq_bitlength := byte(6)
if options.seq_bitlength != 0 { if options.seq_bitlength != 0 {
seq_bitlength = options.seq_bitlength seq_bitlength = options.seq_bitlength
} }
mut max_seqnumber:=u32(0) mut max_seqnumber := u32(0)
if options.max_seqnumber > 0 { if options.max_seqnumber > 0 {
max_seqnumber = options.max_seqnumber max_seqnumber = options.max_seqnumber
} else { } else {
max_seqnumber = (1<<options.seq_bitlength) - 1 max_seqnumber = (1 << options.seq_bitlength) - 1
} }
min_seqnumber := options.min_seqnumber min_seqnumber := options.min_seqnumber
top_over_cost_count := options.top_over_cost_count top_over_cost_count := options.top_over_cost_count
mut base_time:=i64(0) mut base_time := i64(0)
if options.base_time != 0 { if options.base_time != 0 {
base_time = options.base_time base_time = options.base_time
} else { } else {
@@ -56,15 +54,16 @@ pub fn make_sf_m1(options &contract.IdGeneratorOptions) &contract.ISnowWorker{
timestamp_shift := byte(options.workerid_bitlength + options.seq_bitlength) timestamp_shift := byte(options.workerid_bitlength + options.seq_bitlength)
current_seqnumber := options.min_seqnumber current_seqnumber := options.min_seqnumber
return &SnowWorkerM1{ return &SnowWorkerM1{
base_time: base_time, base_time: base_time
worker_id: worker_id, worker_id: worker_id
workerid_bitlength: workerid_bitlength, workerid_bitlength: workerid_bitlength
seq_bitlength: seq_bitlength, seq_bitlength: seq_bitlength
max_seqnumber: max_seqnumber, max_seqnumber: max_seqnumber
min_seqnumber: min_seqnumber, min_seqnumber: min_seqnumber
top_over_cost_count: top_over_cost_count, top_over_cost_count: top_over_cost_count
timestamp_shift: timestamp_shift, timestamp_shift: timestamp_shift
current_seqnumber: current_seqnumber} current_seqnumber: current_seqnumber
}
} }
// fn (m1 SnowWorkerM1) do_gen_id_action(arg &contract.over_cost_action_arg) { // fn (m1 SnowWorkerM1) do_gen_id_action(arg &contract.over_cost_action_arg) {
@@ -162,13 +161,13 @@ fn (mut m1 SnowWorkerM1) next_normal_id() u64 {
} }
fn (mut m1 SnowWorkerM1) calc_id() u64 { fn (mut m1 SnowWorkerM1) calc_id() u64 {
result := u64(m1.last_time_tick<<m1.timestamp_shift) | u64(m1.worker_id<<m1.seq_bitlength) | u64(m1.current_seqnumber) result := u64(m1.last_time_tick << m1.timestamp_shift) | u64(m1.worker_id << m1.seq_bitlength) | u64(m1.current_seqnumber)
m1.current_seqnumber++ m1.current_seqnumber++
return result return result
} }
fn (mut m1 SnowWorkerM1) calc_turn_back_id() u64 { fn (mut m1 SnowWorkerM1) calc_turn_back_id() u64 {
result := u64(m1.turn_back_timetick<<m1.timestamp_shift) | u64(m1.worker_id<<m1.seq_bitlength) | u64(m1.turnback_index) result := u64(m1.turn_back_timetick << m1.timestamp_shift) | u64(m1.worker_id << m1.seq_bitlength) | u64(m1.turnback_index)
m1.turn_back_timetick-- m1.turn_back_timetick--
return result return result
} }
@@ -186,13 +185,13 @@ fn (m1 &SnowWorkerM1) get_next_time_tick() i64 {
} }
pub fn (mut m1 SnowWorkerM1) next_id() u64 { pub fn (mut m1 SnowWorkerM1) next_id() u64 {
m1.mu.@lock() mut id := u64(0)
mut id:=u64(0) lock {
if m1.is_over_cost { if m1.is_over_cost {
id= m1.next_over_cost_id() id = m1.next_over_cost_id()
} else { } else {
id= m1.next_normal_id() id = m1.next_normal_id()
}
} }
m1.mu.unlock()
return id return id
} }

View File

@@ -2,37 +2,37 @@ module core
import contract import contract
struct SnowWorkerM2{ struct SnowWorkerM2 {
SnowWorkerM1 SnowWorkerM1
} }
pub fn make_sf_m2(options &contract.IdGeneratorOptions) &contract.ISnowWorker{ pub fn make_sf_m2(options &contract.IdGeneratorOptions) &contract.ISnowWorker {
m1:=make_sf_m1(options) m1 := make_sf_m1(options)
if m1 is SnowWorkerM1{ if m1 is SnowWorkerM1 {
return &SnowWorkerM2{ return &SnowWorkerM2{m1}
m1
}
} }
return &SnowWorkerM2{} return &SnowWorkerM2{}
} }
pub fn (mut m2 SnowWorkerM2) next_id()u64{ pub fn (mut m2 SnowWorkerM2) next_id() u64 {
m2.mu.@lock() mut id := u64(0)
mut current_time_tick:=m2.get_current_time_tick() lock {
if m2.last_time_tick==current_time_tick{ mut current_time_tick := m2.get_current_time_tick()
m2.current_seqnumber=(m2.current_seqnumber+1) & m2.max_seqnumber if m2.last_time_tick == current_time_tick {
if m2.current_seqnumber==0{ m2.current_seqnumber = (m2.current_seqnumber + 1) & m2.max_seqnumber
m2.current_seqnumber=m2.min_seqnumber if m2.current_seqnumber == 0 {
current_time_tick=m2.get_next_time_tick() m2.current_seqnumber = m2.min_seqnumber
current_time_tick = m2.get_next_time_tick()
}
} else {
m2.current_seqnumber = m2.min_seqnumber
} }
}else{ if current_time_tick < m2.last_time_tick {
m2.current_seqnumber=m2.min_seqnumber println('Time error for ' + (m2.last_time_tick - current_time_tick).str() +
' milliseconds')
}
m2.last_time_tick = current_time_tick
id = u64(current_time_tick << m2.timestamp_shift) | u64(m2.worker_id << m2.seq_bitlength) | u64(m2.current_seqnumber)
} }
if current_time_tick < m2.last_time_tick {
println("Time error for "+(m2.last_time_tick-current_time_tick).str()+" milliseconds")
}
m2.last_time_tick=current_time_tick
id:= u64(current_time_tick<<m2.timestamp_shift) | u64(m2.worker_id<<m2.seq_bitlength) | u64(m2.current_seqnumber)
m2.mu.unlock()
return id return id
} }

View File

@@ -6,62 +6,60 @@ import time
pub struct DefaultIdGenerator { pub struct DefaultIdGenerator {
mut: mut:
options &contract.IdGeneratorOptions options &contract.IdGeneratorOptions
snow_worker &contract.ISnowWorker snow_worker &contract.ISnowWorker
} }
pub fn make_generator(options &contract.IdGeneratorOptions) &DefaultIdGenerator { pub fn make_generator(options &contract.IdGeneratorOptions) &DefaultIdGenerator {
min_time := i64(631123200000) min_time := i64(631123200000)
if options.base_time < min_time || options.base_time > time.now().unix_time_milli() { if options.base_time < min_time || options.base_time > time.now().unix_time_milli() {
panic("base_time error.") panic('base_time error.')
} }
if options.seq_bitlength+options.workerid_bitlength > 22 { if options.seq_bitlength + options.workerid_bitlength > 22 {
panic("errorworkerid_bitlength + seq_bitlength <= 22") panic('errorworkerid_bitlength + seq_bitlength <= 22')
} }
max_workerid_number := 1<<options.workerid_bitlength - 1 max_workerid_number := 1 << options.workerid_bitlength - 1
if options.worker_id > max_workerid_number { if options.worker_id > max_workerid_number {
panic("WorkerId error. (range:[1, " + max_workerid_number.str() + "]") panic('WorkerId error. (range:[1, ' + max_workerid_number.str() + ']')
} }
if options.seq_bitlength < 2 || options.seq_bitlength > 21 { if options.seq_bitlength < 2 || options.seq_bitlength > 21 {
panic("seq_bitlength error. (range:[2, 21])") panic('seq_bitlength error. (range:[2, 21])')
} }
max_seqnumber := 1<<options.seq_bitlength - 1 max_seqnumber := 1 << options.seq_bitlength - 1
if options.max_seqnumber > max_seqnumber { if options.max_seqnumber > max_seqnumber {
panic("MaxSeqNumber error. (range:[1, " + max_seqnumber.str() + "]") panic('MaxSeqNumber error. (range:[1, ' + max_seqnumber.str() + ']')
} }
if options.min_seqnumber > max_seqnumber { if options.min_seqnumber > max_seqnumber {
panic("MinSeqNumber error. (range:[1, " + max_seqnumber.str() + "]") panic('MinSeqNumber error. (range:[1, ' + max_seqnumber.str() + ']')
} }
match options.method { match options.method {
1 { 1 {
return &DefaultIdGenerator{ return &DefaultIdGenerator{
options: options, options: options
snow_worker: core.make_sf_m1(options), snow_worker: core.make_sf_m1(options)
} }
} }
2 { 2 {
return &DefaultIdGenerator{ return &DefaultIdGenerator{
options: options, options: options
snow_worker: core.make_sf_m2(options), snow_worker: core.make_sf_m2(options)
} }
} }
else { else {
return &DefaultIdGenerator{ return &DefaultIdGenerator{
options: options, options: options
snow_worker: core.make_sf_m1(options), snow_worker: core.make_sf_m1(options)
} }
} }
} }
} }
pub fn (mut dig DefaultIdGenerator) new_long() u64 { pub fn (mut dig DefaultIdGenerator) new_long() u64 {
return dig.snow_worker.next_id() return dig.snow_worker.next_id()
} }

View File

@@ -2,11 +2,17 @@ module gen
import contract import contract
pub struct YitIdHelper { pub struct YitIdHelper {
mut: mut:
id_gen contract.IIdGenerator id_gen contract.IIdGenerator
} }
pub fn (mut yih YitIdHelper) set_id_generator(options &contract.IdGeneratorOptions) {
lock {
yih.id_gen = make_generator(options)
}
}
pub fn (yih &YitIdHelper) next_id() u64 { pub fn (yih &YitIdHelper) next_id() u64 {
return yih.id_gen.new_long() return yih.id_gen.new_long()
} }

Binary file not shown.

View File

@@ -1,31 +1,34 @@
module main module main
import time import time
import contract import contract
import gen import gen
fn main(){ __global ( idgen gen.YitIdHelper )
// 方法一直接采用默认方法生成一个Id
yid := gen.YitIdHelper{
id_gen: gen.make_generator(&contract.IdGeneratorOptions{
method: 1
base_time: 1582136402000
workerid_bitlength:6
seq_bitlength:6
})
}
println(yid.next_id())
// 方法二自定义参数 fn main() {
idgen = gen.YitIdHelper{
id_gen: gen.make_generator(&contract.IdGeneratorOptions{})
}
// 方法一直接采用默认方法生成一个Id
println(idgen.next_id())
idgen.set_id_generator(&contract.IdGeneratorOptions{
method: 1
base_time: 1582136402000
workerid_bitlength: 6
seq_bitlength: 10
})
times := 50000 times := 50000
for { for {
begin := time.now().unix_time_milli() begin := time.now().unix_time_milli()
for i := 0; i < times; i++ { for i := 0; i < times; i++ {
yid.next_id() idgen.next_id()
} }
end := time.now().unix_time_milli() end := time.now().unix_time_milli()
println("漂移,总共:"+times.str()+""+(end-begin).str()+" ms") println('漂移总共' + times.str() + '' + (end - begin).str() + ' ms')
time.sleep(1 * time.second) time.sleep(1 * time.second)
} }
} }