summaryrefslogtreecommitdiffstats
path: root/vendor/code.gitea.io
diff options
context:
space:
mode:
authorDuncan Ogilvie <mr.exodia.tpodt@gmail.com>2017-11-29 02:50:39 +0100
committerLunny Xiao <xiaolunwen@gmail.com>2017-11-29 09:50:39 +0800
commit551f3cbe420dcb72bcb784205451d5b01b811041 (patch)
tree612c505d8f46972a598e1ca118cba45c775f329d /vendor/code.gitea.io
parent4035ab05fa2d2c8ec95d346fea91cab8211dab17 (diff)
downloadgitea-551f3cbe420dcb72bcb784205451d5b01b811041.tar.gz
gitea-551f3cbe420dcb72bcb784205451d5b01b811041.zip
Memory usage improvements (#3013)
* govendor update code.gitea.io/git Signed-off-by: Duncan Ogilvie <mr.exodia.tpodt@gmail.com> * Greatly improve memory usage Signed-off-by: Duncan Ogilvie <mr.exodia.tpodt@gmail.com>
Diffstat (limited to 'vendor/code.gitea.io')
-rw-r--r--vendor/code.gitea.io/git/blob.go50
-rw-r--r--vendor/code.gitea.io/git/commit.go3
-rw-r--r--vendor/code.gitea.io/git/git.go2
3 files changed, 49 insertions, 6 deletions
diff --git a/vendor/code.gitea.io/git/blob.go b/vendor/code.gitea.io/git/blob.go
index 10b8ea4c9f..a6e392eeb5 100644
--- a/vendor/code.gitea.io/git/blob.go
+++ b/vendor/code.gitea.io/git/blob.go
@@ -6,7 +6,11 @@ package git
import (
"bytes"
+ "fmt"
"io"
+ "io/ioutil"
+ "os"
+ "os/exec"
)
// Blob represents a Git object.
@@ -18,14 +22,52 @@ type Blob struct {
// Data gets content of blob all at once and wrap it as io.Reader.
// This can be very slow and memory consuming for huge content.
func (b *Blob) Data() (io.Reader, error) {
- stdout, err := NewCommand("show", b.ID.String()).RunInDirBytes(b.repo.Path)
- if err != nil {
- return nil, err
+ stdout := new(bytes.Buffer)
+ stderr := new(bytes.Buffer)
+
+ // Preallocate memory to save ~50% memory usage on big files.
+ stdout.Grow(int(b.Size() + 2048))
+
+ if err := b.DataPipeline(stdout, stderr); err != nil {
+ return nil, concatenateError(err, stderr.String())
}
- return bytes.NewBuffer(stdout), nil
+ return stdout, nil
}
// DataPipeline gets content of blob and write the result or error to stdout or stderr
func (b *Blob) DataPipeline(stdout, stderr io.Writer) error {
return NewCommand("show", b.ID.String()).RunInDirPipeline(b.repo.Path, stdout, stderr)
}
+
+type cmdReadCloser struct {
+ cmd *exec.Cmd
+ stdout io.Reader
+}
+
+func (c cmdReadCloser) Read(p []byte) (int, error) {
+ return c.stdout.Read(p)
+}
+
+func (c cmdReadCloser) Close() error {
+ io.Copy(ioutil.Discard, c.stdout)
+ return c.cmd.Wait()
+}
+
+// DataAsync gets a ReadCloser for the contents of a blob without reading it all.
+// Calling the Close function on the result will discard all unread output.
+func (b *Blob) DataAsync() (io.ReadCloser, error) {
+ cmd := exec.Command("git", "show", b.ID.String())
+ cmd.Dir = b.repo.Path
+ cmd.Stderr = os.Stderr
+
+ stdout, err := cmd.StdoutPipe()
+ if err != nil {
+ return nil, fmt.Errorf("StdoutPipe: %v", err)
+ }
+
+ if err = cmd.Start(); err != nil {
+ return nil, fmt.Errorf("Start: %v", err)
+ }
+
+ return cmdReadCloser{stdout: stdout, cmd: cmd}, nil
+}
diff --git a/vendor/code.gitea.io/git/commit.go b/vendor/code.gitea.io/git/commit.go
index c295412381..299a2381b6 100644
--- a/vendor/code.gitea.io/git/commit.go
+++ b/vendor/code.gitea.io/git/commit.go
@@ -98,10 +98,11 @@ func (c *Commit) IsImageFile(name string) bool {
return false
}
- dataRc, err := blob.Data()
+ dataRc, err := blob.DataAsync()
if err != nil {
return false
}
+ defer dataRc.Close()
buf := make([]byte, 1024)
n, _ := dataRc.Read(buf)
buf = buf[:n]
diff --git a/vendor/code.gitea.io/git/git.go b/vendor/code.gitea.io/git/git.go
index 9ec20c97e1..150b80fb07 100644
--- a/vendor/code.gitea.io/git/git.go
+++ b/vendor/code.gitea.io/git/git.go
@@ -25,7 +25,7 @@ var (
// Prefix the log prefix
Prefix = "[git-module] "
// GitVersionRequired is the minimum Git version required
- GitVersionRequired = "1.8.1.6"
+ GitVersionRequired = "1.7.2"
)
func log(format string, args ...interface{}) {