snowflake

package module
v0.0.0-...-486bd7f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 18, 2019 License: Apache-2.0 Imports: 7 Imported by: 0

README

snowflake

ENGLISH | 简体中文

Build Status Coverage Status Go Report Card

A snowflag id generation tool written by golang and based on the principle of twitter snowflag id.

For more introduction to snowflake ID, please click me!

The structure is like this:

1 bits                         41 bits                           10 bits         12 bits
│  0  │ 0 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 │ 00 0000 0000 │ 0000 0000 0000 │
unused                  time in milliseconds                   machine id      sequence id

In order to reduce the performance consumption caused by calculation and various uncertainties of the final generation form, the operation form of direct assignment is adopted to generate snowflake ID.

It was tested. It was good.

Quick start

Install
go get -u -v github.com/0xn0ne/snowflake
Usage

The default attributes in the default snowflake id are Overtime (elapsed time after creation), Sequence (ID sequence number generated in the same microsecond), Args (other data stored).

Global variables that support modification include Epoch, SequenceBits, ArgsOrder, ArgsBits, high customization.

! ! ! Note: the total number of bits of Snowflake id is 64. if the modified SequenceBits and ArgsBits are occupy too many bits, leaving insufficient bits for timestamps.

recommended to reserve a length of 40 bits for timestamps, i.e. if Epoch is set to the current time, Snowflake id can maintain no conflicts for 34 years.

package main

import (
	"fmt"
	"github.com/0xn0ne/snowflake"
	"log"
)

func main() {
	// Custom Snowflake Epoch, it doesn't matter whether this step is taken or not
	// but it is recommended that Snowflake Epoch is set as the time when the project goes online.
	snowflake.Epoch = 1547963303708

	m, err := snowflake.NewManager()
	if err != nil {
		log.Fatal(err)
	}
	sid := m.New(map[string]int64{}).(*snowflake.IdByDefault)

	fmt.Println("Raw:", sid)
	fmt.Println()

	fmt.Println("Base info:")
	fmt.Println("Over time      :", sid.Overtime)
	fmt.Println("Args           :", sid.Args)
	fmt.Println("Sequence       :", sid.Sequence)
	fmt.Println("Create time    :", sid.CreateTime())
	fmt.Println()

	fmt.Println("Conversion:")
	i64, err := sid.ToInt64()
	fmt.Println("int64          :", i64)
	b, err := sid.ToBytes()
	fmt.Println("[]byte         :", b)
	s, err := sid.ToString()
	fmt.Println("hex string     :", s)
	fmt.Println()

	sFromI64, _ := m.ParseInt64(i64)
	sFromByt, _ := m.ParseBytes(b)
	sFromStr, _ := m.ParseString(s)
	fmt.Println("Restore:")
	fmt.Println("from int64     :", sFromI64)
	fmt.Println("from hex string:", sFromByt)
	fmt.Println("from []byte    :", sFromStr)
}
Modify Args

By default, Args stores unused and machine data. if you think the default Args is not useful, you can manually modify it to the structure you want, such as:

package main

import (
	"fmt"
	"github.com/0xn0ne/snowflake"
	"log"
)

func main() {
	snowflake.ArgsOrder = []string{"thread", "machine"}
	snowflake.ArgsBits = map[string]uint8{"thread": 4, "machine": 8}

	m, err := snowflake.NewManager()
	if err != nil {
		log.Fatal(err)
	}
	sid := m.New(map[string]int64{"thread": 6, "machine": 4}).(*snowflake.IdByDefault)
	fmt.Println("Snowfalke id:", sid)
	fmt.Println("machine     :", sid.Args["machine"])
	fmt.Println("thread      :", sid.Args["thread"])

	i64, _ := sid.ToInt64()
	fmt.Println("to int64    :", i64)
	id, _ := m.ParseInt64(i64)
	fmt.Println("from int64  :", id)
}

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ArgsOrder defines the order in which data is stored.
	// If the keys of ArgsBits are not in ArgsOrder, these keys will not be used.
	ArgsOrder = []string{"unused", "machine"}

	// ArgsBits defines number of bits of snowflake id occupied by key.
	// It is recommended to set aside 40 bits for Overtime.
	// Please note that the default Sequence takes up 12 bits.
	ArgsBits = map[string]uint8{"unused": 1, "machine": 10}

	// ArgsOffsetBits defines offset of each Args, Automatically calculate when new manager is created.
	ArgsOffsetBits = map[string]uint8{}

	// ArgsMax defines max of each Args, Automatically calculate when new manager is created.
	ArgsMax = map[string]int64{}
)
View Source
var (
	// Epoch defines a start time and recommended to be set as the project on-line time.
	Epoch int64 = 1288834974657

	// OvertimeBits defines the number of bits occupied by Overtime. Automatic initialization.
	OvertimeBits uint8 = 64

	// SequenceBits defines the number of bits occupied by Sequence.
	SequenceBits uint8 = 12

	// OvertimeOffsetBits defines the offset of Overtime. Automatic initialization.
	OvertimeOffsetBits uint8 = SequenceBits

	// SequenceOffsetBits defines the offset of Sequence. Automatic initialization.
	SequenceOffsetBits uint8

	// OvertimeMax defines the maximum value of Overtime. Automatic initialization.
	OvertimeMax int64 = -1 ^ (-1 << OvertimeMax)

	// SequenceMax defines the maximum value of Sequence. Automatic initialization.
	SequenceMax int64 = -1 ^ (-1 << SequenceBits)
)

Functions

This section is empty.

Types

type ID

type ID interface {
	// convert id to int64 type
	ToInt64() (int64, error)

	// convert id to []byte type
	ToBytes() ([]byte, error)

	// convert id to string type
	ToString() (string, error)

	// Calculates id create time
	CreateTime() int64
}

ID is the raw interface of snowflake id. The following functions represent actions that can be used.

type IdByDefault

type IdByDefault struct {
	Args     map[string]int64
	Overtime int64
	Sequence int64
}

snowflake id Args is the content stored in snowflake id. If the key of args does not exist, the default value is 0. Overtime = now - Epoch (in ms) Sequence is the serial number in the same microsecond.

func (*IdByDefault) CreateTime

func (id *IdByDefault) CreateTime() int64

Calculates id create time Please do not modify Epoch at will, otherwise CreateTime will be confused.

func (*IdByDefault) ToBytes

func (id *IdByDefault) ToBytes() ([]byte, error)

convert id to []byte type

func (*IdByDefault) ToInt64

func (id *IdByDefault) ToInt64() (int64, error)

convert id to int64 type

func (*IdByDefault) ToString

func (id *IdByDefault) ToString() (string, error)

convert id to string type

type Manager

type Manager interface {
	// New return a Snowflake ID interface.
	// This ID records key data.
	New(map[string]int64) ID

	// NewToInt64 return int64 data that can be used to represent an ID, and return possible errors.
	NewToInt64(map[string]int64) (int64, error)

	// ParseInt64 return parsed int64 data, and return possible errors.
	ParseInt64(int64) (ID, error)

	// NewBytes return []byte data that can be used to represent an ID, and return possible errors.
	NewBytes(map[string]int64) ([]byte, error)

	// ParseInt64 return parsed []byte data, and return possible errors.
	ParseBytes([]byte) (ID, error)

	// NewString return string data that can be used to represent an ID, and return possible errors.
	NewString(map[string]int64) (string, error)

	// ParseInt64 return parsed string data, and return possible errors.
	ParseString(string) (ID, error)
}

Manager is the raw interface used to create snowflake id. The following functions represent the operations that can be used. To be honest, I don't know why I don't call it generators.

func NewDefaultManager

func NewDefaultManager() (Manager, error)

ManagerByDefault returns a Manager object and an error caused by some abnormal data All the generation and analysis are operated by the manager.

func NewManager

func NewManager() (Manager, error)

NewManager retrun NewDefaultManager object. snowflagid is mainly generated/parsed by manager.

type ManagerByDefault

type ManagerByDefault struct {
	Mut         sync.Mutex
	LastUseTime int64
	Sequence    int64
}

id manager Mut dirty data lock. LastUseTime records the last time the manager was used. Sequence records the id serial number that was last generated using the manager.

func (*ManagerByDefault) New

func (m *ManagerByDefault) New(args map[string]int64) ID

Create a new snowflag id Args is snowflake id Args !!!In fact, this part is unsafe because the maximum value is not checked for performance reasons. One solution is to move the args part to the manager.

func (*ManagerByDefault) NewBytes

func (m *ManagerByDefault) NewBytes(args map[string]int64) ([]byte, error)

Create a new snowflag id and convert it to []byte type

func (*ManagerByDefault) NewString

func (m *ManagerByDefault) NewString(args map[string]int64) (string, error)

Create a new snowflag id and convert it to string type

func (*ManagerByDefault) NewToInt64

func (m *ManagerByDefault) NewToInt64(args map[string]int64) (int64, error)

Create a new snowflag id and convert it to int64 type

func (*ManagerByDefault) ParseBytes

func (m *ManagerByDefault) ParseBytes(b []byte) (ID, error)

Parsing snowflake id from []byte type data

func (*ManagerByDefault) ParseInt64

func (m *ManagerByDefault) ParseInt64(i64 int64) (ID, error)

Parsing snowflake id from int64 type data

func (*ManagerByDefault) ParseString

func (m *ManagerByDefault) ParseString(s string) (ID, error)

Parsing snowflake id from string type data

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL