Support bucket versioning (#9377)

- Implement a new xl.json 2.0.0 format to support,
  this moves the entire marshaling logic to POSIX
  layer, top layer always consumes a common FileInfo
  construct which simplifies the metadata reads.
- Implement list object versions
- Migrate to siphash from crchash for new deployments
  for object placements.

Fixes #2111
This commit is contained in:
Harshavardhana
2020-06-12 20:04:01 -07:00
committed by GitHub
parent 43d6e3ae06
commit 4915433bd2
203 changed files with 13833 additions and 6919 deletions

View File

@@ -27,24 +27,6 @@ import (
"time"
)
// Returns function "listDir" of the type listDirFunc.
// disks - used for doing disk.ListDir()
func listDirFactory(ctx context.Context, disk StorageAPI) ListDirFunc {
// Returns sorted merged entries from all the disks.
listDir := func(volume, dirPath, dirEntry string) (bool, []string) {
entries, err := disk.ListDir(volume, dirPath, -1, xlMetaJSONFile)
if err != nil {
return false, nil
}
if len(entries) == 0 {
return true, nil
}
sort.Strings(entries)
return false, filterMatchingPrefix(entries, dirEntry)
}
return listDir
}
// Fixed volume name that could be used across tests
const volume = "testvolume"
@@ -101,6 +83,22 @@ func createNamespace(disk StorageAPI, volume string, files []string) error {
return err
}
// Returns function "listDir" of the type listDirFunc.
// disks - used for doing disk.ListDir()
func listDirFactory(ctx context.Context, disk StorageAPI) ListDirFunc {
return func(volume, dirPath, dirEntry string) (emptyDir bool, entries []string) {
entries, err := disk.ListDir(volume, dirPath, -1)
if err != nil {
return false, nil
}
if len(entries) == 0 {
return true, nil
}
sort.Strings(entries)
return false, filterMatchingPrefix(entries, dirEntry)
}
}
// Test if tree walker returns entries matching prefix alone are received
// when a non empty prefix is supplied.
func testTreeWalkPrefix(t *testing.T, listDir ListDirFunc) {
@@ -237,66 +235,6 @@ func TestTreeWalkTimeout(t *testing.T) {
}
}
// Test ListDir - listDir is expected to only list one disk.
func TestListDir(t *testing.T) {
file1 := "file1"
file2 := "file2"
// Create two backend directories fsDir1 and fsDir2.
fsDir1, err := ioutil.TempDir(globalTestTmpDir, "minio-")
if err != nil {
t.Errorf("Unable to create tmp directory: %s", err)
}
fsDir2, err := ioutil.TempDir(globalTestTmpDir, "minio-")
if err != nil {
t.Errorf("Unable to create tmp directory: %s", err)
}
// Create two StorageAPIs disk1 and disk2.
endpoints := mustGetNewEndpoints(fsDir1)
disk1, err := newStorageAPI(endpoints[0])
if err != nil {
t.Errorf("Unable to create StorageAPI: %s", err)
}
endpoints = mustGetNewEndpoints(fsDir2)
disk2, err := newStorageAPI(endpoints[0])
if err != nil {
t.Errorf("Unable to create StorageAPI: %s", err)
}
// create listDir function.
listDir1 := listDirFactory(context.Background(), disk1)
listDir2 := listDirFactory(context.Background(), disk2)
// Create file1 in fsDir1 and file2 in fsDir2.
disks := []StorageAPI{disk1, disk2}
for i, disk := range disks {
err = createNamespace(disk, volume, []string{fmt.Sprintf("file%d", i+1)})
if err != nil {
t.Fatal(err)
}
}
// Should list "file1" from fsDir1.
_, entries := listDir1(volume, "", "")
if len(entries) != 1 {
t.Fatal("Expected the number of entries to be 1")
}
if entries[0] != file1 {
t.Fatal("Expected the entry to be file1")
}
_, entries = listDir2(volume, "", "")
if len(entries) != 1 {
t.Fatal("Expected the number of entries to be 1")
}
if entries[0] != file2 {
t.Fatal("Expected the entry to be file2")
}
}
// TestRecursiveWalk - tests if treeWalk returns entries correctly with and
// without recursively traversing prefixes.
func TestRecursiveTreeWalk(t *testing.T) {