github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/stl/containers/strvec.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 containers 16 17 import ( 18 "fmt" 19 "io" 20 "unsafe" 21 22 "github.com/matrixorigin/matrixone/pkg/common/mpool" 23 "github.com/matrixorigin/matrixone/pkg/container/types" 24 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common" 25 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/stl" 26 ) 27 28 func NewStrVector[T any](opts ...Options) *StrVector[T] { 29 var capacity int 30 var alloc *mpool.MPool 31 vdataOpt := Options{} 32 areaOpt := Options{} 33 if len(opts) > 0 { 34 opt := opts[0] 35 capacity = opt.Capacity 36 alloc = opt.Allocator 37 if opt.HasData() { 38 if opt.Data.HeaderSize() > 0 { 39 vdataOpt.Data = stl.NewFixedTypeBytes[types.Varlena]() 40 vdataOpt.Data.Storage = opt.Data.HeaderBuf() 41 vdataOpt.Capacity = opt.Data.Length() 42 } 43 if opt.Data.StorageSize() > 0 { 44 vdataOpt.Data = stl.NewFixedTypeBytes[byte]() 45 areaOpt.Data.Storage = opt.Data.StorageBuf() 46 areaOpt.Capacity = opt.Data.StorageSize() 47 } 48 } 49 } 50 if alloc == nil { 51 alloc = common.DefaultAllocator 52 } 53 if vdataOpt.Capacity < capacity { 54 vdataOpt.Capacity = capacity 55 } 56 vdataOpt.Allocator = alloc 57 areaOpt.Allocator = alloc 58 59 vdata := NewStdVector[types.Varlena](vdataOpt) 60 area := NewStdVector[byte](areaOpt) 61 return &StrVector[T]{ 62 area: area, 63 vdata: vdata, 64 } 65 } 66 67 func (vec *StrVector[T]) Close() { 68 if vec.vdata != nil { 69 vec.vdata.Close() 70 } 71 if vec.area != nil { 72 vec.area.Close() 73 } 74 } 75 76 func (vec *StrVector[T]) GetAllocator() *mpool.MPool { 77 return vec.vdata.GetAllocator() 78 } 79 80 func (vec *StrVector[T]) Length() int { return vec.vdata.Length() } 81 func (vec *StrVector[T]) Capacity() int { return vec.vdata.Capacity() } 82 func (vec *StrVector[T]) Allocated() int { 83 size := vec.vdata.Allocated() 84 size += vec.area.Allocated() 85 return size 86 } 87 func (vec *StrVector[T]) IsView() bool { return false } 88 func (vec *StrVector[T]) Data() []byte { panic("not support") } 89 func (vec *StrVector[T]) DataWindow(offset, length int) []byte { panic("not support") } 90 func (vec *StrVector[T]) Bytes() *stl.Bytes { 91 bs := stl.NewBytesWithTypeSize(-types.VarlenaSize) 92 bs.Header = vec.vdata.Slice() 93 bs.Storage = vec.area.Slice() 94 95 return bs 96 } 97 func (vec *StrVector[T]) SlicePtr() unsafe.Pointer { panic("not support") } 98 func (vec *StrVector[T]) Slice() []T { panic("not support") } 99 func (vec *StrVector[T]) SliceWindow(_, _ int) []T { panic("not support") } 100 func (vec *StrVector[T]) WindowAsBytes(offset, length int) *stl.Bytes { 101 bs := vec.Bytes() 102 if offset == 0 && length == vec.vdata.Length() { 103 return bs 104 } 105 bs.ToWindow(offset, length) 106 return bs 107 } 108 func (vec *StrVector[T]) Desc() string { 109 s := fmt.Sprintf("StrVector:Len=%d[Rows];Cap=%d[Rows];Allocted:%d[Bytes]", 110 vec.Length(), 111 vec.Capacity(), 112 vec.Allocated()) 113 return s 114 } 115 func (vec *StrVector[T]) String() string { 116 s := vec.Desc() 117 end := 100 118 if vec.Length() < end { 119 end = vec.Length() 120 } 121 if end == 0 { 122 return s 123 } 124 data := "" 125 for i := 0; i < end; i++ { 126 data = fmt.Sprintf("%s %v", data, vec.Get(i)) 127 } 128 s = fmt.Sprintf("%s %s", s, data) 129 return s 130 } 131 132 func (vec *StrVector[T]) Append(v T) { 133 var vv types.Varlena 134 val := any(v).([]byte) 135 length := len(val) 136 137 // If the length of the data is not larger than types.VarlenaInlineSize, store the 138 // data in vec.vdata 139 if length <= types.VarlenaInlineSize { 140 vv[0] = byte(length) 141 copy(vv[1:1+length], val) 142 vec.vdata.Append(vv) 143 return 144 } 145 146 // If the length of the data is larger than types.VarlenaInlineSize, store the 147 // offset and length in vec.vdata and store the data in vec.area 148 vv.SetOffsetLen(uint32(vec.area.Length()), uint32(length)) 149 vec.vdata.Append(vv) 150 vec.area.AppendMany(val...) 151 } 152 153 func (vec *StrVector[T]) Update(i int, v T) { 154 val := any(v).([]byte) 155 length := len(val) 156 var vv types.Varlena 157 if length <= types.VarlenaInlineSize { 158 vv[0] = byte(length) 159 copy(vv[1:1+length], val) 160 vec.vdata.Update(i, vv) 161 return 162 } 163 vv.SetOffsetLen(uint32(vec.area.Length()), uint32(length)) 164 vec.vdata.Update(i, vv) 165 vec.area.AppendMany(val...) 166 } 167 168 func (vec *StrVector[T]) Get(i int) T { 169 v := vec.vdata.Get(i) 170 if v.IsSmall() { 171 return any(v.ByteSlice()).(T) 172 } 173 vOff, vLen := v.OffsetLen() 174 return any(vec.area.Slice()[vOff : vOff+vLen]).(T) 175 } 176 177 func (vec *StrVector[T]) Delete(i int) (deleted T) { 178 deleted = vec.Get(i) 179 vec.BatchDeleteInts(i) 180 return 181 } 182 183 func (vec *StrVector[T]) BatchDelete(rowGen common.RowGen, cnt int) { 184 vec.vdata.BatchDelete(rowGen, cnt) 185 } 186 func (vec *StrVector[T]) BatchDeleteUint32s(sels ...uint32) { 187 vec.vdata.BatchDeleteUint32s(sels...) 188 } 189 func (vec *StrVector[T]) BatchDeleteInts(sels ...int) { 190 vec.vdata.BatchDeleteInts(sels...) 191 } 192 193 func (vec *StrVector[T]) AppendMany(vals ...T) { 194 for _, val := range vals { 195 vec.Append(val) 196 } 197 } 198 199 func (vec *StrVector[T]) Clone(offset, length int, allocator ...*mpool.MPool) stl.Vector[T] { 200 opts := Options{ 201 Capacity: length, 202 } 203 if len(allocator) == 0 { 204 opts.Allocator = vec.GetAllocator() 205 } else { 206 opts.Allocator = allocator[0] 207 } 208 cloned := NewStrVector[T](opts) 209 210 if offset == 0 && length == vec.Length() { 211 cloned.vdata.AppendMany(vec.vdata.Slice()...) 212 cloned.area.AppendMany(vec.area.Slice()...) 213 } else { 214 for i := offset; i < offset+length; i++ { 215 cloned.Append(vec.Get(i)) 216 } 217 } 218 return cloned 219 } 220 221 func (vec *StrVector[T]) Reset() { 222 vec.vdata.Reset() 223 if vec.area != nil { 224 vec.area.Reset() 225 } 226 } 227 228 func (vec *StrVector[T]) ReadBytes(data *stl.Bytes, share bool) { 229 if data == nil { 230 return 231 } 232 d1 := stl.NewFixedTypeBytes[types.Varlena]() 233 d1.Storage = data.HeaderBuf() 234 vec.vdata.ReadBytes(d1, share) 235 236 d2 := stl.NewFixedTypeBytes[byte]() 237 d2.Storage = data.StorageBuf() 238 vec.area.ReadBytes(d2, share) 239 } 240 241 func (vec *StrVector[T]) InitFromSharedBuf(buf []byte) (n int64, err error) { 242 var nr int64 243 if nr, err = vec.vdata.InitFromSharedBuf(buf); err != nil { 244 return 245 } 246 n += nr 247 buf = buf[nr:] 248 if nr, err = vec.area.InitFromSharedBuf(buf); err != nil { 249 return 250 } 251 n += nr 252 return 253 } 254 255 func (vec *StrVector[T]) ReadFrom(r io.Reader) (n int64, err error) { 256 var nr int64 257 if nr, err = vec.vdata.ReadFrom(r); err != nil { 258 return 259 } 260 n += nr 261 if nr, err = vec.area.ReadFrom(r); err != nil { 262 return 263 } 264 n += nr 265 return 266 } 267 268 func (vec *StrVector[T]) WriteTo(w io.Writer) (n int64, err error) { 269 var nr int64 270 if nr, err = vec.vdata.WriteTo(w); err != nil { 271 return 272 } 273 n += nr 274 if nr, err = vec.area.WriteTo(w); err != nil { 275 return 276 } 277 n += nr 278 return 279 } 280 281 func (vec *StrVector[T]) getAreaRange(offset, length int) (min, max int) { 282 var pos int 283 slice := vec.vdata.Slice() 284 end := offset + length 285 for pos = offset; pos < end; pos++ { 286 if slice[pos].IsSmall() { 287 continue 288 } 289 min32, _ := slice[pos].OffsetLen() 290 min = int(min32) 291 break 292 } 293 // no data stored in area 294 if pos == end { 295 return 296 } 297 minPos := pos 298 for pos = end - 1; pos >= minPos; pos-- { 299 if slice[pos].IsSmall() { 300 continue 301 } 302 max32, maxLen := slice[pos].OffsetLen() 303 max = int(max32 + maxLen) 304 break 305 } 306 return 307 }