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  }