mirror of
https://github.com/walles/moar.git
synced 2024-09-11 12:15:43 +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:
parent
e6c69c2d97
commit
edb3e51680
@ -298,7 +298,7 @@ func TestFindFirstHitSimple(t *testing.T) {
|
|||||||
|
|
||||||
pager.searchPattern = toPattern("AB")
|
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.Assert(t, hit.internalDontTouch.lineNumber.IsZero())
|
||||||
assert.Equal(t, hit.internalDontTouch.deltaScreenLines, 0)
|
assert.Equal(t, hit.internalDontTouch.deltaScreenLines, 0)
|
||||||
}
|
}
|
||||||
@ -312,7 +312,7 @@ func TestFindFirstHitAnsi(t *testing.T) {
|
|||||||
|
|
||||||
pager.searchPattern = toPattern("AB")
|
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.Assert(t, hit.internalDontTouch.lineNumber.IsZero())
|
||||||
assert.Equal(t, hit.internalDontTouch.deltaScreenLines, 0)
|
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")
|
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)
|
assert.Assert(t, hit == nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,7 +340,7 @@ func TestFindFirstHitNoMatchBackwards(t *testing.T) {
|
|||||||
pager.searchPattern = toPattern("this pattern should not be found")
|
pager.searchPattern = toPattern("this pattern should not be found")
|
||||||
theEnd := *linenumbers.LineNumberFromLength(reader.GetLineCount())
|
theEnd := *linenumbers.LineNumberFromLength(reader.GetLineCount())
|
||||||
|
|
||||||
hit := pager.findFirstHit(theEnd, true)
|
hit := pager.findFirstHit(theEnd, nil, true)
|
||||||
assert.Assert(t, hit == nil)
|
assert.Assert(t, hit == nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -682,7 +682,7 @@ func benchmarkSearch(b *testing.B, highlighted bool) {
|
|||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
|
|
||||||
// This test will search through all the N copies we made of our file
|
// 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 {
|
if hit != nil {
|
||||||
panic(fmt.Errorf("This test is meant to scan the whole file without finding anything"))
|
panic(fmt.Errorf("This test is meant to scan the whole file without finding anything"))
|
||||||
|
15
m/search.go
15
m/search.go
@ -12,10 +12,10 @@ func (p *Pager) scrollToSearchHits() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
firstHitPosition := p.findFirstHit(*p.scrollPosition.lineNumber(p), false)
|
firstHitPosition := p.findFirstHit(*p.scrollPosition.lineNumber(p), nil, false)
|
||||||
if firstHitPosition == nil {
|
if firstHitPosition == nil {
|
||||||
// Try again from the top
|
// Try again from the top
|
||||||
firstHitPosition = p.findFirstHit(linenumbers.LineNumber{}, false)
|
firstHitPosition = p.findFirstHit(linenumbers.LineNumber{}, p.scrollPosition.lineNumber(p), false)
|
||||||
}
|
}
|
||||||
if firstHitPosition == nil {
|
if firstHitPosition == nil {
|
||||||
// No match, give up
|
// No match, give up
|
||||||
@ -35,7 +35,7 @@ func (p *Pager) scrollToSearchHits() {
|
|||||||
// scrollPosition for searching.
|
// scrollPosition for searching.
|
||||||
//
|
//
|
||||||
// FIXME: We should take startPosition.deltaScreenLines into account as well!
|
// 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
|
searchPosition := startPosition
|
||||||
for {
|
for {
|
||||||
line := p.reader.GetLine(searchPosition)
|
line := p.reader.GetLine(searchPosition)
|
||||||
@ -58,6 +58,11 @@ func (p *Pager) findFirstHit(startPosition linenumbers.LineNumber, backwards boo
|
|||||||
searchPosition = searchPosition.NonWrappingAdd(-1)
|
searchPosition = searchPosition.NonWrappingAdd(-1)
|
||||||
} else {
|
} else {
|
||||||
searchPosition = searchPosition.NonWrappingAdd(1)
|
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))
|
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 {
|
if firstHitPosition == nil {
|
||||||
p.mode = PagerModeNotFound{pager: p}
|
p.mode = PagerModeNotFound{pager: p}
|
||||||
return
|
return
|
||||||
@ -144,7 +149,7 @@ func (p *Pager) scrollToPreviousSearchHit() {
|
|||||||
panic(fmt.Sprint("Unknown search mode when finding previous: ", p.mode))
|
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 {
|
if firstHitPosition == nil {
|
||||||
p.mode = PagerModeNotFound{pager: p}
|
p.mode = PagerModeNotFound{pager: p}
|
||||||
return
|
return
|
||||||
|
Loading…
Reference in New Issue
Block a user