aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Culverhouse <tim@timculverhouse.com>2022-10-27 15:35:42 -0500
committerRobin Jarry <robin@jarry.cc>2022-11-06 23:17:57 +0100
commit29205fdd07c09c21c2d5244c6c7e4fae7b6c824f (patch)
tree1f95e1981658325368fea8091a8242bac82384f5
parent155f0c3f28a1d7bdb5c317f83a195b2fe9594b0d (diff)
downloadaerc-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.go31
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
}