mirror of
https://github.com/go-gitea/gitea.git
synced 2026-04-14 19:46:28 +00:00
refactor: ParseCatFileTreeLine returns slices from ReadBytes, remove pre-provided buffers
Replace the three caller-provided buffer parameters (modeBuf, fnameBuf, shaBuf)
with internal allocation. Use rd.ReadBytes('\x00') to read mode+fname in one
call and slice the result directly. Allocate sha internally. Update both callers
(catBatchParseTreeEntries and lfs_nogogit.go) to drop the buffer setup.
Co-Authored-By: GitHub Copilot <copilot@github.com>
Agent-Logs-Url: https://github.com/go-gitea/gitea/sessions/43dab9a5-8c12-41c7-8da6-77c268a65ada
Co-authored-by: wxiaoguang <2114189+wxiaoguang@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
d284f5c798
commit
4bece1feb4
@@ -179,18 +179,14 @@ headerLoop:
|
||||
// Therefore we need some method to convert these binary hashes to hex hashes
|
||||
|
||||
// ParseCatFileTreeLine reads an entry from a tree in a cat-file --batch stream
|
||||
// This carefully avoids allocations - except where fnameBuf is too small.
|
||||
// It is recommended therefore to pass in an fnameBuf large enough to avoid almost all allocations
|
||||
//
|
||||
// Each line is composed of:
|
||||
// <mode-in-ascii-dropping-initial-zeros> SP <fname> NUL <binary HASH>
|
||||
//
|
||||
// We don't attempt to convert the raw HASH to save a lot of time
|
||||
func ParseCatFileTreeLine(objectFormat ObjectFormat, rd BufferedReader, modeBuf, fnameBuf, shaBuf []byte) (mode, fname, sha []byte, n int, err error) {
|
||||
var readBytes []byte
|
||||
|
||||
// Read the Mode & fname
|
||||
readBytes, err = rd.ReadSlice('\x00')
|
||||
func ParseCatFileTreeLine(objectFormat ObjectFormat, rd BufferedReader) (mode, fname, sha []byte, n int, err error) {
|
||||
// Read the mode and fname up to and including the NUL separator
|
||||
readBytes, err := rd.ReadBytes('\x00')
|
||||
if err != nil {
|
||||
return mode, fname, sha, n, err
|
||||
}
|
||||
@@ -200,48 +196,23 @@ func ParseCatFileTreeLine(objectFormat ObjectFormat, rd BufferedReader, modeBuf,
|
||||
return mode, fname, sha, n, &ErrNotExist{}
|
||||
}
|
||||
|
||||
n += idx + 1
|
||||
copy(modeBuf, readBytes[:idx])
|
||||
if len(modeBuf) >= idx {
|
||||
modeBuf = modeBuf[:idx]
|
||||
} else {
|
||||
modeBuf = append(modeBuf, readBytes[len(modeBuf):idx]...)
|
||||
}
|
||||
mode = modeBuf
|
||||
mode = readBytes[:idx]
|
||||
fname = readBytes[idx+1 : len(readBytes)-1] // trim the NUL terminator
|
||||
n = len(readBytes)
|
||||
|
||||
readBytes = readBytes[idx+1:]
|
||||
|
||||
// Deal with the fname
|
||||
copy(fnameBuf, readBytes)
|
||||
if len(fnameBuf) > len(readBytes) {
|
||||
fnameBuf = fnameBuf[:len(readBytes)]
|
||||
} else {
|
||||
fnameBuf = append(fnameBuf, readBytes[len(fnameBuf):]...)
|
||||
}
|
||||
for err == bufio.ErrBufferFull {
|
||||
readBytes, err = rd.ReadSlice('\x00')
|
||||
fnameBuf = append(fnameBuf, readBytes...)
|
||||
}
|
||||
n += len(fnameBuf)
|
||||
if err != nil {
|
||||
return mode, fname, sha, n, err
|
||||
}
|
||||
fnameBuf = fnameBuf[:len(fnameBuf)-1]
|
||||
fname = fnameBuf
|
||||
|
||||
// Deal with the binary hash
|
||||
idx = 0
|
||||
// Read the binary hash
|
||||
length := objectFormat.FullLength() / 2
|
||||
sha = make([]byte, length)
|
||||
idx = 0
|
||||
for idx < length {
|
||||
var read int
|
||||
read, err = rd.Read(shaBuf[idx:length])
|
||||
read, err = rd.Read(sha[idx:length])
|
||||
n += read
|
||||
if err != nil {
|
||||
return mode, fname, sha, n, err
|
||||
}
|
||||
idx += read
|
||||
}
|
||||
sha = shaBuf
|
||||
return mode, fname, sha, n, err
|
||||
}
|
||||
|
||||
|
||||
@@ -47,14 +47,11 @@ func parseTreeEntries(data []byte, ptree *Tree) ([]*TreeEntry, error) {
|
||||
}
|
||||
|
||||
func catBatchParseTreeEntries(objectFormat ObjectFormat, ptree *Tree, rd BufferedReader, sz int64) ([]*TreeEntry, error) {
|
||||
fnameBuf := make([]byte, 4096)
|
||||
modeBuf := make([]byte, 40)
|
||||
shaBuf := make([]byte, objectFormat.FullLength())
|
||||
entries := make([]*TreeEntry, 0, 10)
|
||||
|
||||
loop:
|
||||
for sz > 0 {
|
||||
mode, fname, sha, count, err := ParseCatFileTreeLine(objectFormat, rd, modeBuf, fnameBuf, shaBuf)
|
||||
mode, fname, sha, count, err := ParseCatFileTreeLine(objectFormat, rd)
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break loop
|
||||
|
||||
@@ -46,10 +46,6 @@ func findLFSFileFunc(repo *git.Repository, objectID git.ObjectID, revListReader
|
||||
trees := []string{}
|
||||
paths := []string{}
|
||||
|
||||
fnameBuf := make([]byte, 4096)
|
||||
modeBuf := make([]byte, 40)
|
||||
workingShaBuf := make([]byte, objectID.Type().FullLength()/2)
|
||||
|
||||
for scan.Scan() {
|
||||
// Get the next commit ID
|
||||
commitID := scan.Text()
|
||||
@@ -93,7 +89,7 @@ func findLFSFileFunc(repo *git.Repository, objectID git.ObjectID, revListReader
|
||||
case "tree":
|
||||
var n int64
|
||||
for n < info.Size {
|
||||
mode, fname, binObjectID, count, err := git.ParseCatFileTreeLine(objectID.Type(), batchReader, modeBuf, fnameBuf, workingShaBuf)
|
||||
mode, fname, binObjectID, count, err := git.ParseCatFileTreeLine(objectID.Type(), batchReader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user