github.com/GeniusesGroup/libgo@v0.0.0-20220929090155-5ff932cb408e/uuid/8byte/uuid.go (about)

     1  /* For license and copyright information please see LEGAL file in repository */
     2  
     3  package uuid
     4  
     5  import (
     6  	"crypto/rand"
     7  	"encoding/base64"
     8  	"io"
     9  
    10  	"golang.org/x/crypto/sha3"
    11  
    12  	"github.com/GeniusesGroup/libgo/binary"
    13  	"github.com/GeniusesGroup/libgo/protocol"
    14  	"github.com/GeniusesGroup/libgo/time/unix"
    15  )
    16  
    17  type UUID [8]byte
    18  
    19  func (id UUID) UUID() [8]byte      { return id }
    20  func (id UUID) ID() [3]byte        { return id.id() }
    21  func (id UUID) IDasString() string { return base64.RawURLEncoding.EncodeToString(id[:8]) }
    22  func (id UUID) ToString() string   { return "TODO:::" }
    23  func (id UUID) ExistenceTime() protocol.Time {
    24  	var time unix.Time
    25  	time.ChangeTo(unix.SecElapsed(id.secondElapsed()), 0)
    26  	return &time
    27  }
    28  
    29  // New will generate 8 byte time based UUID.
    30  // **CAUTION**: Use for ObjectID in a clustered software without any hash cause all writes always go to one node.
    31  // 99.999999% collision free on distribution generation.
    32  func (id *UUID) New() {
    33  	var err error
    34  	_, err = io.ReadFull(rand.Reader, id[5:])
    35  	if err != nil {
    36  		// TODO::: make random by other ways
    37  	}
    38  
    39  	// Set time to UUID
    40  	var now = unix.Now()
    41  	id.setSecondElapsed(now.SecondElapsed())
    42  }
    43  
    44  // NewHash generate 8 byte incremental by time + hash of data UUID
    45  // CAUTION::: Use for ObjectID in a clustered software cause all writes always go to one node!
    46  // 99.999% collision free on distribution generation.
    47  func (id *UUID) NewHash(data []byte) {
    48  	var uuid32 = sha3.Sum256(data)
    49  	copy(id[5:], uuid32[:])
    50  
    51  	// Set time to UUID
    52  	var now = unix.Now()
    53  	id.setSecondElapsed(now.SecondElapsed())
    54  }
    55  
    56  // NewRandom generate 8 byte random UUID.
    57  func (id *UUID) NewRandom() {
    58  	var err error
    59  	_, err = io.ReadFull(rand.Reader, id[:])
    60  	if err != nil {
    61  		// TODO::: make random by other ways
    62  	}
    63  }
    64  
    65  func (id UUID) id() (rid [3]byte)    { copy(rid[:], id[5:]); return }
    66  func (id UUID) secondElapsed() int64 { 
    67  	var sec [8]byte
    68  	copy(sec[:], id[:])
    69  	return int64(binary.LittleEndian.Uint64(id[0:])) >> (64 - 40)
    70  }
    71  func (id *UUID) setSecondElapsed(sec int64) {
    72  	binary.LittleEndian.PutUint64(id[0:], (uint64(sec) << (64 - 40)))
    73  }