github.com/matrixorigin/matrixone@v0.7.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 "unsafe" 19 20 "github.com/matrixorigin/matrixone/pkg/common/mpool" 21 ) 22 23 const ( 24 VarlenaInlineSize = 23 25 VarlenaSize = 24 26 MaxStringSize = 10485760 27 VarlenaBigHdr = 0xffffffff 28 MaxVarcharLen = 65535 29 MaxCharLen = 255 30 ) 31 32 func (v *Varlena) UnsafePtr() unsafe.Pointer { 33 return unsafe.Pointer(&v[0]) 34 } 35 36 func (v *Varlena) ByteSlice() []byte { 37 svlen := (*v)[0] 38 ptr := unsafe.Add(unsafe.Pointer(&v[0]), 1) 39 return unsafe.Slice((*byte)(ptr), svlen) 40 } 41 42 func (v *Varlena) U32Slice() []uint32 { 43 ptr := (*uint32)(v.UnsafePtr()) 44 return unsafe.Slice(ptr, 6) 45 } 46 47 func (v *Varlena) OffsetLen() (uint32, uint32) { 48 s := v.U32Slice() 49 return s[1], s[2] 50 } 51 func (v *Varlena) SetOffsetLen(voff, vlen uint32) { 52 s := v.U32Slice() 53 s[0] = VarlenaBigHdr 54 s[1] = voff 55 s[2] = vlen 56 } 57 58 func BuildVarlena(bs []byte, area []byte, m *mpool.MPool) (Varlena, []byte, error) { 59 var err error 60 var v Varlena 61 vlen := len(bs) 62 if vlen <= VarlenaInlineSize { 63 v[0] = byte(vlen) 64 copy(v[1:1+vlen], bs) 65 return v, area, nil 66 } else { 67 voff := len(area) 68 if voff+vlen < cap(area) || m == nil { 69 area = append(area, bs...) 70 } else { 71 area, err = m.Grow2(area, bs, voff+vlen) 72 if err != nil { 73 return v, nil, err 74 } 75 } 76 v.SetOffsetLen(uint32(voff), uint32(vlen)) 77 return v, area, nil 78 } 79 } 80 81 func (v *Varlena) IsSmall() bool { 82 return (*v)[0] <= VarlenaInlineSize 83 } 84 85 // For short slice, this one will return a slice stored internal 86 // in the varlena. Caller must ensure that v has a longer life 87 // span than the returned byte slice. 88 // 89 // Main user of Varlena is vector. v that comes from vector.Data 90 // will be fine. 91 func (v *Varlena) GetByteSlice(area []byte) []byte { 92 svlen := (*v)[0] 93 if svlen <= VarlenaInlineSize { 94 return v.ByteSlice() 95 } 96 voff, vlen := v.OffsetLen() 97 return area[voff : voff+vlen] 98 } 99 100 // See the lifespan comment above. 101 func (v *Varlena) GetString(area []byte) string { 102 return string(v.GetByteSlice(area)) 103 } 104 105 func (v *Varlena) Reset() { 106 var vzero Varlena 107 *v = vzero 108 }