packfile: small optimizations for findMatch and matchLength

Signed-off-by: Miguel Molina <miguel@erizocosmi.co>
diff --git a/plumbing/format/packfile/delta_index.go b/plumbing/format/packfile/delta_index.go
index fad9dc8..349bedf 100644
--- a/plumbing/format/packfile/delta_index.go
+++ b/plumbing/format/packfile/delta_index.go
@@ -19,7 +19,19 @@
 	idx.copyEntries(scanner)
 }
 
+// findMatch returns the offset of src where the block starting at tgtOffset
+// is and the length of the match. A length of 0 means there was no match. A
+// length of -1 means the src length is lower than the blksz and whatever
+// other positive length is the length of the match in bytes.
 func (idx *deltaIndex) findMatch(src, tgt []byte, tgtOffset int) (srcOffset, l int) {
+	if len(tgt) < tgtOffset+s {
+		return 0, len(tgt) - tgtOffset
+	}
+
+	if len(src) < blksz {
+		return 0, -1
+	}
+
 	if len(tgt) >= tgtOffset+s && len(src) >= blksz {
 		h := hashBlock(tgt, tgtOffset)
 		tIdx := h & idx.mask
@@ -36,6 +48,17 @@
 	return
 }
 
+func matchLength(src, tgt []byte, otgt, osrc int) (l int) {
+	lensrc := len(src)
+	lentgt := len(tgt)
+	for (osrc < lensrc && otgt < lentgt) && src[osrc] == tgt[otgt] {
+		l++
+		osrc++
+		otgt++
+	}
+	return
+}
+
 func countEntries(scan *deltaIndexScanner) (cnt int) {
 	// Figure out exactly how many entries we need. As we do the
 	// enumeration truncate any delta chains longer than what we
diff --git a/plumbing/format/packfile/diff_delta.go b/plumbing/format/packfile/diff_delta.go
index 2e58ec6..d4b207a 100644
--- a/plumbing/format/packfile/diff_delta.go
+++ b/plumbing/format/packfile/diff_delta.go
@@ -81,8 +81,22 @@
 	for i := 0; i < len(tgt); i++ {
 		offset, l := index.findMatch(src, tgt, i)
 
-		if l < s {
+		if l == 0 {
+			// couldn't find a match, just write the current byte and continue
 			ibuf.WriteByte(tgt[i])
+		} else if l < 0 {
+			// src is less than blksz, copy the rest of the target to avoid
+			// calls to findMatch
+			for ; i < len(tgt); i++ {
+				ibuf.WriteByte(tgt[i])
+			}
+		} else if l < s {
+			// remaining target is less than blksz, copy what's left of it
+			// and avoid calls to findMatch
+			for j := i; j < i+l; j++ {
+				ibuf.WriteByte(tgt[j])
+			}
+			i += l - 1
 		} else {
 			encodeInsertOperation(ibuf, buf)
 
@@ -135,21 +149,6 @@
 	ibuf.Reset()
 }
 
-func matchLength(src, tgt []byte, otgt, osrc int) int {
-	l := 0
-	for {
-		if (osrc >= len(src) || otgt >= len(tgt)) || src[osrc] != tgt[otgt] {
-			break
-		}
-
-		l++
-		osrc++
-		otgt++
-	}
-
-	return l
-}
-
 func deltaEncodeSize(size int) []byte {
 	var ret []byte
 	c := size & 0x7f