Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

storage: keyspace management #5265

Merged
merged 21 commits into from
Aug 8, 2022
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ module github.com/tikv/pd

go 1.18

// TODO: Remove after kvproto merge
replace github.com/pingcap/kvproto => github.com/AmoebaProtozoa/kvproto v0.0.0-20220721101402-e48eba4cc8f7
AmoebaProtozoa marked this conversation as resolved.
Show resolved Hide resolved

require (
github.com/AlekSi/gocov-xml v1.0.0
github.com/BurntSushi/toml v0.3.1
Expand Down
13 changes: 2 additions & 11 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/AlekSi/gocov-xml v1.0.0 h1:4QctJBgXEkbzeKz6PJy6bt3JSPNSN4I2mITYW+eKUoQ=
github.com/AlekSi/gocov-xml v1.0.0/go.mod h1:J0qYeZ6tDg4oZubW9mAAgxlqw39PDfoEkzB3HXSbEuA=
github.com/AmoebaProtozoa/kvproto v0.0.0-20220721101402-e48eba4cc8f7 h1:l8MbmqS/q+3slfDRsFa3w0yTJbS+uSxgkZL9QOPzkJA=
github.com/AmoebaProtozoa/kvproto v0.0.0-20220721101402-e48eba4cc8f7/go.mod h1:OYtxs0786qojVTmkVeufx93xe+jUgm56GUYRIKnmaGI=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
Expand Down Expand Up @@ -178,10 +180,8 @@ github.com/goccy/go-graphviz v0.0.9 h1:s/FMMJ1Joj6La3S5ApO3Jk2cwM4LpXECC2muFx3IP
github.com/goccy/go-graphviz v0.0.9/go.mod h1:wXVsXxmyMQU6TN3zGRttjNn3h+iCAS7xQFC6TlNvLhk=
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v0.0.0-20180717141946-636bf0302bc9/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c=
Expand All @@ -195,7 +195,6 @@ github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4er
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v0.0.0-20180814211427-aa810b61a9c7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
Expand Down Expand Up @@ -306,7 +305,6 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
Expand Down Expand Up @@ -415,10 +413,6 @@ github.com/pingcap/errors v0.11.5-0.20211224045212-9687c2b0f87c h1:xpW9bvK+HuuTm
github.com/pingcap/errors v0.11.5-0.20211224045212-9687c2b0f87c/go.mod h1:X2r9ueLEUZgtx2cIogM0v4Zj5uvvzhuuiu7Pn8HzMPg=
github.com/pingcap/failpoint v0.0.0-20200702092429-9f69995143ce h1:Y1kCxlCtlPTMtVcOkjUcuQKh+YrluSo7+7YMCQSzy30=
github.com/pingcap/failpoint v0.0.0-20200702092429-9f69995143ce/go.mod h1:w4PEZ5y16LeofeeGwdgZB4ddv9bLyDuIX+ljstgKZyk=
github.com/pingcap/kvproto v0.0.0-20191211054548-3c6b38ea5107/go.mod h1:WWLmULLO7l8IOcQG+t+ItJ3fEcrL5FxF0Wu+HrMy26w=
github.com/pingcap/kvproto v0.0.0-20200411081810-b85805c9476c/go.mod h1:IOdRDPLyda8GX2hE/jO7gqaCV/PNFh8BZQCQZXfIOqI=
github.com/pingcap/kvproto v0.0.0-20220510035547-0e2f26c0a46a h1:TxdHGOFeNa1q1mVv6TgReayf26iI4F8PQUm6RnZ/V/E=
github.com/pingcap/kvproto v0.0.0-20220510035547-0e2f26c0a46a/go.mod h1:OYtxs0786qojVTmkVeufx93xe+jUgm56GUYRIKnmaGI=
github.com/pingcap/log v0.0.0-20191012051959-b742a5d432e9/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8=
github.com/pingcap/log v0.0.0-20200511115504-543df19646ad/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8=
github.com/pingcap/log v0.0.0-20210625125904-98ed8e2eb1c7/go.mod h1:8AanEdAHATuRurdGxZXBz0At+9avep+ub7U1AGYLIMM=
Expand Down Expand Up @@ -727,7 +721,6 @@ golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 h1:M73Iuj3xbbb9Uk1DYhzydths
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
Expand Down Expand Up @@ -769,11 +762,9 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20181004005441-af9cb2a35e7f/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c h1:hrpEMCZ2O7DR5gC1n2AJGVhrwiEjOi35+jxtIuZpTMo=
google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/grpc v0.0.0-20180607172857-7a6a684ca69e/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
Expand Down
32 changes: 32 additions & 0 deletions server/storage/endpoint/key_path.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ package endpoint
import (
"fmt"
"path"
"strconv"
"strings"
)

const (
Expand All @@ -34,6 +36,9 @@ const (
minResolvedTS = "min_resolved_ts"
keySpaceSafePointPrefix = "key_space/gc_safepoint"
keySpaceGCSafePointSuffix = "gc"
keyspacePrefix = "keyspaces"
AmoebaProtozoa marked this conversation as resolved.
Show resolved Hide resolved
keyspaceMetaInfix = "meta"
keyspaceIDInfix = "id"
AmoebaProtozoa marked this conversation as resolved.
Show resolved Hide resolved
)

// AppendToRootPath appends the given key to the rootPath.
Expand Down Expand Up @@ -136,3 +141,30 @@ func KeySpaceSafePointPrefix() string {
func KeySpaceGCSafePointSuffix() string {
return "/" + keySpaceGCSafePointSuffix
}

// KeyspaceMetaPrefix returns the prefix of keyspaces' metadata.
// Prefix: keyspaces/meta/
AmoebaProtozoa marked this conversation as resolved.
Show resolved Hide resolved
func KeyspaceMetaPrefix() string {
return path.Join(keyspacePrefix, keyspaceMetaInfix) + "/"
}

// KeyspaceMetaPath returns the path to the given keyspace's metadata.
// Path: keyspaces/meta/{space_id}
func KeyspaceMetaPath(spaceID uint32) string {
idStr := encodeKeyspaceID(spaceID)
return path.Join(KeyspaceMetaPrefix(), idStr)
}

// KeyspaceIDPath returns the path to keyspace id from the given name.
// Path: keyspaces/id/{name}
func KeyspaceIDPath(name string) string {
return path.Join(keyspacePrefix, keyspaceIDInfix, name)
}

// encodeKeyspaceID from uint32 to string.
// It adds extra padding to make encoded ID ordered.
// Encoded ID can be decoded directly with strconv.ParseUint.
func encodeKeyspaceID(spaceID uint32) string {
idStr := strconv.FormatUint(uint64(spaceID), spaceIDBase)
return strings.Repeat("0", spaceIDStrLen-len(idStr)) + idStr
AmoebaProtozoa marked this conversation as resolved.
Show resolved Hide resolved
}
120 changes: 120 additions & 0 deletions server/storage/endpoint/keyspace.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// Copyright 2022 TiKV Project Authors.
//
// 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 endpoint

import (
"strconv"

"github.com/gogo/protobuf/proto"
"github.com/pingcap/kvproto/pkg/keyspacepb"
"go.etcd.io/etcd/clientv3"
)

const (
// spaceIDBase is base used to encode/decode spaceID.
// It's set to 10 for better readability.
spaceIDBase = 10
// spaceIDBitSizeMax is the max bitSize of spaceID.
// It's currently set to 24 (3bytes).
spaceIDBitSizeMax = 24
// spaceIDStrLen is the length of spaceID when written in spaceIDBase.
// It's currently set to 8 (base10 of uint24max is 16777215)
// It's used to pad all spaceIDs in etcd path to the same length.
spaceIDStrLen = 8
)

// KeyspaceStorage defines storage operations on keyspace related data.
type KeyspaceStorage interface {
AmoebaProtozoa marked this conversation as resolved.
Show resolved Hide resolved
// SaveKeyspace saves the given keyspace to the storage.
SaveKeyspace(*keyspacepb.KeyspaceMeta) error
// LoadKeyspace loads keyspace specified by spaceID.
LoadKeyspace(spaceID uint32, keyspace *keyspacepb.KeyspaceMeta) (bool, error)
// RemoveKeyspace removes target keyspace specified by spaceID.
RemoveKeyspace(spaceID uint32) error
// LoadRangeKeyspace loads no more than limit keyspaces starting at startID.
LoadRangeKeyspace(startID uint32, limit int) ([]*keyspacepb.KeyspaceMeta, error)
// SaveKeyspaceIDByName saves keyspace name to ID lookup information.
// It saves the ID onto the path encoded with name.
SaveKeyspaceIDByName(spaceID uint32, name string) error
// LoadKeyspaceIDByName loads keyspace ID for the given keyspace specified by name.
// It first constructs path to spaceID with the given name, then attempt to retrieve
// target spaceID. If the target keyspace does not exist, result boolean is set to false.
LoadKeyspaceIDByName(name string) (bool, uint32, error)
}

var _ KeyspaceStorage = (*StorageEndpoint)(nil)

// SaveKeyspace saves the given keyspace to the storage.
func (se *StorageEndpoint) SaveKeyspace(keyspace *keyspacepb.KeyspaceMeta) error {
AmoebaProtozoa marked this conversation as resolved.
Show resolved Hide resolved
key := KeyspaceMetaPath(keyspace.GetId())
AmoebaProtozoa marked this conversation as resolved.
Show resolved Hide resolved
return se.saveProto(key, keyspace)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we save json instead to make it read/debug-friendly?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here some information defined in proto. maybe proto more suitable.

}

// LoadKeyspace loads keyspace specified by spaceID.
func (se *StorageEndpoint) LoadKeyspace(spaceID uint32, keyspace *keyspacepb.KeyspaceMeta) (bool, error) {
key := KeyspaceMetaPath(spaceID)
return se.loadProto(key, keyspace)
}

// RemoveKeyspace removes target keyspace specified by spaceID.
func (se *StorageEndpoint) RemoveKeyspace(spaceID uint32) error {
key := KeyspaceMetaPath(spaceID)
return se.Remove(key)
}

// LoadRangeKeyspace loads keyspaces starting at startID.
// limit specifies the limit of loaded keyspaces.
func (se *StorageEndpoint) LoadRangeKeyspace(startID uint32, limit int) ([]*keyspacepb.KeyspaceMeta, error) {
startKey := KeyspaceMetaPath(startID)
endKey := clientv3.GetPrefixRangeEnd(KeyspaceMetaPrefix())
keys, values, err := se.LoadRange(startKey, endKey, limit)
if err != nil {
return nil, err
}
if len(keys) == 0 {
return []*keyspacepb.KeyspaceMeta{}, nil
}
keyspaces := make([]*keyspacepb.KeyspaceMeta, 0, len(keys))
for _, value := range values {
keyspace := &keyspacepb.KeyspaceMeta{}
if err = proto.Unmarshal([]byte(value), keyspace); err != nil {
return nil, err
}
keyspaces = append(keyspaces, keyspace)
}
return keyspaces, nil
}

// SaveKeyspaceIDByName saves keyspace name to ID lookup information to storage.
func (se *StorageEndpoint) SaveKeyspaceIDByName(spaceID uint32, name string) error {
key := KeyspaceIDPath(name)
idStr := strconv.FormatUint(uint64(spaceID), spaceIDBase)
return se.Save(key, idStr)
}

// LoadKeyspaceIDByName loads keyspace ID for the given keyspace name
func (se *StorageEndpoint) LoadKeyspaceIDByName(name string) (bool, uint32, error) {
key := KeyspaceIDPath(name)
idStr, err := se.Load(key)
// Failed to load the keyspaceID if loading operation errored, or if keyspace does not exist.
if err != nil || idStr == "" {
return false, 0, err
}
id64, err := strconv.ParseUint(idStr, spaceIDBase, spaceIDBitSizeMax)
if err != nil {
return false, 0, err
}
return true, uint32(id64), nil
}
148 changes: 148 additions & 0 deletions server/storage/keyspace_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// Copyright 2022 TiKV Project Authors.
//
// 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 storage

import (
"testing"
"time"

"github.com/pingcap/kvproto/pkg/keyspacepb"
"github.com/stretchr/testify/require"
"github.com/tikv/pd/server/storage/endpoint"
)

func TestSaveLoadKeyspace(t *testing.T) {
re := require.New(t)
storage := NewStorageWithMemoryBackend()

keyspaces := makeTestKeyspaces()
for _, keyspace := range keyspaces {
re.NoError(storage.SaveKeyspace(keyspace))
}

for _, keyspace := range keyspaces {
spaceID := keyspace.GetId()
loadedKeyspace := &keyspacepb.KeyspaceMeta{}
// Test load keyspace.
success, err := storage.LoadKeyspace(spaceID, loadedKeyspace)
re.True(success)
re.NoError(err)
re.Equal(keyspace, loadedKeyspace)
// Test remove keyspace.
re.NoError(storage.RemoveKeyspace(spaceID))
success, err = storage.LoadKeyspace(spaceID, loadedKeyspace)
// Loading a non-existing keyspace should be unsuccessful.
re.False(success)
// Loading a non-existing keyspace should not return error.
re.NoError(err)
}
}

func TestLoadRangeKeyspaces(t *testing.T) {
re := require.New(t)
storage := NewStorageWithMemoryBackend()

keyspaces := makeTestKeyspaces()
for _, keyspace := range keyspaces {
re.NoError(storage.SaveKeyspace(keyspace))
}

// Load all keyspaces.
loadedKeyspaces, err := storage.LoadRangeKeyspace(keyspaces[0].GetId(), 0)
re.NoError(err)
re.ElementsMatch(keyspaces, loadedKeyspaces)

// Load keyspaces with id >= second test keyspace's id.
loadedKeyspaces2, err := storage.LoadRangeKeyspace(keyspaces[1].GetId(), 0)
re.NoError(err)
re.ElementsMatch(keyspaces[1:], loadedKeyspaces2)

// Load keyspace with the smallest id.
loadedKeyspace3, err := storage.LoadRangeKeyspace(1, 1)
re.NoError(err)
re.ElementsMatch(keyspaces[:1], loadedKeyspace3)
}

func TestSaveLoadKeyspaceID(t *testing.T) {
re := require.New(t)
storage := NewStorageWithMemoryBackend()

ids := []uint32{100, 200, 300}
names := []string{"keyspace1", "keyspace2", "keyspace3"}
for i := range ids {
re.NoError(storage.SaveKeyspaceIDByName(ids[i], names[i]))
}

for i := range names {
success, id, err := storage.LoadKeyspaceIDByName(names[i])
re.NoError(err)
re.True(success)
re.Equal(ids[i], id)
}
// Loading non-existing id should return false, 0, nil.
success, id, err := storage.LoadKeyspaceIDByName("non-existing")
re.NoError(err)
re.False(success)
re.Equal(uint32(0), id)
}

func makeTestKeyspaces() []*keyspacepb.KeyspaceMeta {
now := time.Now().Unix()
return []*keyspacepb.KeyspaceMeta{
{
Id: 10,
Name: "keyspace1",
State: keyspacepb.KeyspaceState_ENABLED,
CreatedAt: now,
StateChangedAt: now,
Config: map[string]string{
"gc_life_time": "6000",
"gc_interval": "3000",
},
},
{
Id: 11,
Name: "keyspace2",
State: keyspacepb.KeyspaceState_ARCHIVED,
CreatedAt: now + 300,
StateChangedAt: now + 300,
Config: map[string]string{
"gc_life_time": "1000",
"gc_interval": "5000",
},
},
{
Id: 100,
Name: "keyspace3",
State: keyspacepb.KeyspaceState_DISABLED,
CreatedAt: now + 500,
StateChangedAt: now + 500,
Config: map[string]string{
"gc_life_time": "4000",
"gc_interval": "2000",
},
},
}
}

// TestEncodeSpaceID test spaceID encoding.
func TestEncodeSpaceID(t *testing.T) {
re := require.New(t)
re.Equal("keyspaces/meta/00000000", endpoint.KeyspaceMetaPath(0))
re.Equal("keyspaces/meta/16777215", endpoint.KeyspaceMetaPath(1<<24-1))
re.Equal("keyspaces/meta/00000100", endpoint.KeyspaceMetaPath(100))
re.Equal("keyspaces/meta/00000011", endpoint.KeyspaceMetaPath(11))
re.Equal("keyspaces/meta/00000010", endpoint.KeyspaceMetaPath(10))
}
Loading