From cc83fc96cb09b2210c7ec8f5846e617d3c05e396 Mon Sep 17 00:00:00 2001 From: Chris Schinnerl Date: Thu, 15 Feb 2024 14:26:25 +0100 Subject: [PATCH 01/10] stores: improve performance of objects stats --- stores/metadata.go | 63 ++++++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/stores/metadata.go b/stores/metadata.go index 68947ed95..39a053528 100644 --- a/stores/metadata.go +++ b/stores/metadata.go @@ -584,11 +584,18 @@ func (s *SQLStore) ListBuckets(ctx context.Context) ([]api.Bucket, error) { // within a single transaction. func (s *SQLStore) ObjectsStats(ctx context.Context, opts api.ObjectsStatsOpts) (api.ObjectsStatsResponse, error) { // if no bucket is specified, we consider all objects + var bucketID uint + if opts.Bucket != "" { + err := s.db.Model(&dbBucket{}).Select("id").Where("name = ?", opts.Bucket).Take(&bucketID).Error + if err != nil { + return api.ObjectsStatsResponse{}, err + } + } whereBucket := func(table string) clause.Expr { if opts.Bucket == "" { return exprTRUE } - return sqlWhereBucket(table, opts.Bucket) + return gorm.Expr(fmt.Sprintf("%s.db_bucket_id = ?", table), bucketID) } // number of objects @@ -632,37 +639,49 @@ func (s *SQLStore) ObjectsStats(ctx context.Context, opts api.ObjectsStatsOpts) return api.ObjectsStatsResponse{}, err } - fromContractSectors := gorm.Expr("contract_sectors cs") + fromContractSectors := gorm.Expr("contract_sectors cs WHERE 1=1") if opts.Bucket != "" { fromContractSectors = gorm.Expr(` contract_sectors cs INNER JOIN sectors s ON s.id = cs.db_sector_id INNER JOIN slabs sla ON sla.id = s.db_slab_id - INNER JOIN slices sli ON sli.db_slab_id = sla.id - INNER JOIN objects o ON o.id = sli.db_object_id AND (?) - `, whereBucket("o")) + WHERE EXISTS ( + SELECT 1 FROM slices sli + INNER JOIN objects o ON o.id = sli.db_object_id + WHERE sli.db_slab_id = sla.id AND o.db_bucket_id = ? + ) + `, bucketID) } var totalSectors uint64 - batchSize := 500000 - marker := uint64(0) - for offset := 0; ; offset += batchSize { - var result struct { - Sectors uint64 - Marker uint64 - } - res := s.db. - Model(&dbSector{}). - Raw("SELECT COUNT(*) as Sectors, MAX(sectors.db_sector_id) as Marker FROM (SELECT cs.db_sector_id FROM ? WHERE cs.db_sector_id > ? GROUP BY cs.db_sector_id LIMIT ?) sectors", fromContractSectors, marker, batchSize). - Scan(&result) - if err := res.Error; err != nil { - return api.ObjectsStatsResponse{}, err - } else if result.Sectors == 0 { - break // done + var sectorsInfo struct { + MinID uint + MaxID uint + Total uint + } + err = s.db.Model(&dbContractSector{}). + Raw("SELECT MIN(db_sector_id) as MinID, MAX(db_sector_id) as MaxID, COUNT(*) as Total FROM contract_sectors"). + Scan(§orsInfo).Error + if err != nil { + return api.ObjectsStatsResponse{}, err + } + + // compute a good batch size for the ids + batchSize := (sectorsInfo.MaxID - sectorsInfo.MinID) / (sectorsInfo.Total/500000 + 1) + + if sectorsInfo.Total > 0 { + for from, to := sectorsInfo.MinID, sectorsInfo.MinID+batchSize; from <= sectorsInfo.MaxID; from, to = to, to+batchSize { + var nSectors uint64 + err := s.db. + Model(&dbSector{}). + Raw("SELECT COUNT(DISTINCT cs.db_sector_id) FROM ? AND cs.db_sector_id >= ? AND cs.db_sector_id < ?", fromContractSectors, from, to). + Scan(&nSectors).Error + if err != nil { + return api.ObjectsStatsResponse{}, err + } + totalSectors += nSectors } - totalSectors += result.Sectors - marker = result.Marker } var totalUploaded int64 From 159276068278a4d3759ae034fe6fb7675da4ad53 Mon Sep 17 00:00:00 2001 From: Chris Schinnerl Date: Thu, 15 Feb 2024 14:51:50 +0100 Subject: [PATCH 02/10] stores: use select count with subquery --- stores/metadata.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stores/metadata.go b/stores/metadata.go index 39a053528..cfd417dbb 100644 --- a/stores/metadata.go +++ b/stores/metadata.go @@ -675,7 +675,7 @@ func (s *SQLStore) ObjectsStats(ctx context.Context, opts api.ObjectsStatsOpts) var nSectors uint64 err := s.db. Model(&dbSector{}). - Raw("SELECT COUNT(DISTINCT cs.db_sector_id) FROM ? AND cs.db_sector_id >= ? AND cs.db_sector_id < ?", fromContractSectors, from, to). + Raw("SELECT COUNT(*) FROM (SELECT DISTINCT cs.db_sector_id FROM ? AND cs.db_sector_id >= ? AND cs.db_sector_id < ?)", fromContractSectors, from, to). Scan(&nSectors).Error if err != nil { return api.ObjectsStatsResponse{}, err From 47a91acb19203b6ed889bbbfe77e6a95eda22018 Mon Sep 17 00:00:00 2001 From: Chris Schinnerl Date: Thu, 15 Feb 2024 15:55:17 +0100 Subject: [PATCH 03/10] stores: use sectors table and don't filter sectors stats by bucket --- stores/metadata.go | 49 +++++------------------------------------ stores/metadata_test.go | 8 +++---- 2 files changed, 10 insertions(+), 47 deletions(-) diff --git a/stores/metadata.go b/stores/metadata.go index cfd417dbb..c2e07ed00 100644 --- a/stores/metadata.go +++ b/stores/metadata.go @@ -639,54 +639,17 @@ func (s *SQLStore) ObjectsStats(ctx context.Context, opts api.ObjectsStatsOpts) return api.ObjectsStatsResponse{}, err } - fromContractSectors := gorm.Expr("contract_sectors cs WHERE 1=1") - if opts.Bucket != "" { - fromContractSectors = gorm.Expr(` - contract_sectors cs - INNER JOIN sectors s ON s.id = cs.db_sector_id - INNER JOIN slabs sla ON sla.id = s.db_slab_id - WHERE EXISTS ( - SELECT 1 FROM slices sli - INNER JOIN objects o ON o.id = sli.db_object_id - WHERE sli.db_slab_id = sla.id AND o.db_bucket_id = ? - ) - `, bucketID) - } - - var totalSectors uint64 - - var sectorsInfo struct { - MinID uint - MaxID uint - Total uint - } - err = s.db.Model(&dbContractSector{}). - Raw("SELECT MIN(db_sector_id) as MinID, MAX(db_sector_id) as MaxID, COUNT(*) as Total FROM contract_sectors"). - Scan(§orsInfo).Error + var totalSectors int64 + err = s.db. + Model(&dbSector{}). + Count(&totalSectors).Error if err != nil { return api.ObjectsStatsResponse{}, err } - // compute a good batch size for the ids - batchSize := (sectorsInfo.MaxID - sectorsInfo.MinID) / (sectorsInfo.Total/500000 + 1) - - if sectorsInfo.Total > 0 { - for from, to := sectorsInfo.MinID, sectorsInfo.MinID+batchSize; from <= sectorsInfo.MaxID; from, to = to, to+batchSize { - var nSectors uint64 - err := s.db. - Model(&dbSector{}). - Raw("SELECT COUNT(*) FROM (SELECT DISTINCT cs.db_sector_id FROM ? AND cs.db_sector_id >= ? AND cs.db_sector_id < ?)", fromContractSectors, from, to). - Scan(&nSectors).Error - if err != nil { - return api.ObjectsStatsResponse{}, err - } - totalSectors += nSectors - } - } - var totalUploaded int64 err = s.db. - Table("?", fromContractSectors). + Model(&dbContractSector{}). Count(&totalUploaded). Error if err != nil { @@ -699,7 +662,7 @@ func (s *SQLStore) ObjectsStats(ctx context.Context, opts api.ObjectsStatsOpts) NumUnfinishedObjects: unfinishedObjects, TotalUnfinishedObjectsSize: totalUnfinishedObjectsSize, TotalObjectsSize: objInfo.TotalObjectsSize, - TotalSectorsSize: totalSectors * rhpv2.SectorSize, + TotalSectorsSize: uint64(totalSectors) * rhpv2.SectorSize, TotalUploadedSize: uint64(totalUploaded) * rhpv2.SectorSize, }, nil } diff --git a/stores/metadata_test.go b/stores/metadata_test.go index a05c0be17..2d550c1d6 100644 --- a/stores/metadata_test.go +++ b/stores/metadata_test.go @@ -2524,10 +2524,10 @@ func TestObjectsStats(t *testing.T) { t.Fatal(err) } else if info.TotalObjectsSize != 0 { t.Fatal("wrong size", info.TotalObjectsSize) - } else if info.TotalSectorsSize != 0 { - t.Fatal("wrong size", info.TotalSectorsSize) - } else if info.TotalUploadedSize != 0 { - t.Fatal("wrong size", info.TotalUploadedSize) + } else if info.TotalSectorsSize != sectorsSize { + t.Fatal("wrong size", info.TotalSectorsSize, sectorsSize) + } else if info.TotalUploadedSize != sectorsSize*2 { + t.Fatal("wrong size", info.TotalUploadedSize, sectorsSize*2) } else if info.NumObjects != 0 { t.Fatal("wrong number of objects", info.NumObjects) } From 3e463cfb4f7103d976ca2d84bb4baeee9438d067 Mon Sep 17 00:00:00 2001 From: Chris Schinnerl Date: Thu, 15 Feb 2024 16:04:48 +0100 Subject: [PATCH 04/10] stores: use sum over total shards --- stores/metadata.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stores/metadata.go b/stores/metadata.go index c2e07ed00..aae62073d 100644 --- a/stores/metadata.go +++ b/stores/metadata.go @@ -641,8 +641,9 @@ func (s *SQLStore) ObjectsStats(ctx context.Context, opts api.ObjectsStatsOpts) var totalSectors int64 err = s.db. - Model(&dbSector{}). - Count(&totalSectors).Error + Model(&dbSlab{}). + Select("COALESCE(SUM(total_shards), 0)"). + Scan(&totalSectors).Error if err != nil { return api.ObjectsStatsResponse{}, err } From 3f6dad71c9ac5add056534d4d8d6da0f18b68837 Mon Sep 17 00:00:00 2001 From: Chris Schinnerl Date: Thu, 15 Feb 2024 17:06:29 +0100 Subject: [PATCH 05/10] stores: use contract size for total uploaded size --- stores/metadata.go | 24 ++++++++++++++++++++---- stores/metadata_test.go | 19 +++++++++++-------- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/stores/metadata.go b/stores/metadata.go index aae62073d..3f13097ad 100644 --- a/stores/metadata.go +++ b/stores/metadata.go @@ -639,9 +639,18 @@ func (s *SQLStore) ObjectsStats(ctx context.Context, opts api.ObjectsStatsOpts) return api.ObjectsStatsResponse{}, err } + fromSlabs := gorm.Expr("slabs sla") + if opts.Bucket != "" { + fromSlabs = gorm.Expr(` + slabs sla + INNER JOIN slices sli ON sli.db_slab_id = sla.id + INNER JOIN objects o ON o.id = sli.db_object_id AND (?) + `, whereBucket("o")) + } + var totalSectors int64 err = s.db. - Model(&dbSlab{}). + Table("?", fromSlabs). Select("COALESCE(SUM(total_shards), 0)"). Scan(&totalSectors).Error if err != nil { @@ -650,13 +659,20 @@ func (s *SQLStore) ObjectsStats(ctx context.Context, opts api.ObjectsStatsOpts) var totalUploaded int64 err = s.db. - Model(&dbContractSector{}). - Count(&totalUploaded). + Model(&dbContract{}). + Select("COALESCE(SUM(size), 0)"). + Scan(&totalUploaded). Error if err != nil { return api.ObjectsStatsResponse{}, err } + var contracts []dbContract + err = s.db.Find(&contracts).Error + if err != nil { + return api.ObjectsStatsResponse{}, err + } + return api.ObjectsStatsResponse{ MinHealth: objInfo.MinHealth, NumObjects: objInfo.NumObjects, @@ -664,7 +680,7 @@ func (s *SQLStore) ObjectsStats(ctx context.Context, opts api.ObjectsStatsOpts) TotalUnfinishedObjectsSize: totalUnfinishedObjectsSize, TotalObjectsSize: objInfo.TotalObjectsSize, TotalSectorsSize: uint64(totalSectors) * rhpv2.SectorSize, - TotalUploadedSize: uint64(totalUploaded) * rhpv2.SectorSize, + TotalUploadedSize: uint64(totalUploaded), }, nil } diff --git a/stores/metadata_test.go b/stores/metadata_test.go index 2d550c1d6..da9ecbbef 100644 --- a/stores/metadata_test.go +++ b/stores/metadata_test.go @@ -2446,6 +2446,7 @@ func TestObjectsStats(t *testing.T) { // Create a few objects of different size. var objectsSize uint64 var sectorsSize uint64 + var totalUploadedSize uint64 for i := 0; i < 2; i++ { obj := newTestObject(1) objectsSize += uint64(obj.TotalSize()) @@ -2458,10 +2459,11 @@ func TestObjectsStats(t *testing.T) { t.Fatal(err) } for _, fcid := range fcids { - _, err := ss.addTestContract(fcid, hpk) + c, err := ss.addTestContract(fcid, hpk) if err != nil { t.Fatal(err) } + totalUploadedSize += c.Size } } } @@ -2482,10 +2484,11 @@ func TestObjectsStats(t *testing.T) { } var newContractID types.FileContractID frand.Read(newContractID[:]) - _, err = ss.addTestContract(newContractID, types.PublicKey{}) + c, err := ss.addTestContract(newContractID, types.PublicKey{}) if err != nil { t.Fatal(err) } + totalUploadedSize += c.Size newContract, err := ss.contract(context.Background(), fileContractID(newContractID)) if err != nil { t.Fatal(err) @@ -2510,8 +2513,8 @@ func TestObjectsStats(t *testing.T) { t.Fatal("wrong size", info.TotalObjectsSize, objectsSize) } else if info.TotalSectorsSize != sectorsSize { t.Fatal("wrong size", info.TotalSectorsSize, sectorsSize) - } else if info.TotalUploadedSize != sectorsSize*2 { - t.Fatal("wrong size", info.TotalUploadedSize, sectorsSize*2) + } else if info.TotalUploadedSize != totalUploadedSize { + t.Fatal("wrong size", info.TotalUploadedSize, totalUploadedSize) } else if info.NumObjects != 2 { t.Fatal("wrong number of objects", info.NumObjects, 2) } @@ -2524,10 +2527,10 @@ func TestObjectsStats(t *testing.T) { t.Fatal(err) } else if info.TotalObjectsSize != 0 { t.Fatal("wrong size", info.TotalObjectsSize) - } else if info.TotalSectorsSize != sectorsSize { - t.Fatal("wrong size", info.TotalSectorsSize, sectorsSize) - } else if info.TotalUploadedSize != sectorsSize*2 { - t.Fatal("wrong size", info.TotalUploadedSize, sectorsSize*2) + } else if info.TotalSectorsSize != 0 { + t.Fatal("wrong size", info.TotalSectorsSize, 0) + } else if info.TotalUploadedSize != totalUploadedSize { + t.Fatal("wrong size", info.TotalUploadedSize, totalUploadedSize) } else if info.NumObjects != 0 { t.Fatal("wrong number of objects", info.NumObjects) } From 2c627d950532477b22d9be0668f76a29c240b49c Mon Sep 17 00:00:00 2001 From: Chris Schinnerl Date: Thu, 15 Feb 2024 17:17:36 +0100 Subject: [PATCH 06/10] testing: fix TestUploadDownloadExtended --- internal/testing/cluster_test.go | 49 +++++++++++++++++--------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/internal/testing/cluster_test.go b/internal/testing/cluster_test.go index 13903115d..4262e493b 100644 --- a/internal/testing/cluster_test.go +++ b/internal/testing/cluster_test.go @@ -697,30 +697,33 @@ func TestUploadDownloadExtended(t *testing.T) { } // check objects stats. - for _, opts := range []api.ObjectsStatsOpts{ - {}, // any bucket - {Bucket: api.DefaultBucketName}, // specific bucket - } { - info, err := cluster.Bus.ObjectsStats(context.Background(), opts) - tt.OK(err) - objectsSize := uint64(len(file1) + len(file2) + len(small) + len(large)) - if info.TotalObjectsSize != objectsSize { - t.Error("wrong size", info.TotalObjectsSize, objectsSize) - } - sectorsSize := 15 * rhpv2.SectorSize - if info.TotalSectorsSize != uint64(sectorsSize) { - t.Error("wrong size", info.TotalSectorsSize, sectorsSize) - } - if info.TotalUploadedSize != uint64(sectorsSize) { - t.Error("wrong size", info.TotalUploadedSize, sectorsSize) - } - if info.NumObjects != 4 { - t.Error("wrong number of objects", info.NumObjects, 4) - } - if info.MinHealth != 1 { - t.Errorf("expected minHealth of 1, got %v", info.MinHealth) + tt.Retry(100, 100*time.Millisecond, func() error { + for _, opts := range []api.ObjectsStatsOpts{ + {}, // any bucket + {Bucket: api.DefaultBucketName}, // specific bucket + } { + info, err := cluster.Bus.ObjectsStats(context.Background(), opts) + tt.OK(err) + objectsSize := uint64(len(file1) + len(file2) + len(small) + len(large)) + if info.TotalObjectsSize != objectsSize { + return fmt.Errorf("wrong size %v %v", info.TotalObjectsSize, objectsSize) + } + sectorsSize := 15 * rhpv2.SectorSize + if info.TotalSectorsSize != uint64(sectorsSize) { + return fmt.Errorf("wrong size %v %v", info.TotalSectorsSize, sectorsSize) + } + if info.TotalUploadedSize != uint64(sectorsSize) { + return fmt.Errorf("wrong size %v %v", info.TotalUploadedSize, sectorsSize) + } + if info.NumObjects != 4 { + return fmt.Errorf("wrong number of objects %v %v", info.NumObjects, 4) + } + if info.MinHealth != 1 { + return fmt.Errorf("expected minHealth of 1, got %v", info.MinHealth) + } } - } + return nil + }) // download the data for _, data := range [][]byte{small, large} { From c3802d8466d2c7abbf418349a43a1bee41d79239 Mon Sep 17 00:00:00 2001 From: Chris Schinnerl Date: Fri, 16 Feb 2024 09:03:24 +0100 Subject: [PATCH 07/10] stores: fix TestSlabBufferStats --- stores/metadata.go | 1 + 1 file changed, 1 insertion(+) diff --git a/stores/metadata.go b/stores/metadata.go index 3f13097ad..4a2ab8657 100644 --- a/stores/metadata.go +++ b/stores/metadata.go @@ -652,6 +652,7 @@ func (s *SQLStore) ObjectsStats(ctx context.Context, opts api.ObjectsStatsOpts) err = s.db. Table("?", fromSlabs). Select("COALESCE(SUM(total_shards), 0)"). + Where("db_buffered_slab_id IS NULL"). Scan(&totalSectors).Error if err != nil { return api.ObjectsStatsResponse{}, err From 6ed8e754ba2706d419fe2d80f01a6802415b35fd Mon Sep 17 00:00:00 2001 From: Chris Schinnerl Date: Fri, 16 Feb 2024 10:20:23 +0100 Subject: [PATCH 08/10] stores: use WHERE EXISTS --- stores/metadata.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/stores/metadata.go b/stores/metadata.go index 4a2ab8657..d3622502f 100644 --- a/stores/metadata.go +++ b/stores/metadata.go @@ -642,9 +642,13 @@ func (s *SQLStore) ObjectsStats(ctx context.Context, opts api.ObjectsStatsOpts) fromSlabs := gorm.Expr("slabs sla") if opts.Bucket != "" { fromSlabs = gorm.Expr(` + (SELECT * FROM slabs sla - INNER JOIN slices sli ON sli.db_slab_id = sla.id - INNER JOIN objects o ON o.id = sli.db_object_id AND (?) + WHERE EXISTS ( + SELECT 1 FROM slices sli + INNER JOIN objects o ON o.id = sli.db_object_id AND ? + WHERE sli.db_slab_id = sla.id + )) sla `, whereBucket("o")) } From 5f8233fb17aa431aafb987654fe879db2f9a35c8 Mon Sep 17 00:00:00 2001 From: Chris Schinnerl Date: Fri, 16 Feb 2024 10:59:46 +0100 Subject: [PATCH 09/10] stores: remove subquery --- stores/metadata.go | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/stores/metadata.go b/stores/metadata.go index d3622502f..2a879d7ae 100644 --- a/stores/metadata.go +++ b/stores/metadata.go @@ -639,25 +639,22 @@ func (s *SQLStore) ObjectsStats(ctx context.Context, opts api.ObjectsStatsOpts) return api.ObjectsStatsResponse{}, err } - fromSlabs := gorm.Expr("slabs sla") + var totalSectors int64 + totalSectorsQuery := s.db. + Table("slabs sla"). + Select("COALESCE(SUM(total_shards), 0)"). + Where("db_buffered_slab_id IS NULL") + if opts.Bucket != "" { - fromSlabs = gorm.Expr(` - (SELECT * FROM - slabs sla - WHERE EXISTS ( + totalSectorsQuery = totalSectorsQuery.Where(` + EXISTS ( SELECT 1 FROM slices sli - INNER JOIN objects o ON o.id = sli.db_object_id AND ? + INNER JOIN objects o ON o.id = sli.db_object_id AND o.db_bucket_id = ? WHERE sli.db_slab_id = sla.id - )) sla - `, whereBucket("o")) + ) + `, bucketID) } - - var totalSectors int64 - err = s.db. - Table("?", fromSlabs). - Select("COALESCE(SUM(total_shards), 0)"). - Where("db_buffered_slab_id IS NULL"). - Scan(&totalSectors).Error + err = totalSectorsQuery.Scan(&totalSectors).Error if err != nil { return api.ObjectsStatsResponse{}, err } From f68e6ee779a3aa6a10e1a46475679e227ab6c785 Mon Sep 17 00:00:00 2001 From: Chris Schinnerl Date: Fri, 16 Feb 2024 11:16:37 +0100 Subject: [PATCH 10/10] stores: remove contract query --- stores/metadata.go | 47 +++++++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/stores/metadata.go b/stores/metadata.go index 2a879d7ae..d257bf681 100644 --- a/stores/metadata.go +++ b/stores/metadata.go @@ -583,7 +583,7 @@ func (s *SQLStore) ListBuckets(ctx context.Context) ([]api.Bucket, error) { // reduce locking and make sure all results are consistent, everything is done // within a single transaction. func (s *SQLStore) ObjectsStats(ctx context.Context, opts api.ObjectsStatsOpts) (api.ObjectsStatsResponse, error) { - // if no bucket is specified, we consider all objects + // fetch bucket id if a bucket was specified var bucketID uint if opts.Bucket != "" { err := s.db.Model(&dbBucket{}).Select("id").Where("name = ?", opts.Bucket).Take(&bucketID).Error @@ -591,12 +591,6 @@ func (s *SQLStore) ObjectsStats(ctx context.Context, opts api.ObjectsStatsOpts) return api.ObjectsStatsResponse{}, err } } - whereBucket := func(table string) clause.Expr { - if opts.Bucket == "" { - return exprTRUE - } - return gorm.Expr(fmt.Sprintf("%s.db_bucket_id = ?", table), bucketID) - } // number of objects var objInfo struct { @@ -604,37 +598,40 @@ func (s *SQLStore) ObjectsStats(ctx context.Context, opts api.ObjectsStatsOpts) MinHealth float64 TotalObjectsSize uint64 } - err := s.db. + objInfoQuery := s.db. Model(&dbObject{}). - Select("COUNT(*) AS NumObjects, COALESCE(MIN(health), 1) as MinHealth, SUM(size) AS TotalObjectsSize"). - Where(whereBucket(dbObject{}.TableName())). - Scan(&objInfo). - Error + Select("COUNT(*) AS NumObjects, COALESCE(MIN(health), 1) as MinHealth, SUM(size) AS TotalObjectsSize") + if opts.Bucket != "" { + objInfoQuery = objInfoQuery.Where("db_bucket_id", bucketID) + } + err := objInfoQuery.Scan(&objInfo).Error if err != nil { return api.ObjectsStatsResponse{}, err } // number of unfinished objects var unfinishedObjects uint64 - err = s.db. + unfinishedObjectsQuery := s.db. Model(&dbMultipartUpload{}). - Select("COUNT(*)"). - Where(whereBucket(dbMultipartUpload{}.TableName())). - Scan(&unfinishedObjects). - Error + Select("COUNT(*)") + if opts.Bucket != "" { + unfinishedObjectsQuery = unfinishedObjectsQuery.Where("db_bucket_id", bucketID) + } + err = unfinishedObjectsQuery.Scan(&unfinishedObjects).Error if err != nil { return api.ObjectsStatsResponse{}, err } // size of unfinished objects var totalUnfinishedObjectsSize uint64 - err = s.db. + totalUnfinishedObjectsSizeQuery := s.db. Model(&dbMultipartPart{}). Joins("INNER JOIN multipart_uploads mu ON multipart_parts.db_multipart_upload_id = mu.id"). - Select("COALESCE(SUM(size), 0)"). - Where(whereBucket("mu")). - Scan(&totalUnfinishedObjectsSize). - Error + Select("COALESCE(SUM(size), 0)") + if opts.Bucket != "" { + totalUnfinishedObjectsSizeQuery = totalUnfinishedObjectsSizeQuery.Where("db_bucket_id", bucketID) + } + err = totalUnfinishedObjectsSizeQuery.Scan(&totalUnfinishedObjectsSize).Error if err != nil { return api.ObjectsStatsResponse{}, err } @@ -669,12 +666,6 @@ func (s *SQLStore) ObjectsStats(ctx context.Context, opts api.ObjectsStatsOpts) return api.ObjectsStatsResponse{}, err } - var contracts []dbContract - err = s.db.Find(&contracts).Error - if err != nil { - return api.ObjectsStatsResponse{}, err - } - return api.ObjectsStatsResponse{ MinHealth: objInfo.MinHealth, NumObjects: objInfo.NumObjects,