diff --git a/pkg/conver/conver.go b/pkg/conver/conver.go index 7fcd53a..b277b11 100644 --- a/pkg/conver/conver.go +++ b/pkg/conver/conver.go @@ -1,7 +1,69 @@ package conver -import "strconv" +import ( + "fmt" + "strconv" + "strings" +) func FloatToString(val float64) string { return strconv.FormatFloat(val, 'f', 1, 64) } + +func SliceIntToString(num []int64) string { + result := "" + + if len(num) > 0 { + for _, item := range num { + result = fmt.Sprintf("%s,%d", result, item) + } + if !strings.HasSuffix(result, ",") { + result = fmt.Sprintf("%s,", result) + } + } + + return result +} + +func SliceStringToString(num []string) string { + result := "" + + if len(num) > 0 { + for _, item := range num { + result = fmt.Sprintf("%s,%s", result, item) + } + if !strings.HasSuffix(result, ",") { + result = fmt.Sprintf("%s,", result) + } + } + + return result +} + +func StringToSlice(num string) []string { + var result []string + + if len(num) > 0 { + result = strings.Split(num, ",") + } + + return result +} + +func StringToSliceInt(num string) []int64 { + var result []int64 + + if len(num) > 0 { + array := strings.Split(num, ",") + if len(array) > 0 { + for _, item := range array { + i, err := strconv.Atoi(item) + if err == nil { + result = append(result, int64(i)) + } + } + } + } + + return result +} diff --git a/pkg/snowflake/snowflake.go b/pkg/snowflake/snowflake.go new file mode 100644 index 0000000..05a8b59 --- /dev/null +++ b/pkg/snowflake/snowflake.go @@ -0,0 +1,55 @@ +package snowflake + +import ( + "errors" + "sync" + "time" +) + +const ( + workerBits uint8 = 10 + numberBits uint8 = 12 + workerMax int64 = -1 ^ (-1 << workerBits) + numberMax int64 = -1 ^ (-1 << numberBits) + timeShift uint8 = workerBits + numberBits + workerShift uint8 = numberBits + startTime int64 = 1262275200000 // 如果在程序跑了一段时间修改了epoch这个值 可能会导致生成相同的ID (开始时间-毫秒) +) + +type Worker struct { + mu sync.Mutex + timestamp int64 + workerId int64 + number int64 +} + +func NewWorker(workerId int64) (*Worker, error) { + if workerId < 0 || workerId > workerMax { + return nil, errors.New("worker id excess of quantity") + } + // 生成一个新节点 + return &Worker{ + timestamp: 0, + workerId: workerId, + number: 0, + }, nil +} + +func (w *Worker) GetId() int64 { + w.mu.Lock() + defer w.mu.Unlock() + now := time.Now().UnixNano() / 1e6 + if w.timestamp == now { + w.number++ + if w.number > numberMax { + for now <= w.timestamp { + now = time.Now().UnixNano() / 1e6 + } + } + } else { + w.number = 0 + w.timestamp = now + } + ID := int64((now-startTime)<