github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/tables/indexwrapper/zonemapnode.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  	"fmt"
    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/objectio"
    24  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/buffer/base"
    25  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common"
    26  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/containers"
    27  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/index"
    28  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/tables/evictable"
    29  )
    30  
    31  type ZmReader struct {
    32  	metaKey        string
    33  	mgr            base.INodeManager
    34  	colMetaFactory evictable.EvictableNodeFactory
    35  }
    36  
    37  func newZmReader(mgr base.INodeManager, typ types.Type, id common.ID, fs *objectio.ObjectFS, idx uint16, metaloc string) *ZmReader {
    38  	metaKey := evictable.EncodeColMetaKey(id.Idx, metaloc)
    39  	return &ZmReader{
    40  		metaKey: metaKey,
    41  		mgr:     mgr,
    42  		colMetaFactory: func() (base.INode, error) {
    43  			return evictable.NewColumnMetaNode(
    44  				idx,
    45  				typ,
    46  				metaloc,
    47  				metaKey,
    48  				mgr,
    49  				fs), nil
    50  		},
    51  	}
    52  }
    53  
    54  func (r *ZmReader) Contains(key any) bool {
    55  	// TODOa: new zmreader if metaloc changed, replayIndex is not right?
    56  	h, err := evictable.PinEvictableNode(r.mgr, r.metaKey, r.colMetaFactory)
    57  	if err != nil {
    58  		// TODOa: Error Handling?
    59  		return false
    60  	}
    61  	defer h.Close()
    62  	node := h.GetNode().(*evictable.ColumnMetaNode)
    63  	return node.Zonemap.Contains(key)
    64  }
    65  
    66  func (r *ZmReader) FastContainsAny(keys containers.Vector) (ok bool) {
    67  	h, err := evictable.PinEvictableNode(r.mgr, r.metaKey, r.colMetaFactory)
    68  	if err != nil {
    69  		return
    70  	}
    71  	defer h.Close()
    72  	node := h.GetNode().(*evictable.ColumnMetaNode)
    73  	return node.Zonemap.FastContainsAny(keys)
    74  }
    75  
    76  func (r *ZmReader) ContainsAny(keys containers.Vector) (visibility *roaring.Bitmap, ok bool) {
    77  	h, err := evictable.PinEvictableNode(r.mgr, r.metaKey, r.colMetaFactory)
    78  	if err != nil {
    79  		return
    80  	}
    81  	defer h.Close()
    82  	node := h.GetNode().(*evictable.ColumnMetaNode)
    83  	return node.Zonemap.ContainsAny(keys)
    84  }
    85  
    86  func (r *ZmReader) Destroy() error { return nil }
    87  
    88  type ZMWriter struct {
    89  	cType       common.CompressType
    90  	writer      objectio.Writer
    91  	block       objectio.BlockObject
    92  	zonemap     *index.ZoneMap
    93  	colIdx      uint16
    94  	internalIdx uint16
    95  }
    96  
    97  func NewZMWriter() *ZMWriter {
    98  	return &ZMWriter{}
    99  }
   100  
   101  func (writer *ZMWriter) String() string {
   102  	return fmt.Sprintf("ZmWriter[Cid-%d,%s]", writer.colIdx, writer.zonemap.String())
   103  }
   104  
   105  func (writer *ZMWriter) Init(wr objectio.Writer, block objectio.BlockObject, cType common.CompressType, colIdx uint16, internalIdx uint16) error {
   106  	writer.writer = wr
   107  	writer.block = block
   108  	writer.cType = cType
   109  	writer.colIdx = colIdx
   110  	writer.internalIdx = internalIdx
   111  	return nil
   112  }
   113  
   114  func (writer *ZMWriter) Finalize() (*IndexMeta, error) {
   115  	if writer.zonemap == nil {
   116  		panic("unexpected error")
   117  	}
   118  	appender := writer.writer
   119  	meta := NewEmptyIndexMeta()
   120  	meta.SetIndexType(BlockZoneMapIndex)
   121  	meta.SetCompressType(writer.cType)
   122  	meta.SetIndexedColumn(writer.colIdx)
   123  	meta.SetInternalIndex(writer.internalIdx)
   124  
   125  	//var startOffset uint32
   126  	iBuf, err := writer.zonemap.Marshal()
   127  	if err != nil {
   128  		return nil, err
   129  	}
   130  	zonemap, err := objectio.NewZoneMap(writer.colIdx, iBuf)
   131  	if err != nil {
   132  		return nil, err
   133  	}
   134  	rawSize := uint32(len(iBuf))
   135  	compressed := common.Compress(iBuf, writer.cType)
   136  	exactSize := uint32(len(compressed))
   137  	meta.SetSize(rawSize, exactSize)
   138  	err = appender.WriteIndex(writer.block, zonemap)
   139  	if err != nil {
   140  		return nil, err
   141  	}
   142  	//meta.SetStartOffset(startOffset)
   143  	return meta, nil
   144  }
   145  
   146  func (writer *ZMWriter) AddValues(values containers.Vector) (err error) {
   147  	typ := values.GetType()
   148  	if writer.zonemap == nil {
   149  		writer.zonemap = index.NewZoneMap(typ)
   150  	} else {
   151  		if writer.zonemap.GetType() != typ {
   152  			err = moerr.NewInternalErrorNoCtx("wrong type")
   153  			return
   154  		}
   155  	}
   156  	ctx := new(index.KeysCtx)
   157  	ctx.Keys = values
   158  	ctx.Count = values.Length()
   159  	err = writer.zonemap.BatchUpdate(ctx)
   160  	return
   161  }
   162  
   163  func (writer *ZMWriter) SetMinMax(min, max any, typ types.Type) (err error) {
   164  	if writer.zonemap == nil {
   165  		writer.zonemap = index.NewZoneMap(typ)
   166  	} else {
   167  		if writer.zonemap.GetType() != typ {
   168  			err = moerr.NewInternalErrorNoCtx("wrong type")
   169  			return
   170  		}
   171  	}
   172  	writer.zonemap.SetMin(min)
   173  	writer.zonemap.SetMax(max)
   174  	return
   175  }