aboutsummaryrefslogtreecommitdiffstats
path: root/plumbing
diff options
context:
space:
mode:
authorMiguel Molina <miguel@erizocosmi.co>2017-09-07 12:02:52 +0200
committerMiguel Molina <miguel@erizocosmi.co>2017-09-07 12:02:52 +0200
commit6d486b4f996c8abffd3206590303d38381a3dca8 (patch)
tree174a34ac3da35cf72633c514c1f67aa50dfb4af9 /plumbing
parent90418e6ab682d1888dd7658a8ebd72a7be8cf502 (diff)
downloadgo-git-6d486b4f996c8abffd3206590303d38381a3dca8.tar.gz
packfile: small optimizations for findMatch and matchLength
Signed-off-by: Miguel Molina <miguel@erizocosmi.co>
Diffstat (limited to 'plumbing')
-rw-r--r--plumbing/format/packfile/delta_index.go23
-rw-r--r--plumbing/format/packfile/diff_delta.go31
2 files changed, 38 insertions, 16 deletions
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 @@ func (idx *deltaIndex) init(buf []byte) {
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 @@ func (idx *deltaIndex) findMatch(src, tgt []byte, tgtOffset int) (srcOffset, l i
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 @@ func diffDelta(index *deltaIndex, src []byte, tgt []byte) []byte {
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 @@ func encodeInsertOperation(ibuf, buf *bytes.Buffer) {
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