github.com/matrixorigin/matrixone@v1.2.0/pkg/vm/engine/memoryengine/id.go (about) 1 // Copyright 2022 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package memoryengine 16 17 import ( 18 "bytes" 19 "context" 20 "encoding/binary" 21 "math/bits" 22 "sync/atomic" 23 "time" 24 25 "github.com/matrixorigin/matrixone/pkg/container/types" 26 ) 27 28 type ID uint64 29 30 func (i ID) Less(than ID) bool { 31 return i < than 32 } 33 34 func (i ID) IsEmpty() bool { 35 return i == emptyID 36 } 37 38 var ( 39 emptyID ID 40 ) 41 42 func (i ID) ToRowID() types.Rowid { 43 buf := new(bytes.Buffer) 44 if err := binary.Write(buf, binary.LittleEndian, i); err != nil { 45 panic(err) 46 } 47 if buf.Len() > types.RowidSize { 48 panic("id size too large") 49 } 50 var rowID types.Rowid 51 copy(rowID[:], buf.Bytes()) 52 return rowID 53 } 54 55 type IDGenerator interface { 56 NewID(context.Context) (ID, error) 57 NewIDByKey(ctx context.Context, key string) (ID, error) 58 } 59 60 type randomIDGenerator struct{} 61 62 var _ IDGenerator = new(randomIDGenerator) 63 64 var idCounter int64 65 66 func (r *randomIDGenerator) NewID(_ context.Context) (ID, error) { 67 ts := time.Now().Unix() 68 n := bits.LeadingZeros(uint(ts)) 69 return ID(ts<<n + atomic.AddInt64(&idCounter, 1)%(1<<n)), nil 70 } 71 72 func (r *randomIDGenerator) NewIDByKey(_ context.Context, _ string) (ID, error) { 73 ts := time.Now().Unix() 74 n := bits.LeadingZeros(uint(ts)) 75 return ID(ts<<n + atomic.AddInt64(&idCounter, 1)%(1<<n)), nil 76 } 77 78 var RandomIDGenerator = new(randomIDGenerator) 79 80 type hakeeperIDGenerator interface { 81 // both CNHAKeeperClient and DNHAKeeperClient has this method 82 AllocateID(ctx context.Context) (uint64, error) 83 AllocateIDByKey(ctx context.Context, key string) (uint64, error) 84 } 85 86 type HakeeperIDGenerator struct { 87 generator hakeeperIDGenerator 88 } 89 90 func NewHakeeperIDGenerator( 91 generator hakeeperIDGenerator, 92 ) *HakeeperIDGenerator { 93 return &HakeeperIDGenerator{ 94 generator: generator, 95 } 96 } 97 98 var _ IDGenerator = new(HakeeperIDGenerator) 99 100 func (h *HakeeperIDGenerator) NewID(ctx context.Context) (ID, error) { 101 ctx, cancel := context.WithTimeout(ctx, time.Minute) 102 defer cancel() 103 id, err := h.generator.AllocateID(ctx) 104 if err != nil { 105 return 0, err 106 } 107 return ID(id), nil 108 } 109 110 func (h *HakeeperIDGenerator) NewIDByKey(ctx context.Context, key string) (ID, error) { 111 ctx, cancel := context.WithTimeout(ctx, time.Minute) 112 defer cancel() 113 id, err := h.generator.AllocateIDByKey(ctx, key) 114 if err != nil { 115 return 0, err 116 } 117 return ID(id), nil 118 }