Compare commits

...

3 Commits

Author SHA1 Message Date
Antoine GIRARD
c1768c5b64 Add some bench and little test 2018-07-05 01:19:23 +02:00
Kim "BKC" Carlbäcker
7635ba9038 make it compile 2018-07-05 00:33:49 +02:00
Kim "BKC" Carlbäcker
a79ae77156 Make ParsePatch more performant 2018-07-05 00:19:52 +02:00
3 changed files with 109 additions and 12 deletions

View File

@ -5,13 +5,13 @@
package integrations package integrations
import ( import (
"fmt"
"net/http" "net/http"
"testing" "testing"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
api "code.gitea.io/sdk/gitea" api "code.gitea.io/sdk/gitea"
"fmt"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )

View File

@ -248,31 +248,55 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
lineCount int lineCount int
curFileLinesCount int curFileLinesCount int
curFileLFSPrefix bool curFileLFSPrefix bool
input = bufio.NewReader(reader)
isEOF = false
) )
input := bufio.NewReader(reader)
isEOF := false
for !isEOF { for !isEOF {
var linebuf bytes.Buffer var linebuf bytes.Buffer
for { for {
b, err := input.ReadByte() peek, err := input.Peek(maxLineCharacters)
if err != nil && err != bufio.ErrBufferFull {
return nil, fmt.Errorf("PeekByte: %v", err)
}
newLine := bytes.IndexByte(peek, '\n')
if newLine == -1 {
// Instead of reading things, and copying memory around,
// we simply discard them (which doesn't allocate memory)
curFile.IsIncomplete = true
// We already know that we can read `len(peek)` amount of bytes,
// hence no error-checking
input.Discard(len(peek))
continue
}
if curFile.IsIncomplete {
// Since we get here without hiting the above case, we've found a newline
// and only discard that part.
input.Discard(newLine)
break
}
buff := make([]byte, newLine)
n, err := input.Read(buff)
if err != nil { if err != nil {
if err == io.EOF { if err == io.EOF {
isEOF = true isEOF = true
break break
} else {
return nil, fmt.Errorf("ReadByte: %v", err)
} }
return nil, fmt.Errorf("Read: %v", err)
}
if n != newLine {
return nil, fmt.Errorf("Read: could not read enough bytes %d != %d", n, newLine)
}
n, err = linebuf.Write(buff)
if err != nil {
return nil, fmt.Errorf("Write: %v", err)
}
if n != newLine {
return nil, fmt.Errorf("Write: could not write enough bytes %d != %d", n, newLine)
} }
if b == '\n' {
break break
} }
if linebuf.Len() < maxLineCharacters {
linebuf.WriteByte(b)
} else if linebuf.Len() == maxLineCharacters {
curFile.IsIncomplete = true
}
}
line := linebuf.String() line := linebuf.String()
if strings.HasPrefix(line, "+++ ") || strings.HasPrefix(line, "--- ") || len(line) == 0 { if strings.HasPrefix(line, "+++ ") || strings.HasPrefix(line, "--- ") || len(line) == 0 {

View File

@ -2,9 +2,13 @@ package models
import ( import (
"html/template" "html/template"
"strings"
"testing" "testing"
"code.gitea.io/gitea/modules/log"
dmp "github.com/sergi/go-diff/diffmatchpatch" dmp "github.com/sergi/go-diff/diffmatchpatch"
"github.com/stretchr/testify/assert"
) )
func assertEqual(t *testing.T, s1 string, s2 template.HTML) { func assertEqual(t *testing.T, s1 string, s2 template.HTML) {
@ -34,3 +38,72 @@ func TestDiffToHTML(t *testing.T) {
{Type: dmp.DiffEqual, Text: " biz"}, {Type: dmp.DiffEqual, Text: " biz"},
}, DiffLineDel)) }, DiffLineDel))
} }
func benchParsePatch(b *testing.B, diffStr string) {
log.DelLogger("console")
log.DelLogger("file")
b.ResetTimer() //Disable logger for becnh
for i := 0; i < b.N; i++ {
ParsePatch(1000, 5000, 100, strings.NewReader(diffStr))
}
}
func BenchmarkParsePatchSimple(b *testing.B) {
benchParsePatch(b, `diff --git a/integrations/api_issue_test.go b/integrations/api_issue_test.go
index 74436ffe9..ff316cec3 100644
--- a/integrations/api_issue_test.go
+++ b/integrations/api_issue_test.go
@@ -5,13 +5,13 @@
package integrations
import (
+ "fmt"
"net/http"
"testing"
"code.gitea.io/gitea/models"
api "code.gitea.io/sdk/gitea"
- "fmt"
"github.com/stretchr/testify/assert"
)
`)
}
func TestParsePatch(t *testing.T) {
testCases := []struct {
result error
files int
addition int
deletion int
diff string
}{
{nil, 1, 1, 1,
`diff --git a/integrations/api_issue_test.go b/integrations/api_issue_test.go
index 74436ffe9..ff316cec3 100644
--- a/integrations/api_issue_test.go
+++ b/integrations/api_issue_test.go
@@ -5,13 +5,13 @@
package integrations
import (
+ "fmt"
"net/http"
"testing"
"code.gitea.io/gitea/models"
api "code.gitea.io/sdk/gitea"
- "fmt"
"github.com/stretchr/testify/assert"
)
`},
}
for _, tc := range testCases {
diff, err := ParsePatch(1000, 5000, 100, strings.NewReader(tc.diff))
assert.Equal(t, tc.result, err)
assert.Equal(t, tc.files, diff.NumFiles())
assert.Equal(t, tc.addition, diff.TotalAddition)
assert.Equal(t, tc.deletion, diff.TotalDeletion)
}
}