Skip to content

Commit f19ada9

Browse files
committed
fix: actually use porportional calculation
1 parent a1dae3d commit f19ada9

File tree

1 file changed

+74
-1
lines changed

1 file changed

+74
-1
lines changed

src/server/backup/backup_rustic.go

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ func (r *RusticBackup) Path() string {
402402
return fmt.Sprintf("%s/snapshot-%s", r.repositoryPath, r.snapshotID)
403403
}
404404

405-
// Size returns the size of the backup
405+
// Size returns the size of the backup accounting for deduplication
406406
func (r *RusticBackup) Size() (int64, error) {
407407
if r.snapshotID == "" {
408408
return 0, errors.New("rustic: no snapshot ID available")
@@ -417,6 +417,19 @@ func (r *RusticBackup) Size() (int64, error) {
417417
defer cancel()
418418
defer r.cleanup()
419419

420+
// Get the proportional size based on repository deduplication
421+
size, err := r.calculateProportionalSize(ctx)
422+
if err != nil {
423+
// Fallback to DataAdded if proportional calculation fails
424+
r.log().WithError(err).Debug("failed to calculate proportional size, falling back to DataAdded")
425+
return r.getSnapshotDataAdded(ctx)
426+
}
427+
428+
return size, nil
429+
}
430+
431+
// getSnapshotDataAdded returns the raw DataAdded value for backward compatibility
432+
func (r *RusticBackup) getSnapshotDataAdded(ctx context.Context) (int64, error) {
420433
cmd := r.buildRusticCommandWithContext(ctx, "snapshots", "--json", r.snapshotID)
421434
output, err := cmd.Output()
422435
if err != nil {
@@ -442,6 +455,66 @@ func (r *RusticBackup) Size() (int64, error) {
442455
return 0, errors.New("rustic: snapshot not found or size unavailable")
443456
}
444457

458+
// calculateProportionalSize calculates the proportional size of this backup based on repository deduplication
459+
func (r *RusticBackup) calculateProportionalSize(ctx context.Context) (int64, error) {
460+
if r.serverUuid == "" {
461+
return 0, errors.New("rustic: server UUID required for proportional size calculation")
462+
}
463+
464+
// Get repository information
465+
repoInfo, err := r.getRepositoryInfo(ctx)
466+
if err != nil {
467+
return 0, errors.Wrap(err, "failed to get repository information for size calculation")
468+
}
469+
470+
// Get all snapshots for this server
471+
snapshots, err := r.getAllServerSnapshots(ctx)
472+
if err != nil {
473+
return 0, errors.Wrap(err, "failed to get all server snapshots for size calculation")
474+
}
475+
476+
if len(snapshots) == 0 {
477+
return 0, errors.New("no snapshots found for proportional size calculation")
478+
}
479+
480+
// Find our snapshot and calculate proportional size
481+
var ourSnapshot *RusticSnapshotInfo
482+
var totalDataAdded int64
483+
484+
for _, snapshot := range snapshots {
485+
if snapshot.Summary != nil && snapshot.Summary.DataAdded > 0 {
486+
totalDataAdded += snapshot.Summary.DataAdded
487+
}
488+
489+
// Check if this is our snapshot
490+
if snapshot.ID == r.snapshotID ||
491+
(len(r.snapshotID) == 8 && strings.HasPrefix(snapshot.ID, r.snapshotID)) {
492+
ourSnapshot = &snapshot
493+
}
494+
}
495+
496+
if ourSnapshot == nil {
497+
return 0, errors.New("current snapshot not found in server snapshots")
498+
}
499+
500+
if ourSnapshot.Summary == nil || ourSnapshot.Summary.DataAdded == 0 {
501+
return 1024, nil // Return minimum size for empty snapshots
502+
}
503+
504+
totalRepoDataSize := repoInfo.GetTotalDataSize()
505+
if totalDataAdded == 0 || totalRepoDataSize == 0 {
506+
return ourSnapshot.Summary.DataAdded, nil // Fallback to original size
507+
}
508+
509+
// Calculate proportional size: (this snapshot's original contribution / total original) * actual repository size
510+
proportionalSize := int64(float64(ourSnapshot.Summary.DataAdded) / float64(totalDataAdded) * float64(totalRepoDataSize))
511+
512+
// Ensure minimum size (avoid zero-sized backups)
513+
proportionalSize = max(proportionalSize, 1024) // 1KB minimum
514+
515+
return proportionalSize, nil
516+
}
517+
445518
// Checksum returns a checksum for the backup
446519
func (r *RusticBackup) Checksum() ([]byte, error) {
447520
if r.snapshotID == "" {

0 commit comments

Comments
 (0)