aboutsummaryrefslogtreecommitdiff
path: root/objectstore/packed/idx_lookup_candidates.go
diff options
context:
space:
mode:
Diffstat (limited to 'objectstore/packed/idx_lookup_candidates.go')
-rw-r--r--objectstore/packed/idx_lookup_candidates.go70
1 files changed, 34 insertions, 36 deletions
diff --git a/objectstore/packed/idx_lookup_candidates.go b/objectstore/packed/idx_lookup_candidates.go
index 9534476a..e69d07d7 100644
--- a/objectstore/packed/idx_lookup_candidates.go
+++ b/objectstore/packed/idx_lookup_candidates.go
@@ -17,50 +17,48 @@ type packCandidate struct {
mtime int64
}
-// ensureCandidates discovers pack/index pairs once.
-func (store *Store) ensureCandidates() error {
- store.discoverOnce.Do(func() {
- candidates, err := store.discoverCandidates()
- candidateByPack := make(map[string]packCandidate, len(candidates))
- nodeByPack := make(map[string]*packCandidateNode, len(candidates))
+type candidateSnapshot struct {
+ candidates []packCandidate
+ candidateByPack map[string]packCandidate
+}
- var (
- head *packCandidateNode
- tail *packCandidateNode
- )
+// Refresh rescans objects/pack and atomically installs a fresh candidate list.
+func (store *Store) Refresh() error {
+ store.refreshMu.Lock()
+ defer store.refreshMu.Unlock()
- for _, candidate := range candidates {
- node := &packCandidateNode{
- candidate: candidate,
- prev: tail,
- }
- if tail != nil {
- tail.next = node
- }
+ candidates, err := store.discoverCandidates()
+ if err != nil {
+ return err
+ }
- if head == nil {
- head = node
- }
+ candidateByPack := make(map[string]packCandidate, len(candidates))
+ for _, candidate := range candidates {
+ candidateByPack[candidate.packName] = candidate
+ }
- tail = node
- candidateByPack[candidate.packName] = candidate
- nodeByPack[candidate.packName] = node
- }
+ store.reconcileMRU(candidates)
- store.candidatesMu.Lock()
- store.candidateHead = head
- store.candidateTail = tail
- store.candidateByPack = candidateByPack
- store.candidateNodeByPack = nodeByPack
- store.discoverErr = err
- store.candidatesMu.Unlock()
+ store.candidates.Store(&candidateSnapshot{
+ candidates: candidates,
+ candidateByPack: candidateByPack,
})
- store.candidatesMu.RLock()
- err := store.discoverErr
- store.candidatesMu.RUnlock()
+ return nil
+}
+
+func (store *Store) ensureCandidates() (*candidateSnapshot, error) {
+ snapshot := store.candidates.Load()
+ if snapshot != nil {
+ return snapshot, nil
+ }
+
+ err := store.Refresh()
+ if err != nil {
+ return nil, err
+ }
- return err
+ return store.candidates.Load(), nil
}
// discoverCandidates scans the objects/pack root and returns sorted pack/index