Skip to content

Commit

Permalink
chore: optimize file reading (#4264)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevwan authored Jul 20, 2024
1 parent 9de04ee commit 0eec33f
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 14 deletions.
27 changes: 13 additions & 14 deletions core/filex/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,25 +61,26 @@ func lastLine(filename string, file *os.File) (string, error) {
return "", err
}

bf := int64(bufSize)
var last []byte
bufLen := int64(bufSize)
offset := info.Size()
for {
if offset < bufSize {
bf = offset

for offset > 0 {
if offset < bufLen {
bufLen = offset
offset = 0
} else {
offset -= bf
offset -= bufLen
}

buf := make([]byte, bf)
buf := make([]byte, bufLen)
n, err := file.ReadAt(buf, offset)
if err != nil && err != io.EOF {
return "", err
}

if n == 0 {
return "", nil
break
}

if buf[n-1] == '\n' {
Expand All @@ -89,16 +90,14 @@ func lastLine(filename string, file *os.File) (string, error) {
buf = buf[:n]
}

for n--; n >= 0; n-- {
if buf[n] == '\n' {
return string(append(buf[n+1:], last...)), nil
for i := n - 1; i >= 0; i-- {
if buf[i] == '\n' {
return string(append(buf[i+1:], last...)), nil
}
}

last = append(buf, last...)

if offset == 0 {
return string(last), nil
}
}

return string(last), nil
}
54 changes: 54 additions & 0 deletions core/filex/file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,57 @@ func TestLastLineEmptyFile(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, "", val)
}

func TestFirstLineExactlyBufSize(t *testing.T) {
content := make([]byte, bufSize)
for i := range content {
content[i] = 'a'
}
content[bufSize-1] = '\n' // Ensure there is a newline at the edge

filename, err := fs.TempFilenameWithText(string(content))
assert.Nil(t, err)
defer os.Remove(filename)

val, err := FirstLine(filename)
assert.Nil(t, err)
assert.Equal(t, string(content[:bufSize-1]), val)
}

func TestLastLineExactlyBufSize(t *testing.T) {
content := make([]byte, bufSize)
for i := range content {
content[i] = 'a'
}
content[bufSize-1] = '\n' // Ensure there is a newline at the edge

filename, err := fs.TempFilenameWithText(string(content))
assert.Nil(t, err)
defer os.Remove(filename)

val, err := LastLine(filename)
assert.Nil(t, err)
assert.Equal(t, string(content[:bufSize-1]), val)
}

func TestFirstLineLargeFile(t *testing.T) {
content := text + text + text + "\n" + "extra"
filename, err := fs.TempFilenameWithText(content)
assert.Nil(t, err)
defer os.Remove(filename)

val, err := FirstLine(filename)
assert.Nil(t, err)
assert.Equal(t, "first line", val)
}

func TestLastLineLargeFile(t *testing.T) {
content := text + text + text + "\n" + "extra"
filename, err := fs.TempFilenameWithText(content)
assert.Nil(t, err)
defer os.Remove(filename)

val, err := LastLine(filename)
assert.Nil(t, err)
assert.Equal(t, "extra", val)
}

0 comments on commit 0eec33f

Please sign in to comment.