internal/store: iterator over all entries
All checks were successful
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 2m27s
Test / Hakurei (push) Successful in 3m13s
Test / Hpkg (push) Successful in 4m9s
Test / Sandbox (race detector) (push) Successful in 4m10s
Test / Hakurei (race detector) (push) Successful in 4m59s
Test / Flake checks (push) Successful in 1m31s
All checks were successful
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 2m27s
Test / Hakurei (push) Successful in 3m13s
Test / Hpkg (push) Successful in 4m9s
Test / Sandbox (race detector) (push) Successful in 4m10s
Test / Hakurei (race detector) (push) Successful in 4m59s
Test / Flake checks (push) Successful in 1m31s
This is quite convenient for searching the store or printing active instance information. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -126,7 +126,7 @@ func (s *Store) Segments() (iter.Seq[SegmentIdentity], int, error) {
|
||||
}
|
||||
|
||||
// this should never happen
|
||||
si.Err = &hst.AppError{Step: step, Err: syscall.EISDIR,
|
||||
si.Err = &hst.AppError{Step: step, Err: syscall.ENOTDIR,
|
||||
Msg: "skipped non-directory entry " + strconv.Quote(ent.Name())}
|
||||
goto out
|
||||
}
|
||||
@@ -152,6 +152,50 @@ func (s *Store) Segments() (iter.Seq[SegmentIdentity], int, error) {
|
||||
}, l, nil
|
||||
}
|
||||
|
||||
// All returns a non-reusable iterator over all [EntryHandle] known to this [Store].
|
||||
// Callers must call copyError after completing iteration and handle the error accordingly.
|
||||
// A non-nil error returned by copyError is of type [hst.AppError].
|
||||
func (s *Store) All() (entries iter.Seq[*EntryHandle], copyError func() error) {
|
||||
var savedErr error
|
||||
return func(yield func(*EntryHandle) bool) {
|
||||
var segments iter.Seq[SegmentIdentity]
|
||||
segments, _, savedErr = s.Segments()
|
||||
if savedErr != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for si := range segments {
|
||||
if savedErr = si.Err; savedErr != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var handle *Handle
|
||||
if handle, savedErr = s.Handle(si.Identity); savedErr != nil {
|
||||
return // not reached
|
||||
}
|
||||
|
||||
var unlock func()
|
||||
if unlock, savedErr = handle.Lock(); savedErr != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var segmentEntries iter.Seq[*EntryHandle]
|
||||
if segmentEntries, _, savedErr = handle.Entries(); savedErr != nil {
|
||||
unlock()
|
||||
return // not reached: lock has succeeded
|
||||
}
|
||||
|
||||
for eh := range segmentEntries {
|
||||
if !yield(eh) {
|
||||
unlock()
|
||||
return
|
||||
}
|
||||
}
|
||||
unlock()
|
||||
}
|
||||
}, func() error { return savedErr }
|
||||
}
|
||||
|
||||
// New returns the address of a new instance of [Store].
|
||||
// Multiple instances of [Store] rooted in the same directory is possible, but unsupported.
|
||||
func New(base *check.Absolute) *Store {
|
||||
|
||||
Reference in New Issue
Block a user