github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/stl/bytes.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 stl 16 17 import ( 18 "unsafe" 19 20 "github.com/matrixorigin/matrixone/pkg/container/types" 21 ) 22 23 func NewFixedTypeBytes[T any]() *Bytes { 24 return NewBytesWithTypeSize(Sizeof[T]()) 25 } 26 27 func NewBytesWithTypeSize(sz int) *Bytes { 28 return &Bytes{ 29 TypeSize: sz, 30 } 31 } 32 33 func (bs *Bytes) IsFixedType() bool { return bs.TypeSize > 0 } 34 func (bs *Bytes) IsWindow() bool { return bs.AsWindow } 35 36 func (bs *Bytes) ToWindow(offset, length int) { 37 bs.AsWindow = true 38 bs.WinOffset = offset 39 bs.WinLength = length 40 } 41 42 func (bs *Bytes) Size() int { 43 return bs.StorageSize() + bs.HeaderSize() 44 } 45 46 func (bs *Bytes) Length() int { 47 if bs.IsFixedType() { 48 return len(bs.Storage) / bs.TypeSize 49 } 50 return len(bs.Header) 51 } 52 53 func (bs *Bytes) StorageSize() int { 54 return len(bs.Storage) 55 } 56 57 func (bs *Bytes) StorageBuf() []byte { 58 return bs.Storage 59 } 60 61 func (bs *Bytes) HeaderSize() int { 62 return len(bs.Header) * types.VarlenaSize 63 } 64 65 func (bs *Bytes) getStart(offset int) int { 66 if !bs.IsWindow() { 67 return offset 68 } 69 return offset + bs.WinOffset 70 } 71 func (bs *Bytes) HeaderBuf() (buf []byte) { 72 if len(bs.Header) == 0 { 73 return 74 } 75 buf = unsafe.Slice((*byte)(unsafe.Pointer(&bs.Header[0])), bs.HeaderSize()) 76 return 77 } 78 79 func (bs *Bytes) SetHeaderBuf(buf []byte) { 80 if len(buf) == 0 { 81 return 82 } 83 bs.Header = unsafe.Slice((*types.Varlena)(unsafe.Pointer(&buf[0])), len(buf)/Sizeof[types.Varlena]()) 84 } 85 86 func (bs *Bytes) SetStorageBuf(buf []byte) { 87 bs.Storage = buf 88 } 89 90 func (bs *Bytes) GetVarValueAt(i int) []byte { 91 pos := bs.getStart(i) 92 val := bs.Header[pos] 93 if val.IsSmall() { 94 return val.ByteSlice() 95 } 96 offset, length := val.OffsetLen() 97 return bs.Storage[offset : offset+length] 98 } 99 100 func (bs *Bytes) Window(offset, length int) *Bytes { 101 if bs.IsFixedType() { 102 return bs.fixSizeWindow(offset, length) 103 } 104 nbs := NewBytesWithTypeSize(bs.TypeSize) 105 nbs.AsWindow = true 106 nbs.Storage = bs.Storage 107 nbs.Header = bs.Header 108 if bs.IsWindow() { 109 nbs.WinOffset += offset 110 nbs.WinLength = length 111 } else { 112 nbs.WinOffset = offset 113 nbs.WinLength = length 114 } 115 116 return nbs 117 } 118 119 func (bs *Bytes) fixSizeWindow(offset, length int) *Bytes { 120 nbs := NewBytesWithTypeSize(bs.TypeSize) 121 nbs.Storage = bs.Storage[offset*bs.TypeSize : (offset+length)*bs.TypeSize] 122 return nbs 123 }