Minor FSTree improvements #31

Merged
fyrchik merged 3 commits from fstree-cleanup into master 2023-02-10 09:49:31 +00:00
2 changed files with 40 additions and 35 deletions

View file

@ -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")
} }
carpawell commented 2023-01-31 13:04:36 +00:00 (Migrated from github.com)

some bench to commit/PR decs about the enhancement?

some bench to commit/PR decs about the enhancement?
fyrchik commented 2023-02-10 05:08:39 +00:00 (Migrated from github.com)

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 {

View file

@ -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)
}
}
} }