shithub: hugo

Download patch

ref: a843ca53b5e0f29df9535fa0e88408a63cdc2cd7
parent: 02397e76cece28b467de30ff0cb0f471d9b212ee
author: HyeonGyu Lee <vazrupe@naver.com>
date: Tue Aug 6 20:46:20 EDT 2019

transform/urlreplacers: Cache the next position of `urlreplacer.prefix`

Improved performance due to `bytes.Index` repeated calls

Fixes #5942

--- a/transform/urlreplacers/absurlreplacer.go
+++ b/transform/urlreplacers/absurlreplacer.go
@@ -41,8 +41,30 @@
 	disabled bool
 	b        []byte
 	f        func(l *absurllexer)
+
+	nextPos int
 }
 
+func (p *prefix) find(bs []byte, start int) bool {
+	if p.disabled {
+		return false
+	}
+
+	if p.nextPos == -1 {
+		idx := bytes.Index(bs[start:], p.b)
+
+		if idx == -1 {
+			p.disabled = true
+			// Find the closest match
+			return false
+		}
+
+		p.nextPos = start + idx + len(p.b)
+	}
+
+	return true
+}
+
 func newPrefixState() []*prefix {
 	return []*prefix{
 		{b: []byte("src="), f: checkCandidateBase},
@@ -179,35 +201,28 @@
 			break
 		}
 
-		nextPos := -1
-
 		var match *prefix
 
 		for _, p := range prefixes {
-			if p.disabled {
+			if !p.find(l.content, l.pos) {
 				continue
 			}
-			idx := bytes.Index(l.content[l.pos:], p.b)
 
-			if idx == -1 {
-				p.disabled = true
-				// Find the closest match
-			} else if nextPos == -1 || idx < nextPos {
-				nextPos = idx
+			if match == nil || p.nextPos < match.nextPos {
 				match = p
 			}
 		}
 
-		if nextPos == -1 {
+		if match == nil {
 			// Done!
 			l.pos = contentLength
 			break
 		} else {
-			l.pos += nextPos + len(match.b)
+			l.pos = match.nextPos
+			match.nextPos = -1
 			match.f(l)
 		}
 	}
-
 	// Done!
 	if l.pos > l.start {
 		l.emit()