Commit f82967d9 authored by Kevin Atkinson's avatar Kevin Atkinson

Refactor parsing of shard identifier.

parent d7bea76d
......@@ -46,7 +46,7 @@ var ShardingFileMissing = errors.New("SHARDING file not found in datastore")
const IPFS_DEF_SHARD = "/repo/flatfs/shard/v1/next-to-last/2"
func Create(path string, fun string) error {
func Create(path string, funStr string) error {
err := os.Mkdir(path, 0777)
if err != nil && !os.IsExist(err) {
......@@ -58,17 +58,19 @@ func Create(path string, fun string) error {
case ShardingFileMissing:
// fixme: make sure directory is empty and return an error if
// it is not
err := WriteShardFunc(path, fun)
err := WriteShardFunc(path, funStr)
if err != nil {
return err
}
return nil
case nil:
_ = dsFun
fun = NormalizeShardFunc(fun)
if fun != dsFun {
fun, err := ParseShardFunc(funStr)
if err != nil {
return err
}
if fun.String() != dsFun.String() {
return fmt.Errorf("specified shard func '%s' does not match repo shard func '%s'",
fun, dsFun)
fun.String(), dsFun.String())
}
return DatastoreExists
default:
......@@ -84,20 +86,19 @@ func Open(path string, sync bool) (*Datastore, error) {
return nil, err
}
fun, err := ReadShardFunc(path)
shardId, err := ReadShardFunc(path)
if err != nil {
return nil, err
}
getDir, err := ShardFuncFromString(fun)
if err != nil {
return nil, fmt.Errorf("unable to parse shard func: %v", err)
}
fs := &Datastore{
path: path,
shardFunc: fun,
getDir: getDir,
shardFunc: shardId.String(),
getDir: shardId.Func(),
sync: sync,
}
return fs, nil
......
......@@ -9,84 +9,74 @@ import (
"strings"
)
type shardId struct {
version string
type ShardIdV1 struct {
funName string
param string
param int
fun ShardFunc
}
func (f shardId) str() string {
return fmt.Sprintf("/repo/flatfs/shard/v1/%s/%s", f.funName, f.param)
const PREFIX = "/repo/flatfs/shard"
func (f *ShardIdV1) String() string {
return fmt.Sprintf("%s/v1/%s/%d", PREFIX, f.funName, f.param)
}
func (f *ShardIdV1) Func() ShardFunc {
return f.fun
}
func parseShardFunc(str string) shardId {
func ParseShardFunc(str string) (*ShardIdV1, error) {
str = strings.TrimSpace(str)
parts := strings.Split(str, "/")
// ignore prefix for now
if len(parts) > 3 {
parts = parts[len(parts)-3:]
}
switch len(parts) {
case 3:
return shardId{version: parts[0], funName: parts[1], param: parts[2]}
case 2:
return shardId{funName: parts[0], param: parts[1]}
case 1:
return shardId{funName: parts[0]}
default: // can only happen for len == 0
return shardId{}
}
}
func (f shardId) Func() (ShardFunc, error) {
if f.version != "" && f.version != "v1" {
return nil, fmt.Errorf("expected 'v1' for version string got: %s\n", f.version)
if len(parts) == 3 {
version := parts[0]
if version != "v1" {
return nil, fmt.Errorf("expected 'v1' for version string got: %s\n", version)
}
parts = parts[1:]
}
if f.param == "" {
return nil, fmt.Errorf("'%s' function requires a parameter", f.funName)
if len(parts) != 2 {
return nil, fmt.Errorf("invalid shard identifier: %s", str)
}
len, err := strconv.Atoi(f.param)
id := &ShardIdV1 {funName: parts[0]}
param, err := strconv.Atoi(parts[1])
if err != nil {
return nil, err
return nil, fmt.Errorf("invalid parameter: %v", err)
}
switch f.funName {
id.param = param
switch id.funName {
case "prefix":
return Prefix(len), nil
id.fun = Prefix(param)
case "suffix":
return Suffix(len), nil
id.fun = Suffix(param)
case "next-to-last":
return NextToLast(len), nil
id.fun = NextToLast(param)
default:
return nil, fmt.Errorf("expected 'prefix', 'suffix' or 'next-to-last' got: %s", f.funName)
return nil, fmt.Errorf("expected 'prefix', 'suffix' or 'next-to-last' got: %s", id.funName)
}
}
func NormalizeShardFunc(str string) string {
return parseShardFunc(str).str()
}
func ShardFuncFromString(str string) (ShardFunc, error) {
id := parseShardFunc(str)
fun, err := id.Func()
if err != nil {
return nil, err
}
return fun, nil
return id, nil
}
func ReadShardFunc(dir string) (string, error) {
func ReadShardFunc(dir string) (*ShardIdV1, error) {
buf, err := ioutil.ReadFile(filepath.Join(dir, "SHARDING"))
if os.IsNotExist(err) {
return "", ShardingFileMissing
return nil, ShardingFileMissing
} else if err != nil {
return "", err
return nil, err
}
return NormalizeShardFunc(string(buf)), nil
return ParseShardFunc(string(buf))
}
func WriteShardFunc(dir, str string) error {
str = NormalizeShardFunc(str)
_, err := ShardFuncFromString(str)
id, err := ParseShardFunc(str)
if err != nil {
return err
}
......@@ -95,7 +85,7 @@ func WriteShardFunc(dir, str string) error {
return err
}
defer file.Close()
_, err = file.WriteString(str)
_, err = file.WriteString(id.String())
if err != nil {
return err
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment