tidb memid 源码
tidb memid 代码
文件路径:/meta/autoid/memid.go
// Copyright 2021 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package autoid
import (
"context"
"math"
"github.com/pingcap/tidb/parser/model"
)
// NewAllocatorFromTempTblInfo creates an in-memory allocator from a temporary table info.
func NewAllocatorFromTempTblInfo(tblInfo *model.TableInfo) Allocator {
hasRowID := !tblInfo.PKIsHandle && !tblInfo.IsCommonHandle
hasAutoIncID := tblInfo.GetAutoIncrementColInfo() != nil
var alloc Allocator
// Temporary tables don't support auto_random and sequence.
if hasRowID || hasAutoIncID {
alloc = &inMemoryAllocator{
isUnsigned: tblInfo.IsAutoIncColUnsigned(),
allocType: RowIDAllocType,
}
}
// Rebase the allocator if the base is specified.
if alloc != nil && tblInfo.AutoIncID > 1 {
// Actually, `inMemoryAllocator.Rebase` always returns nil.
if err := alloc.Rebase(context.Background(), tblInfo.AutoIncID-1, false); err != nil {
return nil
}
}
return alloc
}
// inMemoryAllocator is typically used for temporary tables.
// Some characteristics:
// - It allocates IDs from memory.
// - It's session-wide and thus won't be visited concurrently.
// - It doesn't support sequence.
// - The metrics are not reported.
type inMemoryAllocator struct {
base int64
isUnsigned bool
allocType AllocatorType
}
// Base implements autoid.Allocator Base interface.
func (alloc *inMemoryAllocator) Base() int64 {
return alloc.base
}
// End implements autoid.Allocator End interface.
func (*inMemoryAllocator) End() int64 {
// It doesn't matter.
return 0
}
// GetType implements autoid.Allocator GetType interface.
func (alloc *inMemoryAllocator) GetType() AllocatorType {
return alloc.allocType
}
// NextGlobalAutoID implements autoid.Allocator NextGlobalAutoID interface.
func (alloc *inMemoryAllocator) NextGlobalAutoID() (int64, error) {
if alloc.isUnsigned {
return int64(uint64(alloc.base) + 1), nil
}
return alloc.base + 1, nil
}
func (alloc *inMemoryAllocator) Alloc(_ context.Context, n uint64, increment, offset int64) (min int64, max int64, err error) {
if n == 0 {
return 0, 0, nil
}
if alloc.allocType == AutoIncrementType || alloc.allocType == RowIDAllocType {
if !validIncrementAndOffset(increment, offset) {
return 0, 0, errInvalidIncrementAndOffset.GenWithStackByArgs(increment, offset)
}
}
if alloc.isUnsigned {
return alloc.alloc4Unsigned(n, increment, offset)
}
return alloc.alloc4Signed(n, increment, offset)
}
// Rebase implements autoid.Allocator Rebase interface.
// The requiredBase is the minimum base value after Rebase.
// The real base may be greater than the required base.
func (alloc *inMemoryAllocator) Rebase(_ context.Context, requiredBase int64, _ bool) error {
if alloc.isUnsigned {
if uint64(requiredBase) > uint64(alloc.base) {
alloc.base = requiredBase
}
} else {
if requiredBase > alloc.base {
alloc.base = requiredBase
}
}
return nil
}
// ForceRebase implements autoid.Allocator ForceRebase interface.
func (alloc *inMemoryAllocator) ForceRebase(requiredBase int64) error {
alloc.base = requiredBase
return nil
}
func (alloc *inMemoryAllocator) alloc4Signed(n uint64, increment, offset int64) (min int64, max int64, err error) {
// Check offset rebase if necessary.
if offset-1 > alloc.base {
alloc.base = offset - 1
}
// CalcNeededBatchSize calculates the total batch size needed.
n1 := CalcNeededBatchSize(alloc.base, int64(n), increment, offset, alloc.isUnsigned)
// Condition alloc.base+N1 > alloc.end will overflow when alloc.base + N1 > MaxInt64. So need this.
if math.MaxInt64-alloc.base <= n1 {
return 0, 0, ErrAutoincReadFailed
}
min = alloc.base
alloc.base += n1
return min, alloc.base, nil
}
func (alloc *inMemoryAllocator) alloc4Unsigned(n uint64, increment, offset int64) (min int64, max int64, err error) {
// Check offset rebase if necessary.
if uint64(offset)-1 > uint64(alloc.base) {
alloc.base = int64(uint64(offset) - 1)
}
// CalcNeededBatchSize calculates the total batch size needed.
n1 := CalcNeededBatchSize(alloc.base, int64(n), increment, offset, alloc.isUnsigned)
// Condition alloc.base+n1 > alloc.end will overflow when alloc.base + n1 > MaxInt64. So need this.
if math.MaxUint64-uint64(alloc.base) <= uint64(n1) {
return 0, 0, ErrAutoincReadFailed
}
min = alloc.base
// Use uint64 n directly.
alloc.base = int64(uint64(alloc.base) + uint64(n1))
return min, alloc.base, nil
}
func (*inMemoryAllocator) AllocSeqCache() (base int64, end int64, round int64, err error) {
return 0, 0, 0, errNotImplemented.GenWithStackByArgs()
}
func (*inMemoryAllocator) RebaseSeq(_ int64) (res int64, alreadySatisfied bool, err error) {
return 0, false, errNotImplemented.GenWithStackByArgs()
}
相关信息
相关文章
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦