mirror of
https://github.com/minio/minio.git
synced 2025-11-09 13:39:46 -05:00
fs: drop Stat() call from fsDeleteFile,deleteFile (#4744)
This commit makes fsDeleteFile() simply call deleteFile() after calling the relevant path length checking functions. This DRYs the code base. This commit removes the Stat() call from deleteFile(). This improves performance and removes any possibility of a race condition. This additionally adds tests and a benchmark for said function. The results aren't very consistent, although I'd expect this commit to make it faster.
This commit is contained in:
committed by
Dee Koder
parent
0f401b67ad
commit
bccc386994
@@ -18,6 +18,7 @@ package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
@@ -263,50 +264,123 @@ func TestFSDeletes(t *testing.T) {
|
||||
t.Fatalf("Unable to create file, %s", err)
|
||||
}
|
||||
// Seek back.
|
||||
reader.Seek(0, 0)
|
||||
reader.Seek(0, io.SeekStart)
|
||||
|
||||
// folder is not empty
|
||||
err = fsMkdir(pathJoin(path, "success-vol", "not-empty"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = ioutil.WriteFile(pathJoin(path, "success-vol", "not-empty", "file"), []byte("data"), 0777)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// recursive
|
||||
if err = fsMkdir(pathJoin(path, "success-vol", "parent")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err = fsMkdir(pathJoin(path, "success-vol", "parent", "dir")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
basePath string
|
||||
srcVol string
|
||||
srcPath string
|
||||
expectedErr error
|
||||
}{
|
||||
// Test case - 1.
|
||||
// valid case with existing volume and file to delete.
|
||||
{
|
||||
basePath: path,
|
||||
srcVol: "success-vol",
|
||||
srcPath: "success-file",
|
||||
expectedErr: nil,
|
||||
},
|
||||
// Test case - 2.
|
||||
// The file was deleted in the last case, so DeleteFile should fail.
|
||||
{
|
||||
basePath: path,
|
||||
srcVol: "success-vol",
|
||||
srcPath: "success-file",
|
||||
expectedErr: errFileNotFound,
|
||||
},
|
||||
// Test case - 3.
|
||||
// Test case with segment of the volume name > 255.
|
||||
{
|
||||
basePath: path,
|
||||
srcVol: "my-obj-del-0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
|
||||
srcPath: "success-file",
|
||||
expectedErr: errFileNameTooLong,
|
||||
},
|
||||
// Test case - 4.
|
||||
// Test case with src path segment > 255.
|
||||
{
|
||||
basePath: path,
|
||||
srcVol: "success-vol",
|
||||
srcPath: "my-obj-del-0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
|
||||
expectedErr: errFileNameTooLong,
|
||||
},
|
||||
// Base path is way too long.
|
||||
{
|
||||
basePath: "path03333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333",
|
||||
srcVol: "success-vol",
|
||||
srcPath: "object",
|
||||
expectedErr: errFileNameTooLong,
|
||||
},
|
||||
// Directory is not empty. Should give nil, but won't delete.
|
||||
{
|
||||
basePath: path,
|
||||
srcVol: "success-vol",
|
||||
srcPath: "not-empty",
|
||||
expectedErr: nil,
|
||||
},
|
||||
// Should delete recursively.
|
||||
{
|
||||
basePath: path,
|
||||
srcVol: "success-vol",
|
||||
srcPath: pathJoin("parent", "dir"),
|
||||
expectedErr: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
if err = fsDeleteFile(path, pathJoin(path, testCase.srcVol, testCase.srcPath)); errorCause(err) != testCase.expectedErr {
|
||||
if err = fsDeleteFile(testCase.basePath, pathJoin(testCase.basePath, testCase.srcVol, testCase.srcPath)); errorCause(err) != testCase.expectedErr {
|
||||
t.Errorf("Test case %d: Expected: \"%s\", got: \"%s\"", i+1, testCase.expectedErr, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFSDeleteFile(b *testing.B) {
|
||||
// create posix test setup
|
||||
_, path, err := newPosixTestSetup()
|
||||
if err != nil {
|
||||
b.Fatalf("Unable to create posix test setup, %s", err)
|
||||
}
|
||||
defer removeAll(path)
|
||||
|
||||
// Setup test environment.
|
||||
if err = fsMkdir(pathJoin(path, "benchmark")); err != nil {
|
||||
b.Fatalf("Unable to create directory, %s", err)
|
||||
}
|
||||
|
||||
benchDir := pathJoin(path, "benchmark")
|
||||
filename := pathJoin(benchDir, "file.txt")
|
||||
|
||||
b.ResetTimer()
|
||||
// We need to create and delete the file sequentially inside the benchmark.
|
||||
for i := 0; i < b.N; i++ {
|
||||
b.StopTimer()
|
||||
err = ioutil.WriteFile(filename, []byte("data"), 0777)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.StartTimer()
|
||||
|
||||
err = fsDeleteFile(benchDir, filename)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests fs removes.
|
||||
func TestFSRemoves(t *testing.T) {
|
||||
// create posix test setup
|
||||
|
||||
Reference in New Issue
Block a user