1
1
mirror of https://github.com/walles/moar.git synced 2024-11-23 05:53:18 +03:00

Don't search the whole file more than once

Should improve the performance situation reported here:
https://github.com/walles/moar/issues/209
This commit is contained in:
Johan Walles 2024-05-13 07:59:40 +02:00
parent e6c69c2d97
commit edb3e51680
2 changed files with 15 additions and 10 deletions

View File

@ -298,7 +298,7 @@ func TestFindFirstHitSimple(t *testing.T) {
pager.searchPattern = toPattern("AB")
hit := pager.findFirstHit(linenumbers.LineNumber{}, false)
hit := pager.findFirstHit(linenumbers.LineNumber{}, nil, false)
assert.Assert(t, hit.internalDontTouch.lineNumber.IsZero())
assert.Equal(t, hit.internalDontTouch.deltaScreenLines, 0)
}
@ -312,7 +312,7 @@ func TestFindFirstHitAnsi(t *testing.T) {
pager.searchPattern = toPattern("AB")
hit := pager.findFirstHit(linenumbers.LineNumber{}, false)
hit := pager.findFirstHit(linenumbers.LineNumber{}, nil, false)
assert.Assert(t, hit.internalDontTouch.lineNumber.IsZero())
assert.Equal(t, hit.internalDontTouch.deltaScreenLines, 0)
}
@ -326,7 +326,7 @@ func TestFindFirstHitNoMatch(t *testing.T) {
pager.searchPattern = toPattern("this pattern should not be found")
hit := pager.findFirstHit(linenumbers.LineNumber{}, false)
hit := pager.findFirstHit(linenumbers.LineNumber{}, nil, false)
assert.Assert(t, hit == nil)
}
@ -340,7 +340,7 @@ func TestFindFirstHitNoMatchBackwards(t *testing.T) {
pager.searchPattern = toPattern("this pattern should not be found")
theEnd := *linenumbers.LineNumberFromLength(reader.GetLineCount())
hit := pager.findFirstHit(theEnd, true)
hit := pager.findFirstHit(theEnd, nil, true)
assert.Assert(t, hit == nil)
}
@ -682,7 +682,7 @@ func benchmarkSearch(b *testing.B, highlighted bool) {
b.ResetTimer()
// This test will search through all the N copies we made of our file
hit := pager.findFirstHit(linenumbers.LineNumber{}, false)
hit := pager.findFirstHit(linenumbers.LineNumber{}, nil, false)
if hit != nil {
panic(fmt.Errorf("This test is meant to scan the whole file without finding anything"))

View File

@ -12,10 +12,10 @@ func (p *Pager) scrollToSearchHits() {
return
}
firstHitPosition := p.findFirstHit(*p.scrollPosition.lineNumber(p), false)
firstHitPosition := p.findFirstHit(*p.scrollPosition.lineNumber(p), nil, false)
if firstHitPosition == nil {
// Try again from the top
firstHitPosition = p.findFirstHit(linenumbers.LineNumber{}, false)
firstHitPosition = p.findFirstHit(linenumbers.LineNumber{}, p.scrollPosition.lineNumber(p), false)
}
if firstHitPosition == nil {
// No match, give up
@ -35,7 +35,7 @@ func (p *Pager) scrollToSearchHits() {
// scrollPosition for searching.
//
// FIXME: We should take startPosition.deltaScreenLines into account as well!
func (p *Pager) findFirstHit(startPosition linenumbers.LineNumber, backwards bool) *scrollPosition {
func (p *Pager) findFirstHit(startPosition linenumbers.LineNumber, beforePosition *linenumbers.LineNumber, backwards bool) *scrollPosition {
searchPosition := startPosition
for {
line := p.reader.GetLine(searchPosition)
@ -58,6 +58,11 @@ func (p *Pager) findFirstHit(startPosition linenumbers.LineNumber, backwards boo
searchPosition = searchPosition.NonWrappingAdd(-1)
} else {
searchPosition = searchPosition.NonWrappingAdd(1)
if beforePosition != nil && searchPosition == *beforePosition {
// No match, give up
return nil
}
}
}
}
@ -105,7 +110,7 @@ func (p *Pager) scrollToNextSearchHit() {
panic(fmt.Sprint("Unknown search mode when finding next: ", p.mode))
}
firstHitPosition := p.findFirstHit(firstSearchPosition, false)
firstHitPosition := p.findFirstHit(firstSearchPosition, nil, false)
if firstHitPosition == nil {
p.mode = PagerModeNotFound{pager: p}
return
@ -144,7 +149,7 @@ func (p *Pager) scrollToPreviousSearchHit() {
panic(fmt.Sprint("Unknown search mode when finding previous: ", p.mode))
}
firstHitPosition := p.findFirstHit(firstSearchPosition, true)
firstHitPosition := p.findFirstHit(firstSearchPosition, nil, true)
if firstHitPosition == nil {
p.mode = PagerModeNotFound{pager: p}
return