Skip to content

Commit

Permalink
Use map for tableIDs and storeIDs in namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
ming535 committed Sep 20, 2017
1 parent b87db27 commit fb96f63
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 59 deletions.
2 changes: 1 addition & 1 deletion server/api/namespace.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func (h *namespaceHandler) Append(w http.ResponseWriter, r *http.Request) {
ns := input["namespace"]

// append table id to namespace
if err := cluster.AppendNamespaceTableID(ns, tableID); err != nil {
if err := cluster.AddNamespaceTableID(ns, tableID); err != nil {
h.rd.JSON(w, http.StatusInternalServerError, err.Error())
return
}
Expand Down
2 changes: 1 addition & 1 deletion server/api/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ func (h *storeHandler) SetNamespace(w http.ResponseWriter, r *http.Request) {
ns := input["namespace"]

// append store id to namespace
if err := cluster.AppendNamespaceStoreID(ns, storeID); err != nil {
if err := cluster.AddNamespaceStoreID(ns, storeID); err != nil {
h.rd.JSON(w, http.StatusInternalServerError, err.Error())
return
}
Expand Down
30 changes: 13 additions & 17 deletions server/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -654,59 +654,55 @@ func (c *RaftCluster) CreateNamespace(name string) error {
r := regexp.MustCompile(`^\w+$`)
matched := r.MatchString(name)
if !matched {
return errors.New("name should be 0-9, a-z or A-Z")
return errors.New("Name should be 0-9, a-z or A-Z")
}

cachedCluster := c.cachedCluster
if _, ok := cachedCluster.namespacesInfo.namespaces[name]; ok {
return errors.New("Duplicate namespace name")
return errors.New("Duplicate namespace Name")
}

id, err := c.s.idAlloc.Alloc()
if err != nil {
return errors.Trace(err)
}

ns := &Namespace{
ID: id,
Name: name,
}

ns := NewNamespace(id, name)
return cachedCluster.putNamespace(ns)
}

// AppendNamespaceTableID append table id to namespace
func (c *RaftCluster) AppendNamespaceTableID(name string, tableID int64) error {
// AddNamespaceTableID adds table ID to namespace
func (c *RaftCluster) AddNamespaceTableID(name string, tableID int64) error {
c.Lock()
defer c.Unlock()

if c.cachedCluster.namespacesInfo.IsTableIDExist(tableID) {
return errors.New("Table id already exists in this cluster")
return errors.New("Table ID already exists in this cluster")
}

namespace := c.cachedCluster.getNamespace(name)
if namespace == nil {
return errors.Errorf("invalid namespace name %s, nod found", name)
return errors.Errorf("invalid namespace Name %s, nod found", name)
}

namespace.TableIDs = append(namespace.TableIDs, tableID)
namespace.AddTableID(tableID)
return c.cachedCluster.putNamespace(namespace)
}

// AppendNamespaceStoreID append store id to namespace
func (c *RaftCluster) AppendNamespaceStoreID(name string, storeID uint64) error {
// AddNamespaceStoreID adds store ID to namespace
func (c *RaftCluster) AddNamespaceStoreID(name string, storeID uint64) error {
c.Lock()
defer c.Unlock()

if c.cachedCluster.namespacesInfo.IsStoreIDExist(storeID) {
return errors.New("Store id already exists in this namespace")
return errors.New("Store ID already exists in this namespace")
}

namespace := c.cachedCluster.getNamespace(name)
if namespace == nil {
return errors.Errorf("invalid namespace name %s, not found", name)
return errors.Errorf("invalid namespace Name %s, not found", name)
}

namespace.StoreIDs = append(namespace.StoreIDs, storeID)
namespace.AddStoreID(storeID)
return c.cachedCluster.putNamespace(namespace)
}
16 changes: 8 additions & 8 deletions server/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -519,41 +519,41 @@ func (s *testClusterSuite) TestNamespaceOperation(c *C) {
c.Assert(len(namespaces), Equals, 1)
c.Assert(namespaces[0].Name, Equals, "test1")

// Add the same name
// Add the same Name
err = raftCluster.CreateNamespace("test1")
c.Assert(err, NotNil)

raftCluster.CreateNamespace("test2")

// Add tableID
err = raftCluster.AppendNamespaceTableID("test1", 1)
err = raftCluster.AddNamespaceTableID("test1", 1)
namespaces = raftCluster.GetNamespaces()
c.Assert(err, IsNil)
c.Assert(raftCluster.cachedCluster.namespacesInfo.IsTableIDExist(1), Equals, true)

// Add storeID
err = raftCluster.AppendNamespaceStoreID("test1", 456)
err = raftCluster.AddNamespaceStoreID("test1", 456)
namespaces = raftCluster.GetNamespaces()
c.Assert(err, IsNil)
c.Assert(namespacesInfo.IsStoreIDExist(456), Equals, true)

// Ensure that duplicate tableID cannot exist in one namespace
err = raftCluster.AppendNamespaceTableID("test1", 1)
err = raftCluster.AddNamespaceTableID("test1", 1)
c.Assert(err, NotNil)

// Ensure that duplicate tableID cannot exist across namespaces
err = raftCluster.AppendNamespaceTableID("test2", 1)
err = raftCluster.AddNamespaceTableID("test2", 1)
c.Assert(err, NotNil)

// Ensure that duplicate storeID cannot exist in one namespace
err = raftCluster.AppendNamespaceStoreID("test1", 456)
err = raftCluster.AddNamespaceStoreID("test1", 456)
c.Assert(err, NotNil)

// Ensure that duplicate storeID cannot exist across namespaces
err = raftCluster.AppendNamespaceStoreID("test2", 456)
err = raftCluster.AddNamespaceStoreID("test2", 456)
c.Assert(err, NotNil)

// Add tableID to a namespace that doesn't exist
err = raftCluster.AppendNamespaceTableID("test_not_exist", 2)
err = raftCluster.AddNamespaceTableID("test_not_exist", 2)
c.Assert(err, NotNil)
}
63 changes: 39 additions & 24 deletions server/table_namespace_classifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,27 @@ import (
)

// Namespace defines two things:
// 1. relation between a name and several tables
// 2. relation between a name and several stores
// 1. relation between a Name and several tables
// 2. relation between a Name and several stores
// It is used to bind tables with stores
type Namespace struct {
ID uint64 `json:"id"`
Name string `json:"name"`
TableIDs []int64 `json:"table_ids,omitempty"`
StoreIDs []uint64 `json:"store_ids,omitempty"`
ID uint64 `json:"ID"`
Name string `json:"Name"`
TableIDs map[int64]int `json:"table_ids,omitempty"`
StoreIDs map[uint64]int `json:"store_ids,omitempty"`
}

// NewNamespace creates a new namespace
func NewNamespace(id uint64, name string) *Namespace {
return &Namespace{
ID: id,
Name: name,
TableIDs: make(map[int64]int),
StoreIDs: make(map[uint64]int),
}
}

// GetName returns namespace's name or default 'global' value
// GetName returns namespace's Name or default 'global' value
func (ns *Namespace) GetName() string {
if ns != nil {
return ns.Name
Expand All @@ -45,6 +55,16 @@ func (ns *Namespace) GetID() uint64 {
return 0
}

// AddTableID adds a tableID to this namespace
func (ns *Namespace) AddTableID(tableID int64) {
ns.TableIDs[tableID] = 1
}

// AddStoreID adds a storeID to this namespace
func (ns *Namespace) AddStoreID(storeID uint64) {
ns.StoreIDs[storeID] = 1
}

// tableNamespaceClassifier implements Classifier interface
type tableNamespaceClassifier struct {
nsInfo *namespacesInfo
Expand All @@ -68,10 +88,9 @@ func (c tableNamespaceClassifier) GetAllNamespaces() []string {

func (c tableNamespaceClassifier) GetStoreNamespace(storeInfo *core.StoreInfo) string {
for name, ns := range c.nsInfo.namespaces {
for _, storeID := range ns.StoreIDs {
if storeID == storeInfo.Id {
return name
}
_, ok := ns.StoreIDs[storeInfo.Id]
if ok {
return name
}
}
return namespace.DefaultNamespace
Expand All @@ -85,7 +104,7 @@ func (c tableNamespaceClassifier) GetRegionNamespace(regionInfo *core.RegionInfo
}

for name, ns := range c.nsInfo.namespaces {
for _, tableID := range ns.TableIDs {
for tableID := range ns.TableIDs {
if tableID == startTable && tableID == endTable {
return name
}
Expand Down Expand Up @@ -128,28 +147,24 @@ func (namespaceInfo *namespacesInfo) getNamespaces() []*Namespace {
return nsList
}

// IsTableIDExist returns true if table id exists in namespacesInfo
// IsTableIDExist returns true if table ID exists in namespacesInfo
func (namespaceInfo *namespacesInfo) IsTableIDExist(tableID int64) bool {
for _, ns := range namespaceInfo.namespaces {
for _, id := range ns.TableIDs {
if id == tableID {
return true
}
_, ok := ns.TableIDs[tableID]
if ok {
return true
}

}
return false
}

// IsStoreIDExist returns true if store id exists in namespacesInfo
// IsStoreIDExist returns true if store ID exists in namespacesInfo
func (namespaceInfo *namespacesInfo) IsStoreIDExist(storeID uint64) bool {
for _, ns := range namespaceInfo.namespaces {
for _, id := range ns.StoreIDs {
if id == storeID {
return true
}
_, ok := ns.StoreIDs[storeID]
if ok {
return true
}

}
return false
}
24 changes: 16 additions & 8 deletions server/table_namespace_classifier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,25 @@ func (d mockTableIDDecoderForGlobal) DecodeTableID(key core.Key) int64 {

func (s *testTableNamespaceSuite) SetUpSuite(c *C) {
testNamespace1 := Namespace{
ID: 1,
Name: "test1",
TableIDs: []int64{targetTableID},
StoreIDs: []uint64{targetStoreID},
ID: 1,
Name: "test1",
TableIDs: map[int64]int{
targetTableID: 1,
},
StoreIDs: map[uint64]int{
targetStoreID: 1,
},
}

testNamespace2 := Namespace{
ID: 2,
Name: "test2",
TableIDs: []int64{targetTableID + 1},
StoreIDs: []uint64{targetStoreID + 1},
ID: 2,
Name: "test2",
TableIDs: map[int64]int{
targetTableID + 1: 1,
},
StoreIDs: map[uint64]int{
targetStoreID + 1: 1,
},
}

namespaces := newNamespacesInfo()
Expand Down

0 comments on commit fb96f63

Please sign in to comment.