From 2587e9b9384b2d776ffef62043f5597e5881aab6 Mon Sep 17 00:00:00 2001 From: valoq Date: Sun, 3 May 2026 23:52:44 +0200 Subject: [PATCH 1/2] feat: parallel preview processing --- nav.go | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/nav.go b/nav.go index e77d4af6f..b3ec60f8f 100644 --- a/nav.go +++ b/nav.go @@ -13,6 +13,7 @@ import ( "os/exec" "path/filepath" "regexp" + "runtime" "slices" "strconv" "strings" @@ -431,6 +432,11 @@ type clipboard struct { mode clipboardMode } +type previewWork struct { + path string + mode string +} + type nav struct { dirPaths []string copyJobs int @@ -452,6 +458,7 @@ type nav struct { deleteTotalChan chan int preloadChan chan string previewChan chan string + workChan chan previewWork dirChan chan *dir regChan chan *reg fileChan chan *file @@ -585,6 +592,7 @@ func newNav(ui *ui) *nav { deleteTotalChan: make(chan int, 1024), preloadChan: make(chan string, 1024), previewChan: make(chan string, 1024), + workChan: make(chan previewWork), dirChan: make(chan *dir), regChan: make(chan *reg), fileChan: make(chan *file), @@ -731,6 +739,15 @@ func (nav *nav) exportFiles() { } func (nav *nav) preloadLoop(ui *ui) { + workers := max(2, runtime.NumCPU()/2) + for i := 0; i < workers; i++ { + go func() { + for w := range nav.workChan { + nav.preview(w.path, ui.wins[len(ui.wins)-1], w.mode) + } + }() + } + stack := []string{} push := func(path string) { @@ -751,9 +768,8 @@ func (nav *nav) preloadLoop(ui *ui) { select { case path := <-nav.preloadChan: push(path) - default: - path := pop() - nav.preview(path, ui.wins[len(ui.wins)-1], "preload") + case nav.workChan <- previewWork{stack[len(stack)-1], "preload"}: + pop() } } } @@ -799,7 +815,7 @@ func (nav *nav) previewLoop(ui *ui) { nav.volatilePreview = false } if len(path) != 0 { - nav.preview(path, win, "preview") + nav.workChan <- previewWork{path, "preview"} prev = path } } From 7bf50d80482441698223aaf8af9ec963af57c743 Mon Sep 17 00:00:00 2001 From: valoq Date: Tue, 5 May 2026 00:28:12 +0200 Subject: [PATCH 2/2] fix race --- nav.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/nav.go b/nav.go index b3ec60f8f..d02392195 100644 --- a/nav.go +++ b/nav.go @@ -435,6 +435,7 @@ type clipboard struct { type previewWork struct { path string mode string + done chan struct{} } type nav struct { @@ -740,10 +741,13 @@ func (nav *nav) exportFiles() { func (nav *nav) preloadLoop(ui *ui) { workers := max(2, runtime.NumCPU()/2) - for i := 0; i < workers; i++ { + for range workers { go func() { for w := range nav.workChan { nav.preview(w.path, ui.wins[len(ui.wins)-1], w.mode) + if w.done != nil { + close(w.done) + } } }() } @@ -768,7 +772,7 @@ func (nav *nav) preloadLoop(ui *ui) { select { case path := <-nav.preloadChan: push(path) - case nav.workChan <- previewWork{stack[len(stack)-1], "preload"}: + case nav.workChan <- previewWork{stack[len(stack)-1], "preload", nil}: pop() } } @@ -815,7 +819,9 @@ func (nav *nav) previewLoop(ui *ui) { nav.volatilePreview = false } if len(path) != 0 { - nav.workChan <- previewWork{path, "preview"} + done := make(chan struct{}) + nav.workChan <- previewWork{path, "preview", done} + <-done prev = path } }