From 28edae5169239a4cd2bde78002e398b271bbd3e3 Mon Sep 17 00:00:00 2001 From: luke-lombardi <33990301+luke-lombardi@users.noreply.github.com> Date: Fri, 17 Jan 2025 13:30:38 -0800 Subject: [PATCH 1/4] test contention --- pkg/blobfs_prefetch.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/blobfs_prefetch.go b/pkg/blobfs_prefetch.go index ddcf0f2..441d2c5 100644 --- a/pkg/blobfs_prefetch.go +++ b/pkg/blobfs_prefetch.go @@ -266,6 +266,8 @@ func (pb *PrefetchBuffer) tryGetRange(offset, length uint64) ([]byte, bool, bool windowIndex := offset / pb.windowSize + Logger.Infof("tryGetRange - [%s] (offset=%d, length=%d, windowIndex=%d)", pb.hash, offset, length, windowIndex) + var w *window pb.windows.Range(func(key, value any) bool { win := value.(*window) From 4d5efa4c85afba7f44d729ab951e78e8ba9db43e Mon Sep 17 00:00:00 2001 From: luke-lombardi <33990301+luke-lombardi@users.noreply.github.com> Date: Fri, 17 Jan 2025 13:53:33 -0800 Subject: [PATCH 2/4] only lock in fetch --- pkg/blobfs_prefetch.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/pkg/blobfs_prefetch.go b/pkg/blobfs_prefetch.go index 441d2c5..931673a 100644 --- a/pkg/blobfs_prefetch.go +++ b/pkg/blobfs_prefetch.go @@ -261,9 +261,6 @@ func (pb *PrefetchBuffer) GetRange(offset, length uint64) ([]byte, error) { } func (pb *PrefetchBuffer) tryGetRange(offset, length uint64) ([]byte, bool, bool) { - pb.mu.Lock() - defer pb.mu.Unlock() - windowIndex := offset / pb.windowSize Logger.Infof("tryGetRange - [%s] (offset=%d, length=%d, windowIndex=%d)", pb.hash, offset, length, windowIndex) From 71934996a5e8422e0b132926284ec0c6fe020f78 Mon Sep 17 00:00:00 2001 From: luke-lombardi <33990301+luke-lombardi@users.noreply.github.com> Date: Fri, 17 Jan 2025 14:08:07 -0800 Subject: [PATCH 3/4] only lock if we are still fetching --- pkg/blobfs_prefetch.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/blobfs_prefetch.go b/pkg/blobfs_prefetch.go index 931673a..fd70786 100644 --- a/pkg/blobfs_prefetch.go +++ b/pkg/blobfs_prefetch.go @@ -263,8 +263,6 @@ func (pb *PrefetchBuffer) GetRange(offset, length uint64) ([]byte, error) { func (pb *PrefetchBuffer) tryGetRange(offset, length uint64) ([]byte, bool, bool) { windowIndex := offset / pb.windowSize - Logger.Infof("tryGetRange - [%s] (offset=%d, length=%d, windowIndex=%d)", pb.hash, offset, length, windowIndex) - var w *window pb.windows.Range(func(key, value any) bool { win := value.(*window) @@ -281,8 +279,10 @@ func (pb *PrefetchBuffer) tryGetRange(offset, length uint64) ([]byte, bool, bool return nil, false, false } - w.mu.Lock() - defer w.mu.Unlock() + if w.fetching { + w.mu.Lock() + defer w.mu.Unlock() + } windowOffset := offset - (windowIndex * pb.windowSize) windowHead := (windowIndex * pb.windowSize) + w.readLength From 0befd4a9850c581c13f952fd39789db788f77e91 Mon Sep 17 00:00:00 2001 From: luke-lombardi <33990301+luke-lombardi@users.noreply.github.com> Date: Fri, 17 Jan 2025 14:56:37 -0800 Subject: [PATCH 4/4] better memory cleanup --- pkg/blobfs_prefetch.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/pkg/blobfs_prefetch.go b/pkg/blobfs_prefetch.go index fd70786..2b3ad92 100644 --- a/pkg/blobfs_prefetch.go +++ b/pkg/blobfs_prefetch.go @@ -3,6 +3,7 @@ package blobcache import ( "context" "fmt" + "runtime" "sync" "time" ) @@ -200,13 +201,11 @@ func (pb *PrefetchBuffer) fetch(windowIndex uint64) { func (pb *PrefetchBuffer) IsIdle() bool { idle := true - pb.mu.Lock() - defer pb.mu.Unlock() - + windowsToDelete := make([]int64, 0) pb.windows.Range(func(key, value any) bool { w := value.(*window) if w != nil && time.Since(w.lastRead) > pb.manager.windowIdleTTL && !w.fetching { - return true + windowsToDelete = append(windowsToDelete, w.index) } else { idle = false } @@ -214,6 +213,15 @@ func (pb *PrefetchBuffer) IsIdle() bool { return true }) + for _, index := range windowsToDelete { + w, exists := pb.windows.Load(index) + if exists { + w.(*window).data = nil + } + + pb.windows.Delete(index) + } + return idle } @@ -231,8 +239,11 @@ func (pb *PrefetchBuffer) Clear() { if w != nil { w.data = nil } + return true }) + + runtime.GC() } func (pb *PrefetchBuffer) GetRange(offset, length uint64) ([]byte, error) {