github.com/matrixorigin/matrixone@v1.2.0/pkg/vm/engine/tae/index/indexwrapper/mutindex.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 indexwrapper 16 17 import ( 18 "context" 19 20 "github.com/RoaringBitmap/roaring" 21 "github.com/matrixorigin/matrixone/pkg/common/moerr" 22 "github.com/matrixorigin/matrixone/pkg/container/types" 23 "github.com/matrixorigin/matrixone/pkg/container/vector" 24 "github.com/matrixorigin/matrixone/pkg/objectio" 25 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/containers" 26 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/index" 27 ) 28 29 type MutIndex struct { 30 art index.SecondaryIndex 31 zonemap index.ZM 32 } 33 34 func NewMutIndex(typ types.Type) *MutIndex { 35 return &MutIndex{ 36 art: index.NewSimpleARTMap(), 37 zonemap: index.NewZM(typ.Oid, typ.Scale), 38 } 39 } 40 41 // BatchUpsert batch insert the specific keys 42 // If any deduplication, it will fetch the old value first, fill the active map with new value, insert the old value into delete map 43 // If any other unknown error hanppens, return error 44 func (idx *MutIndex) BatchUpsert( 45 keys *vector.Vector, 46 offset int, 47 ) (err error) { 48 defer func() { 49 err = TranslateError(err) 50 }() 51 if err = index.BatchUpdateZM(idx.zonemap, keys); err != nil { 52 return 53 } 54 // logutil.Infof("Pre: %s", idx.art.String()) 55 err = idx.art.BatchInsert(keys, 0, keys.Length(), uint32(offset)) 56 // logutil.Infof("Post: %s", idx.art.String()) 57 return 58 } 59 60 func (idx *MutIndex) GetActiveRow(key any) (row []uint32, err error) { 61 defer func() { 62 err = TranslateError(err) 63 // logutil.Infof("[Trace][GetActiveRow] key=%v: err=%v", key, err) 64 }() 65 exist := idx.zonemap.Contains(key) 66 // 1. key is definitely not existed 67 if !exist { 68 err = moerr.NewNotFoundNoCtx() 69 return 70 } 71 // 2. search art tree for key 72 ikey := types.EncodeValue(key, idx.zonemap.GetType()) 73 row, err = idx.art.Search(ikey) 74 err = TranslateError(err) 75 return 76 } 77 78 func (idx *MutIndex) String() string { 79 return idx.art.String() 80 } 81 82 // Dedup returns wether the specified key is existed 83 // If key is existed, return ErrDuplicate 84 // If any other unknown error happens, return error 85 // If key is not found, return nil 86 func (idx *MutIndex) Dedup(ctx context.Context, key any, skipfn func(row uint32) (err error)) (err error) { 87 exist := idx.zonemap.Contains(key) 88 if !exist { 89 return 90 } 91 ikey := types.EncodeValue(key, idx.zonemap.GetType()) 92 rows, err := idx.art.Search(ikey) 93 if err == index.ErrNotFound { 94 err = nil 95 return 96 } 97 for _, row := range rows { 98 if err = skipfn(row); err != nil { 99 return 100 } 101 } 102 return 103 } 104 105 func (idx *MutIndex) BatchDedup( 106 ctx context.Context, 107 keys *vector.Vector, 108 keysZM index.ZM, 109 skipfn func(row uint32) (err error), 110 _ objectio.BloomFilter, 111 ) (keyselects *roaring.Bitmap, err error) { 112 if keysZM.Valid() { 113 if exist := idx.zonemap.FastIntersect(keysZM); !exist { 114 return 115 } 116 } else { 117 // 1. all keys are definitely not existed 118 if exist := idx.zonemap.FastContainsAny(keys); !exist { 119 return 120 } 121 } 122 op := func(v []byte, _ bool, _ int) error { 123 rows, err := idx.art.Search(v) 124 if err == index.ErrNotFound { 125 return nil 126 } 127 for _, row := range rows { 128 if err = skipfn(row); err != nil { 129 return err 130 } 131 } 132 return nil 133 } 134 if err = containers.ForeachWindowBytes(keys, 0, keys.Length(), op, nil); err != nil { 135 if moerr.IsMoErrCode(err, moerr.OkExpectedDup) || moerr.IsMoErrCode(err, moerr.ErrTxnWWConflict) { 136 return 137 } else { 138 panic(err) 139 } 140 } 141 return 142 } 143 144 func (idx *MutIndex) Close() error { 145 idx.art = nil 146 idx.zonemap = nil 147 return nil 148 }