zhangqian
2023-12-08 32e00f9438ed29fc26351f65cf7d98eefd1d838e
换个雪花算法
3个文件已修改
152 ■■■■ 已修改文件
go.mod 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
go.sum 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pkg/snowflake/snowflake.go 140 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
go.mod
@@ -9,6 +9,7 @@
    basic.com/valib/bhomedbapi.git v0.0.0-20220825084023-fe74ddd6ae6e
    github.com/apache/plc4x/plc4go v0.0.0-20230817065839-dd203446b558
    github.com/gin-contrib/cors v1.4.0
    github.com/gin-contrib/pprof v1.4.0
    github.com/gin-gonic/gin v1.9.1
    github.com/go-co-op/gocron v1.32.1
    github.com/go-redis/redis/v8 v8.11.4
@@ -19,8 +20,10 @@
    github.com/jinzhu/gorm v1.9.16
    github.com/mitchellh/mapstructure v1.5.0
    github.com/mojocn/base64Captcha v1.3.1
    github.com/muesli/cache2go v0.0.0-20221011235721-518229cd8021
    github.com/nsqio/go-nsq v1.1.0
    github.com/robfig/cron/v3 v3.0.1
    github.com/satori/go.uuid v1.2.0
    github.com/shirou/gopsutil v3.21.11+incompatible
    github.com/shopspring/decimal v1.3.1
    github.com/songzhibin97/gkit v1.2.10
@@ -41,7 +44,6 @@
    github.com/IBM/netaddr v1.5.0 // indirect
    github.com/KyleBanks/depth v1.2.1 // indirect
    github.com/ajg/form v1.5.1 // indirect
    github.com/bwmarrin/snowflake v0.3.0 // indirect
    github.com/bytedance/sonic v1.9.1 // indirect
    github.com/cespare/xxhash/v2 v2.2.0 // indirect
    github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
@@ -50,7 +52,6 @@
    github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
    github.com/fsnotify/fsnotify v1.6.0 // indirect
    github.com/gabriel-vasile/mimetype v1.4.2 // indirect
    github.com/gin-contrib/pprof v1.4.0 // indirect
    github.com/gin-contrib/sse v0.1.0 // indirect
    github.com/go-ole/go-ole v1.2.6 // indirect
    github.com/go-openapi/jsonpointer v0.19.6 // indirect
@@ -84,14 +85,12 @@
    github.com/mattn/go-sqlite3 v1.14.17 // indirect
    github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
    github.com/modern-go/reflect2 v1.0.2 // indirect
    github.com/muesli/cache2go v0.0.0-20221011235721-518229cd8021 // indirect
    github.com/onsi/gomega v1.27.4 // indirect
    github.com/pelletier/go-toml/v2 v2.0.8 // indirect
    github.com/pkg/errors v0.9.1 // indirect
    github.com/pmezard/go-difflib v1.0.0 // indirect
    github.com/rogpeppe/go-internal v1.10.0 // indirect
    github.com/rs/zerolog v1.30.0 // indirect
    github.com/satori/go.uuid v1.2.0 // indirect
    github.com/spf13/afero v1.9.5 // indirect
    github.com/spf13/jwalterweatherman v1.1.0 // indirect
    github.com/spf13/pflag v1.0.5 // indirect
go.sum
@@ -63,9 +63,6 @@
github.com/apache/plc4x/plc4go v0.0.0-20230817065839-dd203446b558 h1:d3INvMf4ei9qlX10We5+z/+dQnmmCx0J0wflcZVihGo=
github.com/apache/plc4x/plc4go v0.0.0-20230817065839-dd203446b558/go.mod h1:KC3Kj7xv0dlGb5yT1+Mz9cI9YZj1RD19cr8TyqfnBDU=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0=
github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE=
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
@@ -277,7 +274,6 @@
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -421,7 +417,6 @@
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8=
go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
pkg/snowflake/snowflake.go
@@ -2,26 +2,18 @@
import (
    "apsClient/pkg/logx"
    "errors"
    "fmt"
    "github.com/bwmarrin/snowflake"
    "hash/fnv"
    "net"
    "strconv"
    "sync"
    "time"
)
var Node *snowflake.Node
var idGenerater *IdWorker
func Init(nodeId int64) error {
    // Create a new Node with a Node number of 0~1023
    var err error
    Node, err = snowflake.NewNode(nodeId)
    if err != nil {
        logx.Errorf("snowflake NewNode error:%v", err)
        return err
    }
    return nil
}
func InitWithIP() {
func init() {
    // 使用 LookupIP 获取主机的 IP 地址列表
    // 获取本机所有网络接口
    interfaces, err := net.Interfaces()
@@ -69,20 +61,11 @@
        logx.Errorf("snowflake can not generate, init error, ip to number error :%v", err)
        panic(fmt.Sprintf("snowflake can not generate, init error, ip to number error :%v", err))
    }
    err = Init(ipNumber)
    idGenerater, err = NewIdWorker(ipNumber)
    if err != nil {
        logx.Errorf("snowflake can not generate, init error :%v", err)
        panic(fmt.Sprintf("snowflake can not generate, init error :%v", err))
    }
}
func StringToNumber(input string) (int64, error) {
    hash := fnv.New32a()
    _, err := hash.Write([]byte(input))
    if err != nil {
        return 0, err
    }
    return int64(hash.Sum32() % 1024), nil // 取余数确保结果在 1 到 1023 之间
}
func ipToNumber(ip string) (int64, error) {
@@ -98,9 +81,110 @@
    return int64(hash.Sum32() % 1024), nil // 取余数确保结果在 1 到 1023 之间
}
func GenerateID() int64 {
    if Node == nil {
        InitWithIP()
const (
    CEpoch         = 1474802888000
    CWorkerIdBits  = 10 // Num of WorkerId Bits
    CSenquenceBits = 12 // Num of Sequence Bits
    CWorkerIdShift  = 12
    CTimeStampShift = 22
    CSequenceMask = 0xfff // equal as getSequenceMask()
    CMaxWorker    = 0x3ff // equal as getMaxWorkerId()
)
type IdWorker struct {
    workerId      int64
    lastTimeStamp int64
    sequence      int64
    maxWorkerId   int64
    lock          *sync.Mutex
}
func NewIdWorker(workerId int64) (iw *IdWorker, err error) {
    iw = new(IdWorker)
    iw.maxWorkerId = getMaxWorkerId()
    if workerId > iw.maxWorkerId || workerId < 0 {
        return nil, errors.New("worker not fit")
    }
    return int64(Node.Generate())
    iw.workerId = workerId
    iw.lastTimeStamp = -1
    iw.sequence = 0
    iw.lock = new(sync.Mutex)
    return iw, nil
}
func getMaxWorkerId() int64 {
    return -1 ^ -1<<CWorkerIdBits
}
func getSequenceMask() int64 {
    return -1 ^ -1<<CSenquenceBits
}
// return in ms
func (iw *IdWorker) timeGen() int64 {
    return time.Now().UnixNano() / 1000 / 1000
}
func (iw *IdWorker) timeReGen(last int64) int64 {
    ts := time.Now().UnixNano() / 1000 / 1000
    for {
        if ts <= last {
            ts = iw.timeGen()
        } else {
            break
        }
    }
    return ts
}
func (iw *IdWorker) NextId() (ts int64, err error) {
    iw.lock.Lock()
    defer iw.lock.Unlock()
    ts = iw.timeGen()
    if ts == iw.lastTimeStamp {
        iw.sequence = (iw.sequence + 1) & CSequenceMask
        if iw.sequence == 0 {
            ts = iw.timeReGen(ts)
        }
    } else {
        iw.sequence = 0
    }
    if ts < iw.lastTimeStamp {
        err = errors.New("Clock moved backwards, Refuse gen id")
        return 0, err
    }
    iw.lastTimeStamp = ts
    ts = (ts-CEpoch)<<CTimeStampShift | iw.workerId<<CWorkerIdShift | iw.sequence
    return ts, nil
}
func ParseId(id int64) (t time.Time, ts int64, workerId int64, seq int64) {
    seq = id & CSequenceMask
    workerId = (id >> CWorkerIdShift) & CMaxWorker
    ts = (id >> CTimeStampShift) + CEpoch
    t = time.Unix(ts/1000, (ts%1000)*1000000)
    return
}
func GenerateID() int64 {
start:
    id, err := idGenerater.NextId()
    if err != nil {
        goto start
    }
    return id
}
func GenerateIdStr() string {
start:
    id, err := idGenerater.NextId()
    if err != nil {
        goto start
    }
    return strconv.FormatInt(id, 10)
}