github.com/matrixorigin/matrixone@v1.2.0/pkg/container/types/rowid.go (about) 1 // Copyright 2023 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 types 16 17 import ( 18 "bytes" 19 "encoding/hex" 20 "fmt" 21 "unsafe" 22 23 "github.com/google/uuid" 24 ) 25 26 /* 27 28 [SegUUID-16bytes] [ObjectOffset-2bytes] [BlockOffset-2bytes] [RowOffset-4bytes] 29 --------------------------------------- s3 file name 30 ------------------------------------------------------------ block id 31 ------------------------------------------------------------------------------ rowid 32 33 */ 34 35 const ObjectBytesSize = 18 36 37 type ObjectBytes = [ObjectBytesSize]byte 38 39 // BuildTestRowid used only in unit test. 40 func BuildTestRowid(a, b int64) (ret Rowid) { 41 copy(ret[0:8], EncodeInt64(&a)) 42 copy(ret[8:16], EncodeInt64(&b)) 43 copy(ret[20:], EncodeInt64(&b)) 44 return 45 } 46 47 // BuildTestBlockid used only in unit test 48 func BuildTestBlockid(a, b int64) (ret Blockid) { 49 copy(ret[0:8], EncodeInt64(&a)) 50 copy(ret[8:16], EncodeInt64(&b)) 51 return 52 } 53 54 func CompareRowidRowidAligned(a, b Rowid) int { 55 return bytes.Compare(a[:], b[:]) 56 } 57 58 func CompareBlockidBlockidAligned(a, b Blockid) int { 59 return bytes.Compare(a[:], b[:]) 60 } 61 62 func (r Rowid) Compare(other Rowid) int { 63 return bytes.Compare(r[:], other[:]) 64 } 65 66 func (r Rowid) Less(than Rowid) bool { 67 return bytes.Compare(r[:], than[:]) < 0 68 } 69 70 func (r Rowid) Le(than Rowid) bool { 71 return r.Less(than) || r.Equal(than) 72 } 73 74 func (r Rowid) Equal(to Rowid) bool { 75 return bytes.Equal(r[:], to[:]) 76 } 77 78 func (r Rowid) NotEqual(to Rowid) bool { 79 return !r.Equal(to) 80 } 81 82 func (r Rowid) Great(than Rowid) bool { 83 return !r.Less(than) 84 } 85 86 func (r Rowid) Ge(than Rowid) bool { 87 return r.Great(than) || r.Equal(than) 88 } 89 90 // CloneBlockID clones the block id from row id. 91 func (r *Rowid) CloneBlockID() Blockid { 92 return *(*Blockid)(unsafe.Pointer(&r[0])) 93 } 94 95 // BorrowBlockID borrows block id from row id. 96 func (r *Rowid) BorrowBlockID() *Blockid { 97 return (*Blockid)(unsafe.Pointer(&r[0])) 98 } 99 100 // BorrowSegmentID borrows segment id from row id. 101 func (r *Rowid) BorrowSegmentID() *Segmentid { 102 return (*Segmentid)(unsafe.Pointer(&r[0])) 103 } 104 105 // CloneSegmentID clones segment id from row id. 106 func (r *Rowid) CloneSegmentID() Segmentid { 107 return *(*Segmentid)(unsafe.Pointer(&r[0])) 108 } 109 110 func (r Rowid) Decode() (Blockid, uint32) { 111 b := *(*Blockid)(r[:BlockidSize]) 112 s := DecodeUint32(r[BlockidSize:]) 113 return b, s 114 } 115 116 func (r Rowid) GetObject() ObjectBytes { 117 return *(*ObjectBytes)(r[:ObjectBytesSize]) 118 } 119 120 func (r *Rowid) BorrowObjectID() *Objectid { 121 return (*Objectid)(unsafe.Pointer(&r[0])) 122 } 123 func (r *Rowid) SetRowOffset(offset uint32) { 124 copy(r[BlockidSize:], EncodeUint32(&offset)) 125 } 126 127 func (r Rowid) GetRowOffset() uint32 { 128 return DecodeUint32(r[BlockidSize:]) 129 } 130 131 func (r Rowid) GetBlockOffset() uint16 { 132 return DecodeUint16(r[ObjectBytesSize:BlockidSize]) 133 } 134 135 func (r Rowid) GetObjectString() string { 136 uuid := (*uuid.UUID)(r[:UuidSize]) 137 s := DecodeUint16(r[UuidSize:ObjectBytesSize]) 138 return fmt.Sprintf("%s-%d", uuid.String(), s) 139 } 140 141 func (r *Rowid) String() string { 142 b := (*Blockid)(unsafe.Pointer(&r[0])) 143 s := DecodeUint32(r[BlockidSize:]) 144 return fmt.Sprintf("%s-%d", b.String(), s) 145 } 146 147 func (b Blockid) Less(than Blockid) bool { 148 return b.Compare(than) < 0 149 } 150 151 func (b Blockid) Great(than Blockid) bool { 152 return b.Compare(than) > 0 153 } 154 155 func RandomRowid() Rowid { 156 var r Rowid 157 u, _ := uuid.NewV7() 158 copy(r[:], u[:]) 159 return r 160 } 161 162 func (b Blockid) Compare(other Blockid) int { 163 return bytes.Compare(b[:], other[:]) 164 } 165 166 func (b *Blockid) IsEmpty() bool { 167 for _, v := range b[:] { 168 if v != 0 { 169 return false 170 } 171 } 172 return true 173 } 174 175 func (b *Blockid) String() string { 176 uuid := (*uuid.UUID)(b[:UuidSize]) 177 filen, blkn := b.Offsets() 178 return fmt.Sprintf("%s-%d-%d", uuid.String(), filen, blkn) 179 } 180 181 func (b *Blockid) ShortString() string { 182 filen, blkn := b.Offsets() 183 return fmt.Sprintf("%d-%d", filen, blkn) 184 } 185 186 func (b *Blockid) ShortStringEx() string { 187 var shortuuid [12]byte 188 hex.Encode(shortuuid[:], b[10:16]) 189 filen, blkn := b.Offsets() 190 return fmt.Sprintf("%s-%d-%d", string(shortuuid[:]), filen, blkn) 191 } 192 193 func (b *Blockid) Offsets() (uint16, uint16) { 194 filen := DecodeUint16(b[UuidSize:ObjectBytesSize]) 195 blkn := DecodeUint16(b[ObjectBytesSize:BlockidSize]) 196 return filen, blkn 197 } 198 199 func (b *Blockid) Segment() *Segmentid { 200 return (*Uuid)(unsafe.Pointer(&b[0])) 201 } 202 203 func (b *Blockid) Object() *Objectid { 204 return (*Objectid)(unsafe.Pointer(&b[0])) 205 } 206 207 func (b *Blockid) Sequence() uint16 { 208 return DecodeUint16(b[ObjectBytesSize:BlockidSize]) 209 } 210 func (o *Objectid) Segment() *Segmentid { 211 return (*Uuid)(unsafe.Pointer(&o[0])) 212 } 213 func (o *Objectid) String() string { 214 return fmt.Sprintf("%v_%d", o.Segment().ToString(), o.Offset()) 215 } 216 func (o *Objectid) ShortStringEx() string { 217 var shortuuid [12]byte 218 hex.Encode(shortuuid[:], o[10:16]) 219 return string(shortuuid[:]) 220 } 221 func (o *Objectid) Offset() uint16 { 222 filen := DecodeUint16(o[UuidSize:ObjectBytesSize]) 223 return filen 224 } 225 226 func (o *Objectid) Eq(other Objectid) bool { 227 return bytes.Equal(o[:], other[:]) 228 } 229 230 func (o *Objectid) Le(other Objectid) bool { 231 return bytes.Compare(o[:], other[:]) <= 0 232 } 233 func (o *Objectid) Ge(other Objectid) bool { 234 return bytes.Compare(o[:], other[:]) >= 0 235 } 236 func (o *Objectid) Lt(other Objectid) bool { 237 return bytes.Compare(o[:], other[:]) < 0 238 } 239 func (o *Objectid) Gt(other Objectid) bool { 240 return bytes.Compare(o[:], other[:]) > 0 241 }