github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/tables/handle.go (about)

     1  // Copyright 2021 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 tables
    16  
    17  import (
    18  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/catalog"
    19  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common"
    20  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/data"
    21  )
    22  
    23  type tableHandle struct {
    24  	table    *dataTable
    25  	block    *ablock
    26  	appender data.BlockAppender
    27  }
    28  
    29  func newHandle(table *dataTable, block *ablock) *tableHandle {
    30  	h := &tableHandle{
    31  		table: table,
    32  		block: block,
    33  	}
    34  	if block != nil {
    35  		h.appender, _ = block.MakeAppender()
    36  	}
    37  	return h
    38  }
    39  
    40  func (h *tableHandle) SetAppender(id *common.ID) (appender data.BlockAppender) {
    41  	tableMeta := h.table.meta
    42  	segMeta, _ := tableMeta.GetSegmentByID(id.SegmentID)
    43  	blkMeta, _ := segMeta.GetBlockEntryByID(id.BlockID)
    44  	h.block = blkMeta.GetBlockData().(*ablock)
    45  	h.appender, _ = h.block.MakeAppender()
    46  	h.block.Ref()
    47  	return h.appender
    48  }
    49  
    50  func (h *tableHandle) ThrowAppenderAndErr() (appender data.BlockAppender, err error) {
    51  	id := h.appender.GetID()
    52  	segEntry, _ := h.table.meta.GetSegmentByID(id.SegmentID)
    53  	if segEntry == nil ||
    54  		segEntry.GetAppendableBlockCnt() >= int(segEntry.GetTable().GetSchema().SegmentMaxBlocks) {
    55  		err = data.ErrAppendableSegmentNotFound
    56  	} else {
    57  		err = data.ErrAppendableBlockNotFound
    58  		appender = h.appender
    59  	}
    60  	h.block = nil
    61  	h.appender = nil
    62  	return
    63  }
    64  
    65  func (h *tableHandle) GetAppender() (appender data.BlockAppender, err error) {
    66  	var segEntry *catalog.SegmentEntry
    67  	if h.appender == nil {
    68  		segEntry = h.table.meta.LastAppendableSegmemt()
    69  		if segEntry == nil {
    70  			err = data.ErrAppendableSegmentNotFound
    71  			return
    72  		}
    73  		blkEntry := segEntry.LastAppendableBlock()
    74  		if blkEntry == nil {
    75  			err = data.ErrAppendableSegmentNotFound
    76  			return
    77  		}
    78  		h.block = blkEntry.GetBlockData().(*ablock)
    79  		h.appender, err = h.block.MakeAppender()
    80  		if err != nil {
    81  			panic(err)
    82  		}
    83  	}
    84  	dropped := h.block.meta.HasDropCommitted()
    85  	if !h.appender.IsAppendable() || !h.block.IsAppendable() || dropped {
    86  		return h.ThrowAppenderAndErr()
    87  	}
    88  	h.block.Ref()
    89  	// Similar to optimistic locking
    90  	dropped = h.block.meta.HasDropCommitted()
    91  	if !h.appender.IsAppendable() || !h.block.IsAppendable() || dropped {
    92  		h.block.Unref()
    93  		return h.ThrowAppenderAndErr()
    94  	}
    95  	appender = h.appender
    96  	return
    97  }