diff options
| author | 2026-03-08 15:33:36 +0800 | |
|---|---|---|
| committer | 2026-03-08 15:44:32 +0800 | |
| commit | dd027e1e5379019bfeffc48ff1274b5e05581ff3 (patch) | |
| tree | 1f6b8f55957e706eeed801079ab42f3069085746 /objectstore/packed/idx_lookup_candidates.go | |
| parent | format/pack/ingest: Thin fix error handling (diff) | |
| signature | No signature | |
objectstore: Refresh v0.1.80
* Add manual Refresh for various objectstore's
* RefreshPolicy option
* Refreshable MRU and atomic snapshotting
Diffstat (limited to 'objectstore/packed/idx_lookup_candidates.go')
| -rw-r--r-- | objectstore/packed/idx_lookup_candidates.go | 70 |
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 |
