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  }