mirror of
https://github.com/minio/minio.git
synced 2025-11-22 10:37:42 -05:00
optimize listObjects to list only from 3 random disks (#9184)
This commit is contained in:
@@ -592,20 +592,16 @@ func (z *xlZones) listObjectsNonSlash(ctx context.Context, bucket, prefix, marke
|
||||
endWalkCh := make(chan struct{})
|
||||
defer close(endWalkCh)
|
||||
|
||||
const ndisks = 3
|
||||
for _, zone := range z.zones {
|
||||
zonesEntryChs = append(zonesEntryChs,
|
||||
zone.startMergeWalks(ctx, bucket, prefix, "", true, endWalkCh))
|
||||
zone.startMergeWalksN(ctx, bucket, prefix, "", true, endWalkCh, ndisks))
|
||||
}
|
||||
|
||||
var objInfos []ObjectInfo
|
||||
var eof bool
|
||||
var prevPrefix string
|
||||
|
||||
var zoneDrivesPerSet []int
|
||||
for _, zone := range z.zones {
|
||||
zoneDrivesPerSet = append(zoneDrivesPerSet, zone.drivesPerSet)
|
||||
}
|
||||
|
||||
var zonesEntriesInfos [][]FileInfo
|
||||
var zonesEntriesValid [][]bool
|
||||
for _, entryChs := range zonesEntryChs {
|
||||
@@ -617,18 +613,15 @@ func (z *xlZones) listObjectsNonSlash(ctx context.Context, bucket, prefix, marke
|
||||
if len(objInfos) == maxKeys {
|
||||
break
|
||||
}
|
||||
result, quorumCount, zoneIndex, ok := leastEntryZone(zonesEntryChs, zonesEntriesInfos, zonesEntriesValid)
|
||||
|
||||
result, quorumCount, _, ok := leastEntryZone(zonesEntryChs, zonesEntriesInfos, zonesEntriesValid)
|
||||
if !ok {
|
||||
eof = true
|
||||
break
|
||||
}
|
||||
rquorum := result.Quorum
|
||||
// Quorum is zero for all directories.
|
||||
if rquorum == 0 {
|
||||
// Choose N/2 quorum for directory entries.
|
||||
rquorum = zoneDrivesPerSet[zoneIndex] / 2
|
||||
}
|
||||
if quorumCount < rquorum {
|
||||
|
||||
if quorumCount < ndisks-1 {
|
||||
// Skip entries which are not found on upto ndisks.
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -704,7 +697,7 @@ func (z *xlZones) listObjectsNonSlash(ctx context.Context, bucket, prefix, marke
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (z *xlZones) listObjects(ctx context.Context, bucket, prefix, marker, delimiter string, maxKeys int, heal bool) (ListObjectsInfo, error) {
|
||||
func (z *xlZones) listObjects(ctx context.Context, bucket, prefix, marker, delimiter string, maxKeys int) (ListObjectsInfo, error) {
|
||||
loi := ListObjectsInfo{}
|
||||
|
||||
if err := checkListObjsArgs(ctx, bucket, prefix, marker, z); err != nil {
|
||||
@@ -752,22 +745,18 @@ func (z *xlZones) listObjects(ctx context.Context, bucket, prefix, marker, delim
|
||||
var zonesEntryChs [][]FileInfoCh
|
||||
var zonesEndWalkCh []chan struct{}
|
||||
|
||||
const ndisks = 3
|
||||
for _, zone := range z.zones {
|
||||
entryChs, endWalkCh := zone.pool.Release(listParams{bucket, recursive, marker, prefix})
|
||||
if entryChs == nil {
|
||||
endWalkCh = make(chan struct{})
|
||||
entryChs = zone.startMergeWalks(ctx, bucket, prefix, marker, recursive, endWalkCh)
|
||||
entryChs = zone.startMergeWalksN(ctx, bucket, prefix, marker, recursive, endWalkCh, ndisks)
|
||||
}
|
||||
zonesEntryChs = append(zonesEntryChs, entryChs)
|
||||
zonesEndWalkCh = append(zonesEndWalkCh, endWalkCh)
|
||||
}
|
||||
|
||||
var zoneDrivesPerSet []int
|
||||
for _, zone := range z.zones {
|
||||
zoneDrivesPerSet = append(zoneDrivesPerSet, zone.drivesPerSet)
|
||||
}
|
||||
|
||||
entries := mergeZonesEntriesCh(zonesEntryChs, maxKeys, zoneDrivesPerSet, heal)
|
||||
entries := mergeZonesEntriesCh(zonesEntryChs, maxKeys, ndisks)
|
||||
if len(entries.Files) == 0 {
|
||||
return loi, nil
|
||||
}
|
||||
@@ -873,7 +862,7 @@ func leastEntryZone(zoneEntryChs [][]FileInfoCh, zoneEntries [][]FileInfo, zoneE
|
||||
}
|
||||
|
||||
// mergeZonesEntriesCh - merges FileInfo channel to entries upto maxKeys.
|
||||
func mergeZonesEntriesCh(zonesEntryChs [][]FileInfoCh, maxKeys int, zoneDrives []int, heal bool) (entries FilesInfo) {
|
||||
func mergeZonesEntriesCh(zonesEntryChs [][]FileInfoCh, maxKeys int, ndisks int) (entries FilesInfo) {
|
||||
var i = 0
|
||||
var zonesEntriesInfos [][]FileInfo
|
||||
var zonesEntriesValid [][]bool
|
||||
@@ -882,32 +871,17 @@ func mergeZonesEntriesCh(zonesEntryChs [][]FileInfoCh, maxKeys int, zoneDrives [
|
||||
zonesEntriesValid = append(zonesEntriesValid, make([]bool, len(entryChs)))
|
||||
}
|
||||
for {
|
||||
fi, quorumCount, zoneIndex, valid := leastEntryZone(zonesEntryChs, zonesEntriesInfos, zonesEntriesValid)
|
||||
if !valid {
|
||||
fi, quorumCount, _, ok := leastEntryZone(zonesEntryChs, zonesEntriesInfos, zonesEntriesValid)
|
||||
if !ok {
|
||||
// We have reached EOF across all entryChs, break the loop.
|
||||
break
|
||||
}
|
||||
rquorum := fi.Quorum
|
||||
// Quorum is zero for all directories.
|
||||
if rquorum == 0 {
|
||||
// Choose N/2 quoroum for directory entries.
|
||||
rquorum = zoneDrives[zoneIndex] / 2
|
||||
|
||||
if quorumCount < ndisks-1 {
|
||||
// Skip entries which are not found on upto ndisks.
|
||||
continue
|
||||
}
|
||||
|
||||
if heal {
|
||||
// When healing is enabled, we should
|
||||
// list only objects which need healing.
|
||||
if quorumCount == zoneDrives[zoneIndex] {
|
||||
// Skip good entries.
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
// Regular listing, we skip entries not in quorum.
|
||||
if quorumCount < rquorum {
|
||||
// Skip entries which do not have quorum.
|
||||
continue
|
||||
}
|
||||
}
|
||||
entries.Files = append(entries.Files, fi)
|
||||
i++
|
||||
if i == maxKeys {
|
||||
@@ -953,7 +927,7 @@ func (z *xlZones) ListObjects(ctx context.Context, bucket, prefix, marker, delim
|
||||
return z.zones[0].ListObjects(ctx, bucket, prefix, marker, delimiter, maxKeys)
|
||||
}
|
||||
|
||||
return z.listObjects(ctx, bucket, prefix, marker, delimiter, maxKeys, false)
|
||||
return z.listObjects(ctx, bucket, prefix, marker, delimiter, maxKeys)
|
||||
}
|
||||
|
||||
func (z *xlZones) ListMultipartUploads(ctx context.Context, bucket, prefix, keyMarker, uploadIDMarker, delimiter string, maxUploads int) (ListMultipartsInfo, error) {
|
||||
|
||||
Reference in New Issue
Block a user