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 }