readAllData: Reuse small file buffers (#13530)

(Re)use small buffers for small readAllData operations.
This commit is contained in:
Klaus Post 2021-10-28 17:02:22 -07:00 committed by GitHub
parent 2f1ee25f50
commit c603f85488
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 4 deletions

View File

@ -497,6 +497,8 @@ func (s *storageRESTServer) ReadAllHandler(w http.ResponseWriter, r *http.Reques
s.writeErrorResponse(w, err) s.writeErrorResponse(w, err)
return return
} }
// Reuse after return.
defer metaDataPoolPut(buf)
w.Header().Set(xhttp.ContentLength, strconv.Itoa(len(buf))) w.Header().Set(xhttp.ContentLength, strconv.Itoa(len(buf)))
w.Write(buf) w.Write(buf)
} }
@ -535,6 +537,7 @@ func (s *storageRESTServer) ReadFileHandler(w http.ResponseWriter, r *http.Reque
verifier = NewBitrotVerifier(BitrotAlgorithmFromString(vars[storageRESTBitrotAlgo]), hash) verifier = NewBitrotVerifier(BitrotAlgorithmFromString(vars[storageRESTBitrotAlgo]), hash)
} }
buf := make([]byte, length) buf := make([]byte, length)
defer metaDataPoolPut(buf) // Reuse if we can.
_, err = s.storage.ReadFile(r.Context(), volume, filePath, int64(offset), buf, verifier) _, err = s.storage.ReadFile(r.Context(), volume, filePath, int64(offset), buf, verifier)
if err != nil { if err != nil {
s.writeErrorResponse(w, err) s.writeErrorResponse(w, err)

View File

@ -859,6 +859,8 @@ func (s *xlStorage) DeleteVersion(ctx context.Context, volume, path string, fi F
// Create a new xl.meta with a delete marker in it // Create a new xl.meta with a delete marker in it
return s.WriteMetadata(ctx, volume, path, fi) return s.WriteMetadata(ctx, volume, path, fi)
} }
metaDataPoolPut(buf) // Never used, return it
buf, err = s.ReadAll(ctx, volume, pathJoin(path, xlStorageFormatFileV1)) buf, err = s.ReadAll(ctx, volume, pathJoin(path, xlStorageFormatFileV1))
if err != nil { if err != nil {
if err == errFileNotFound && fi.VersionID != "" { if err == errFileNotFound && fi.VersionID != "" {
@ -1232,12 +1234,29 @@ func (s *xlStorage) readAllData(volumeDir string, filePath string) (buf []byte,
SmallFile: true, SmallFile: true,
} }
defer r.Close() defer r.Close()
buf, err = ioutil.ReadAll(r)
// Get size for precise allocation.
stat, err := f.Stat()
if err != nil { if err != nil {
err = osErrToFileErr(err) buf, err = ioutil.ReadAll(r)
return buf, osErrToFileErr(err)
}
if stat.IsDir() {
return nil, errFileNotFound
} }
return buf, err // Read into appropriate buffer.
sz := stat.Size()
if sz <= metaDataReadDefault {
buf = metaDataPoolGet()
buf = buf[:sz]
} else {
buf = make([]byte, sz)
}
// Read file...
_, err = io.ReadFull(r, buf)
return buf, osErrToFileErr(err)
} }
// ReadAll reads from r until an error or EOF and returns the data it read. // ReadAll reads from r until an error or EOF and returns the data it read.

View File

@ -443,7 +443,8 @@ func TestXLStorageReadAll(t *testing.T) {
for i, testCase := range testCases { for i, testCase := range testCases {
dataRead, err = xlStorage.ReadAll(context.Background(), testCase.volume, testCase.path) dataRead, err = xlStorage.ReadAll(context.Background(), testCase.volume, testCase.path)
if err != testCase.err { if err != testCase.err {
t.Fatalf("TestXLStorage %d: Expected err \"%s\", got err \"%s\"", i+1, testCase.err, err) t.Errorf("TestXLStorage %d: Expected err \"%v\", got err \"%v\"", i+1, testCase.err, err)
continue
} }
if err == nil { if err == nil {
if string(dataRead) != string([]byte("Hello, World")) { if string(dataRead) != string([]byte("Hello, World")) {