Minor FSTree improvements #31
2 changed files with 40 additions and 35 deletions
|
@ -71,27 +71,27 @@ func stringifyAddress(addr oid.Address) string {
|
||||||
return addr.Object().EncodeToString() + "." + addr.Container().EncodeToString()
|
return addr.Object().EncodeToString() + "." + addr.Container().EncodeToString()
|
||||||
}
|
}
|
||||||
|
|
||||||
func addressFromString(s string) (*oid.Address, error) {
|
func addressFromString(s string) (oid.Address, error) {
|
||||||
ss := strings.SplitN(s, ".", 2)
|
i := strings.IndexByte(s, '.')
|
||||||
if len(ss) != 2 {
|
if i == -1 {
|
||||||
return nil, errors.New("invalid address")
|
return oid.Address{}, errors.New("invalid address")
|
||||||
}
|
}
|
||||||
|
|
||||||
![]() Fixed Fixed
|
|||||||
var obj oid.ID
|
var obj oid.ID
|
||||||
if err := obj.DecodeString(ss[0]); err != nil {
|
if err := obj.DecodeString(s[:i]); err != nil {
|
||||||
return nil, err
|
return oid.Address{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var cnr cid.ID
|
var cnr cid.ID
|
||||||
if err := cnr.DecodeString(ss[1]); err != nil {
|
if err := cnr.DecodeString(s[i+1:]); err != nil {
|
||||||
return nil, err
|
return oid.Address{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var addr oid.Address
|
var addr oid.Address
|
||||||
addr.SetObject(obj)
|
addr.SetObject(obj)
|
||||||
addr.SetContainer(cnr)
|
addr.SetContainer(cnr)
|
||||||
|
|
||||||
return &addr, nil
|
return addr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate iterates over all stored objects.
|
// Iterate iterates over all stored objects.
|
||||||
|
@ -135,7 +135,7 @@ func (t *FSTree) iterate(depth uint64, curPath []string, prm common.IteratePrm)
|
||||||
}
|
}
|
||||||
|
|
||||||
if prm.LazyHandler != nil {
|
if prm.LazyHandler != nil {
|
||||||
err = prm.LazyHandler(*addr, func() ([]byte, error) {
|
err = prm.LazyHandler(addr, func() ([]byte, error) {
|
||||||
return os.ReadFile(filepath.Join(curPath...))
|
return os.ReadFile(filepath.Join(curPath...))
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
@ -147,7 +147,7 @@ func (t *FSTree) iterate(depth uint64, curPath []string, prm common.IteratePrm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if prm.IgnoreErrors {
|
if prm.IgnoreErrors {
|
||||||
if prm.ErrorHandler != nil {
|
if prm.ErrorHandler != nil {
|
||||||
return prm.ErrorHandler(*addr, err)
|
return prm.ErrorHandler(addr, err)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ func (t *FSTree) iterate(depth uint64, curPath []string, prm common.IteratePrm)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = prm.Handler(common.IterationElement{
|
err = prm.Handler(common.IterationElement{
|
||||||
Address: *addr,
|
Address: addr,
|
||||||
ObjectData: data,
|
ObjectData: data,
|
||||||
StorageID: []byte{},
|
StorageID: []byte{},
|
||||||
})
|
})
|
||||||
|
@ -172,17 +172,19 @@ func (t *FSTree) iterate(depth uint64, curPath []string, prm common.IteratePrm)
|
||||||
func (t *FSTree) treePath(addr oid.Address) string {
|
func (t *FSTree) treePath(addr oid.Address) string {
|
||||||
sAddr := stringifyAddress(addr)
|
sAddr := stringifyAddress(addr)
|
||||||
|
|
||||||
dirs := make([]string, 0, t.Depth+1+1) // 1 for root, 1 for file
|
var sb strings.Builder
|
||||||
dirs = append(dirs, t.RootPath)
|
sb.Grow(len(t.RootPath) + len(sAddr) + int(t.Depth) + 1)
|
||||||
|
sb.WriteString(t.RootPath)
|
||||||
|
|
||||||
for i := 0; uint64(i) < t.Depth; i++ {
|
for i := 0; uint64(i) < t.Depth; i++ {
|
||||||
dirs = append(dirs, sAddr[:t.DirNameLen])
|
sb.WriteRune(filepath.Separator)
|
||||||
|
sb.WriteString(sAddr[:t.DirNameLen])
|
||||||
sAddr = sAddr[t.DirNameLen:]
|
sAddr = sAddr[t.DirNameLen:]
|
||||||
}
|
}
|
||||||
|
|
||||||
dirs = append(dirs, sAddr)
|
sb.WriteRune(filepath.Separator)
|
||||||
|
sb.WriteString(sAddr)
|
||||||
return filepath.Join(dirs...)
|
return sb.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete removes the object with the specified address from the storage.
|
// Delete removes the object with the specified address from the storage.
|
||||||
|
@ -191,15 +193,9 @@ func (t *FSTree) Delete(prm common.DeletePrm) (common.DeleteRes, error) {
|
||||||
return common.DeleteRes{}, common.ErrReadOnly
|
return common.DeleteRes{}, common.ErrReadOnly
|
||||||
}
|
}
|
||||||
|
|
||||||
p, err := t.getPath(prm.Address)
|
p := t.treePath(prm.Address)
|
||||||
if err != nil {
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
err = logicerr.Wrap(apistatus.ObjectNotFound{})
|
|
||||||
}
|
|
||||||
return common.DeleteRes{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = os.Remove(p)
|
err := os.Remove(p)
|
||||||
if err != nil && os.IsNotExist(err) {
|
if err != nil && os.IsNotExist(err) {
|
||||||
err = logicerr.Wrap(apistatus.ObjectNotFound{})
|
err = logicerr.Wrap(apistatus.ObjectNotFound{})
|
||||||
}
|
}
|
||||||
|
@ -209,7 +205,9 @@ func (t *FSTree) Delete(prm common.DeletePrm) (common.DeleteRes, error) {
|
||||||
// Exists returns the path to the file with object contents if it exists in the storage
|
// Exists returns the path to the file with object contents if it exists in the storage
|
||||||
// and an error otherwise.
|
// and an error otherwise.
|
||||||
func (t *FSTree) Exists(prm common.ExistsPrm) (common.ExistsRes, error) {
|
func (t *FSTree) Exists(prm common.ExistsPrm) (common.ExistsRes, error) {
|
||||||
_, err := t.getPath(prm.Address)
|
p := t.treePath(prm.Address)
|
||||||
|
|
||||||
|
_, err := os.Stat(p)
|
||||||
found := err == nil
|
found := err == nil
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
err = nil
|
err = nil
|
||||||
|
@ -217,13 +215,6 @@ func (t *FSTree) Exists(prm common.ExistsPrm) (common.ExistsRes, error) {
|
||||||
return common.ExistsRes{Exists: found}, err
|
return common.ExistsRes{Exists: found}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *FSTree) getPath(addr oid.Address) (string, error) {
|
|
||||||
p := t.treePath(addr)
|
|
||||||
|
|
||||||
_, err := os.Stat(p)
|
|
||||||
return p, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Put puts an object in the storage.
|
// Put puts an object in the storage.
|
||||||
func (t *FSTree) Put(prm common.PutPrm) (common.PutRes, error) {
|
func (t *FSTree) Put(prm common.PutPrm) (common.PutRes, error) {
|
||||||
if t.readOnly {
|
if t.readOnly {
|
||||||
|
|
|
@ -12,5 +12,19 @@ func TestAddressToString(t *testing.T) {
|
||||||
s := stringifyAddress(addr)
|
s := stringifyAddress(addr)
|
||||||
actual, err := addressFromString(s)
|
actual, err := addressFromString(s)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, addr, *actual)
|
require.Equal(t, addr, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Benchmark_addressFromString(b *testing.B) {
|
||||||
|
addr := oidtest.Address()
|
||||||
|
s := stringifyAddress(addr)
|
||||||
|
|
||||||
|
b.ReportAllocs()
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_, err := addressFromString(s)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatalf("benchmark error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue
some bench to commit/PR decs about the enhancement?