Skip to content

Commit

Permalink
blobstore/filestore: cache Info for a second
Browse files Browse the repository at this point in the history
this shows up in speed profiles as a hot spot
on windows. in a test of 50k pieces, it took
67 seconds out of 145 seconds, leaving 78 total
seconds so we should see a reduction of 78/50000
or 0.1% of the time, or ~600ms. should be good
enough and still maintain enough freshness for
it to do a good enough job enforcing the available
space on the piece upload.

Change-Id: Iaaff8b7739c52bcb5313c283c5aa3750c9f9139f
  • Loading branch information
zeebo authored and andriikotko committed May 9, 2024
1 parent 5bf9a60 commit 2b13d98
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 1 deletion.
31 changes: 30 additions & 1 deletion storagenode/blobstore/filestore/dir.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (
"os"
"path/filepath"
"strings"
"sync"
"sync/atomic"
"time"

"github.com/zeebo/errs"
Expand Down Expand Up @@ -47,6 +49,16 @@ var PathEncoding = base32.NewEncoding("abcdefghijklmnopqrstuvwxyz234567").WithPa
type Dir struct {
log *zap.Logger
path string

mu sync.Mutex
info atomic.Pointer[infoAge]
}

const infoMaxAge = time.Second

type infoAge struct {
info blobstore.DiskInfo
age time.Time
}

// OpenDir opens existing folder for storing blobs.
Expand Down Expand Up @@ -998,11 +1010,28 @@ func walkNamespaceWithPrefix(ctx context.Context, log *zap.Logger, namespace []b

// Info returns information about the current state of the dir.
func (dir *Dir) Info(ctx context.Context) (blobstore.DiskInfo, error) {
if info := dir.info.Load(); info != nil && time.Since(info.age) < infoMaxAge {
return info.info, nil
}

dir.mu.Lock()
defer dir.mu.Unlock()

if info := dir.info.Load(); info != nil && time.Since(info.age) < infoMaxAge {
return info.info, nil
}

path, err := filepath.Abs(dir.path)
if err != nil {
return blobstore.DiskInfo{}, err
}
return diskInfoFromPath(path)
info, err := diskInfoFromPath(path)
if err != nil {
return blobstore.DiskInfo{}, err
}

dir.info.Store(&infoAge{info: info, age: time.Now()})
return info, nil
}

type blobInfo struct {
Expand Down
14 changes: 14 additions & 0 deletions storagenode/blobstore/filestore/dir_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,20 @@ func TestTrashRecoveryWithMultipleDayDirs(t *testing.T) {
}
}

func BenchmarkDirInfo(b *testing.B) {
ctx := testcontext.New(b)
log := zaptest.NewLogger(b)
dir, err := NewDir(log, ctx.Dir("store"))
require.NoError(b, err)
b.ReportAllocs()
b.ResetTimer()

for i := 0; i < b.N; i++ {
_, err = dir.Info(ctx)
require.NoError(b, err)
}
}

// check that trash emptying works as expected with per-day trash directories.
func TestEmptyTrash(t *testing.T) {
ctx := testcontext.New(t)
Expand Down

0 comments on commit 2b13d98

Please sign in to comment.