From 288d78f66ecd1b628e8d1df7a3da99fc5e6880ec Mon Sep 17 00:00:00 2001
From: zhangqian <zhangqian@123.com>
Date: 星期五, 08 十二月 2023 14:13:37 +0800
Subject: [PATCH] debug

---
 pkg/snowflake/snowflake.go |  178 +++++++++++++++++++++++++++-------------------------------
 1 files changed, 83 insertions(+), 95 deletions(-)

diff --git a/pkg/snowflake/snowflake.go b/pkg/snowflake/snowflake.go
index ad86994..049b307 100644
--- a/pkg/snowflake/snowflake.go
+++ b/pkg/snowflake/snowflake.go
@@ -1,118 +1,106 @@
 package snowflake
 
 import (
-	"errors"
-	"strconv"
-	"sync"
-	"time"
+	"apsClient/pkg/logx"
+	"fmt"
+	"github.com/bwmarrin/snowflake"
+	"hash/fnv"
+	"net"
 )
 
-const (
-	CEpoch         = 1474802888000
-	CWorkerIdBits  = 10 // Num of WorkerId Bits
-	CSenquenceBits = 12 // Num of Sequence Bits
+var Node *snowflake.Node
 
-	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")
+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
 	}
-	iw.workerId = workerId
-	iw.lastTimeStamp = -1
-	iw.sequence = 0
-	iw.lock = new(sync.Mutex)
-	return iw, nil
+	return nil
 }
 
-func getMaxWorkerId() int64 {
-	return -1 ^ -1<<CWorkerIdBits
-}
+func InitWithIP() {
+	// 浣跨敤 LookupIP 鑾峰彇涓绘満鐨� IP 鍦板潃鍒楄〃
+	// 鑾峰彇鏈満鎵�鏈夌綉缁滄帴鍙�
+	interfaces, err := net.Interfaces()
+	if err != nil {
+		logx.Errorf("snowflake InitWithIP error:%v", err)
+		return
+	}
 
-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
+	var ip string
+	// 閬嶅巻鎵�鏈夌綉缁滄帴鍙�
+	for _, iface := range interfaces {
+		// 鎺掗櫎涓�浜涚壒娈婄殑鎺ュ彛锛屼緥濡� loopback 鎺ュ彛
+		if iface.Flags&net.FlagUp != 0 && iface.Flags&net.FlagLoopback == 0 {
+			// 鑾峰彇鎺ュ彛鐨勬墍鏈夊湴鍧�
+			addrs, err := iface.Addrs()
+			if err != nil {
+				logx.Errorf("snowflake InitWithIP error:%v", err)
+				continue
+			}
+			// 閬嶅巻鎺ュ彛鐨勬墍鏈夊湴鍧�
+			for _, addr := range addrs {
+				// 妫�鏌ュ湴鍧�绫诲瀷鏄惁鏄� IP 鍦板潃
+				if ipNet, ok := addr.(*net.IPNet); ok && !ipNet.IP.IsLoopback() {
+					// 鍒ゆ柇 IP 鍦板潃鐨勭増鏈槸 IPv4 杩樻槸 IPv6
+					if ipNet.IP.To4() != nil {
+						fmt.Printf("IPv4 Address: %s\n", ipNet.IP.String())
+						if ipNet.IP.String() != "127.0.0.1" {
+							ip = ipNet.IP.String()
+							goto getIpOK
+						}
+					} else {
+						fmt.Printf("IPv6 Address: %s\n", ipNet.IP.String())
+					}
+				}
+			}
 		}
 	}
-	return ts
+getIpOK:
+	if ip == "" {
+		logx.Errorf("snowflake InitWithIP can not find Ip")
+		return
+	}
+	ipNumber, err := ipToNumber(ip)
+	if err != nil {
+		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)
+	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 (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")
+func StringToNumber(input string) (int64, error) {
+	hash := fnv.New32a()
+	_, err := hash.Write([]byte(input))
+	if err != nil {
 		return 0, err
 	}
-	iw.lastTimeStamp = ts
-	ts = (ts-CEpoch)<<CTimeStampShift | iw.workerId<<CWorkerIdShift | iw.sequence
-	return ts, nil
+	return int64(hash.Sum32() % 1024), nil // 鍙栦綑鏁扮‘淇濈粨鏋滃湪 1 鍒� 1023 涔嬮棿
 }
 
-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
-}
-
-var idGenerater, _ = NewIdWorker(0)
-
-func GenerateId() int64 {
-start:
-	id, err := idGenerater.NextId()
-	if err != nil {
-		goto start
+func ipToNumber(ip string) (int64, error) {
+	// 灏� IP 鍦板潃瀛楃涓茶В鏋愪负 net.IP 绫诲瀷
+	parsedIP := net.ParseIP(ip)
+	if parsedIP == nil {
+		return 0, fmt.Errorf("invalid IP address:%v", ip)
 	}
-	return id
+
+	// 浣跨敤 FNV-1a 鏁e垪绠楁硶璁$畻鍝堝笇鍊�
+	hash := fnv.New32a()
+	hash.Write(parsedIP)
+	return int64(hash.Sum32() % 1024), nil // 鍙栦綑鏁扮‘淇濈粨鏋滃湪 1 鍒� 1023 涔嬮棿
 }
 
-func GenerateIdStr() string {
-start:
-	id, err := idGenerater.NextId()
-	if err != nil {
-		goto start
+func GenerateID() int64 {
+	if Node == nil {
+		InitWithIP()
 	}
-	return strconv.FormatInt(id, 10)
+	return int64(Node.Generate())
 }

--
Gitblit v1.8.0