github.com/matrixorigin/matrixone@v1.2.0/pkg/container/types/bytes.go (about) 1 // Copyright 2021 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 "unsafe" 20 21 "github.com/matrixorigin/matrixone/pkg/common/mpool" 22 "github.com/matrixorigin/matrixone/pkg/common/util" 23 ) 24 25 const ( 26 VarlenaInlineSize = 23 27 VarlenaSize = 24 28 MaxStringSize = 10485760 29 VarlenaBigHdr = 0xffffffff 30 MaxVarcharLen = 65535 31 MaxCharLen = 255 32 MaxBinaryLen = 255 33 MaxVarBinaryLen = 65535 34 MaxEnumLen = 65535 35 MaxBitLen = 64 36 ) 37 38 func (v *Varlena) UnsafePtr() unsafe.Pointer { 39 return unsafe.Pointer(&v[0]) 40 } 41 42 func (v *Varlena) ByteSlice() []byte { 43 svlen := (*v)[0] 44 ptr := unsafe.Add(unsafe.Pointer(&v[0]), 1) 45 return unsafe.Slice((*byte)(ptr), svlen) 46 } 47 48 func (v *Varlena) U32Slice() []uint32 { 49 ptr := (*uint32)(v.UnsafePtr()) 50 return unsafe.Slice(ptr, 6) 51 } 52 53 func (v *Varlena) OffsetLen() (uint32, uint32) { 54 s := v.U32Slice() 55 return s[1], s[2] 56 } 57 58 func (v *Varlena) SetOffsetLen(voff, vlen uint32) { 59 s := v.U32Slice() 60 s[0] = VarlenaBigHdr 61 s[1] = voff 62 s[2] = vlen 63 } 64 65 // do not use this function, will be deleted in the future 66 // use BuildVarlenaFromValena or BuildVarlenaFromByteSlice instead 67 func BuildVarlena(bs []byte, area []byte, m *mpool.MPool) (Varlena, []byte, error) { 68 var err error 69 var v Varlena 70 vlen := len(bs) 71 if vlen <= VarlenaInlineSize { 72 v[0] = byte(vlen) 73 copy(v[1:1+vlen], bs) 74 return v, area, nil 75 } else { 76 voff := len(area) 77 if voff+vlen < cap(area) || m == nil { 78 area = append(area, bs...) 79 } else { 80 area, err = m.Grow2(area, bs, voff+vlen) 81 if err != nil { 82 return v, nil, err 83 } 84 } 85 v.SetOffsetLen(uint32(voff), uint32(vlen)) 86 return v, area, nil 87 } 88 } 89 90 func (v *Varlena) IsSmall() bool { 91 return (*v)[0] <= VarlenaInlineSize 92 } 93 94 // For short slice, this one will return a slice stored internal 95 // in the varlena. Caller must ensure that v has a longer life 96 // span than the returned byte slice. 97 // 98 // Main user of Varlena is vector. v that comes from vector.Data 99 // will be fine. 100 func (v *Varlena) GetByteSlice(area []byte) []byte { 101 svlen := (*v)[0] 102 if svlen <= VarlenaInlineSize { 103 return v.ByteSlice() 104 } 105 voff, vlen := v.OffsetLen() 106 return area[voff : voff+vlen] 107 } 108 109 // GetArray Returns []T from Varlena. If the Varlena size is less than Inline size, 110 // it returns the value from the Varlena header. 111 // Else, it returns the value from the area. 112 func GetArray[T RealNumbers](v *Varlena, area []byte) []T { 113 svlen := (*v)[0] 114 if svlen <= VarlenaInlineSize { 115 return BytesToArray[T](v.ByteSlice()) 116 } 117 voff, vlen := v.OffsetLen() 118 return BytesToArray[T](area[voff : voff+vlen]) 119 } 120 121 // See the lifespan comment above. 122 func (v *Varlena) GetString(area []byte) string { 123 return util.UnsafeBytesToString(v.GetByteSlice(area)) 124 } 125 126 func (v *Varlena) Reset() { 127 var vzero Varlena 128 *v = vzero 129 } 130 131 func PrefixCompare(lhs, rhs []byte) int { 132 if len(lhs) > len(rhs) { 133 lhs = lhs[:len(rhs)] 134 } 135 136 return bytes.Compare(lhs, rhs) 137 }