diff --git a/server/core/tablecodec.go b/server/core/tablecodec.go new file mode 100644 index 00000000000..98ee4621f85 --- /dev/null +++ b/server/core/tablecodec.go @@ -0,0 +1,59 @@ +// Copyright 2016 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, +// See the License for the specific language governing permissions and +// limitations under the License. + +package core + +import ( + "bytes" + "encoding/binary" + "github.com/juju/errors" +) + +var tablePrefix = []byte{'t'} + +const signMask uint64 = 0x8000000000000000 + +// Key represents high-level Key type. +type Key []byte + +// HasPrefix tests whether the Key begins with prefix. +func (k Key) HasPrefix(prefix Key) bool { + return bytes.HasPrefix(k, prefix) +} + +// DecodeTableID decodes the table ID of the key, if the key is not table key, returns 0. +func DecodeTableID(key Key) int64 { + if !key.HasPrefix(tablePrefix) { + return 0 + } + key = key[len(tablePrefix):] + _, tableID, _ := DecodeInt(key) + return tableID +} + +// DecodeInt decodes value encoded by EncodeInt before. +// It returns the leftover un-decoded slice, decoded value if no error. +func DecodeInt(b []byte) ([]byte, int64, error) { + if len(b) < 8 { + return nil, 0, errors.New("insufficient bytes to decode value") + } + + u := binary.BigEndian.Uint64(b[:8]) + v := decodeCmpUintToInt(u) + b = b[8:] + return b, v, nil +} + +func decodeCmpUintToInt(u uint64) int64 { + return int64(u ^ signMask) +} diff --git a/server/tableNamespaceClassifier.go b/server/tableNamespaceClassifier.go new file mode 100644 index 00000000000..40a1907094f --- /dev/null +++ b/server/tableNamespaceClassifier.go @@ -0,0 +1,46 @@ +package server + +import ( + "github.com/pingcap/pd/server/core" + "github.com/pingcap/pd/server/namespace" +) + +type tableNamespaceClassifier struct { + nsInfo *namespacesInfo +} + +func newTableNamespaceClassifier(nsInfo *namespacesInfo) tableNamespaceClassifier { + return tableNamespaceClassifier{ + nsInfo, + } +} + +func (classifier tableNamespaceClassifier) GetAllNamespaces() []string { + nsList := make([]string, len(classifier.nsInfo.namespaces)) + for name := range classifier.nsInfo.namespaces { + nsList = append(nsList, name) + } + return nsList +} + +func (classifier tableNamespaceClassifier) GetStoreNamespace(storeInfo *core.StoreInfo) string { + for name, ns := range classifier.nsInfo.namespaces { + if storeInfo.Id == ns.ID { + return name + } + } + return namespace.DefaultNamespace +} + +func (classifier tableNamespaceClassifier) GetRegionNamespace(regionInfo *core.RegionInfo) string { + for name, ns := range classifier.nsInfo.namespaces { + startTable := core.DecodeTableID(regionInfo.StartKey) + endTable := core.DecodeTableID(regionInfo.EndKey) + for _, tableID := range ns.TableIDs { + if tableID == startTable && tableID == endTable { + return name + } + } + } + return namespace.DefaultNamespace +}