datahub/shard.go (59 lines of code) (raw):
package datahub
import (
"fmt"
"math/big"
"strings"
)
type ShardEntry struct {
ShardId string `json:"ShardId"`
State ShardState `json:"State"`
BeginHashKey string `json:"BeginHashKey"`
EndHashKey string `json:"EndHashKey"`
ClosedTime int64 `json:"ClosedTime"`
ParentShardIds []string `json:"ParentShardIds"`
LeftShardId string `json:"LeftShardId"`
RightShardId string `json:"RightShardId"`
Address string `json:"Address"`
}
func generateSpliteKey(projectName, topicName, shardId string, datahub DataHubApi) (string, error) {
ls, err := datahub.ListShard(projectName, topicName)
if err != nil {
return "", err
}
shards := ls.Shards
splitKey := ""
for _, shard := range shards {
if strings.EqualFold(shardId, shard.ShardId) {
if shard.State != ACTIVE {
return "", fmt.Errorf("only active shard can be split,the shard %s state is %s", shard.ShardId, shard.State)
}
splitKey, err = getSplitKey(shard.BeginHashKey, shard.EndHashKey)
splitKey = strings.ToUpper(splitKey)
if err != nil {
return "", err
}
}
}
if splitKey == "" {
return "", fmt.Errorf("shard not exist")
}
return splitKey, nil
}
func getSplitKey(beginHashKey, endHashKey string) (string, error) {
var begin, end, sum, quo big.Int
base := 16
if len(beginHashKey) != 32 || len(endHashKey) != 32 {
return "", fmt.Errorf("invalid Hash Key Range")
}
_, ok := begin.SetString(beginHashKey, base)
if !ok {
return "", fmt.Errorf("invalid Hash Key Range")
}
_, ok = end.SetString(endHashKey, base)
if !ok {
return "", fmt.Errorf("invalid Hash Key Range")
}
sum.Add(&begin, &end)
quo.Quo(&sum, big.NewInt(2))
return quo.Text(base), nil
}