diff options
author | Tim Culverhouse <tim@timculverhouse.com> | 2022-10-27 15:35:42 -0500 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2022-11-06 23:17:57 +0100 |
commit | 29205fdd07c09c21c2d5244c6c7e4fae7b6c824f (patch) | |
tree | 1f95e1981658325368fea8091a8242bac82384f5 | |
parent | 155f0c3f28a1d7bdb5c317f83a195b2fe9594b0d (diff) | |
download | aerc-29205fdd07c09c21c2d5244c6c7e4fae7b6c824f.tar.gz |
maildir/search: get MessageInfos in parallel
Searching in the maildir worker requires reading each file in the
directory. Use waitgroups and goroutines to read files in parallel.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
-rw-r--r-- | worker/maildir/search.go | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/worker/maildir/search.go b/worker/maildir/search.go index 2ad1c0e1..729d521f 100644 --- a/worker/maildir/search.go +++ b/worker/maildir/search.go @@ -3,7 +3,9 @@ package maildir import ( "io" "net/textproto" + "runtime" "strings" + "sync" "unicode" "github.com/emersion/go-maildir" @@ -97,16 +99,29 @@ func (w *Worker) search(criteria *searchCriteria) ([]uint32, error) { } matchedUids := []uint32{} + mu := sync.Mutex{} + wg := sync.WaitGroup{} + // Hard limit at 2x CPU cores + max := runtime.NumCPU() * 2 + limit := make(chan struct{}, max) for _, key := range keys { - success, err := w.searchKey(key, criteria, requiredParts) - if err != nil { - // don't return early so that we can still get some results - logging.Errorf("Failed to search key %d: %v", key, err) - } else if success { - matchedUids = append(matchedUids, key) - } + limit <- struct{}{} + wg.Add(1) + go func(key uint32) { + defer wg.Done() + success, err := w.searchKey(key, criteria, requiredParts) + if err != nil { + // don't return early so that we can still get some results + logging.Errorf("Failed to search key %d: %v", key, err) + } else if success { + mu.Lock() + matchedUids = append(matchedUids, key) + mu.Unlock() + } + <-limit + }(key) } - + wg.Wait() return matchedUids, nil } |