@@ -22,6 +22,14 @@ import (
2222 "github.com/substantialcattle5/sietch/util"
2323)
2424
25+ // SpaceSavings represents space savings statistics for a file
26+ type SpaceSavings struct {
27+ OriginalSize int64
28+ CompressedSize int64
29+ SpaceSaved int64
30+ SpaceSavedPct float64
31+ }
32+
2533// addCmd represents the add command
2634var addCmd = & cobra.Command {
2735 Use : "add <source_path> <destination_path> [source_path2] [destination_path2]..." ,
@@ -114,6 +122,7 @@ Examples:
114122 // Process each file pair
115123 successCount := 0
116124 var failedFiles []string
125+ var totalSpaceSavings SpaceSavings
117126
118127 // Show initial progress for multiple files
119128 if len (filePairs ) > 1 {
@@ -183,16 +192,34 @@ Examples:
183192 continue
184193 }
185194
195+ // Calculate space savings for this file
196+ spaceSavings := calculateSpaceSavings (chunkRefs )
197+
186198 // Success message
187199 if len (filePairs ) > 1 {
188- fmt .Printf ("✓ %s (%d chunks)\n " , filepath .Base (pair .Source ), len (chunkRefs ))
200+ fmt .Printf ("✓ %s (%d chunks" , filepath .Base (pair .Source ), len (chunkRefs ))
201+ if spaceSavings .SpaceSaved > 0 {
202+ fmt .Printf (", %s saved" , util .HumanReadableSize (spaceSavings .SpaceSaved ))
203+ }
204+ fmt .Printf (")\n " )
189205 } else {
190206 fmt .Printf ("✓ File added to vault: %s\n " , filepath .Base (pair .Source ))
191207 fmt .Printf ("✓ %d chunks stored in vault\n " , len (chunkRefs ))
208+ if spaceSavings .SpaceSaved > 0 {
209+ fmt .Printf ("✓ Space saved: %s (%.1f%%)\n " ,
210+ util .HumanReadableSize (spaceSavings .SpaceSaved ),
211+ spaceSavings .SpaceSavedPct )
212+ }
192213 fmt .Printf ("✓ Manifest written to .sietch/manifests/%s.yaml\n " , filepath .Base (pair .Source ))
193214 }
194215
195216 successCount ++
217+
218+ // Add to total space savings
219+ fileSavings := calculateSpaceSavings (chunkRefs )
220+ totalSpaceSavings .OriginalSize += fileSavings .OriginalSize
221+ totalSpaceSavings .CompressedSize += fileSavings .CompressedSize
222+ totalSpaceSavings .SpaceSaved += fileSavings .SpaceSaved
196223 }
197224
198225 // Cleanup progress manager
@@ -232,14 +259,21 @@ Examples:
232259
233260 fmt .Printf (" • Compression: %s\n " , vaultConfig .Compression )
234261
235- // Calculate and show space savings if compression is used
236- if vaultConfig .Compression != "none" {
237- // TODO: Calculate actual space savings during processing
238- // For now, show compression info
239- fmt .Printf (" • Compression: %s (space savings calculated during processing)\n " , vaultConfig .Compression )
240- }
241-
242262 fmt .Printf (" • Chunking: %s (size: %s)\n " , vaultConfig .Chunking .Strategy , vaultConfig .Chunking .ChunkSize )
263+
264+ // Show total space savings if compression is used
265+ if vaultConfig .Compression != "none" && totalSpaceSavings .SpaceSaved > 0 {
266+ totalSpaceSavedPct := float64 (0 )
267+ if totalSpaceSavings .OriginalSize > 0 {
268+ totalSpaceSavedPct = float64 (totalSpaceSavings .SpaceSaved ) / float64 (totalSpaceSavings .OriginalSize ) * 100
269+ }
270+ fmt .Printf ("\n 💾 Total Space Savings:\n " )
271+ fmt .Printf (" • Original size: %s\n " , util .HumanReadableSize (totalSpaceSavings .OriginalSize ))
272+ fmt .Printf (" • Compressed size: %s\n " , util .HumanReadableSize (totalSpaceSavings .CompressedSize ))
273+ fmt .Printf (" • Space saved: %s (%.1f%%)\n " ,
274+ util .HumanReadableSize (totalSpaceSavings .SpaceSaved ),
275+ totalSpaceSavedPct )
276+ }
243277 }
244278
245279 // Return error only if all files failed
@@ -257,6 +291,35 @@ type FilePair struct {
257291 Destination string
258292}
259293
294+ // calculateSpaceSavings calculates space savings for a file based on its chunks
295+ func calculateSpaceSavings (chunks []config.ChunkRef ) SpaceSavings {
296+ originalSize := int64 (0 )
297+ compressedSize := int64 (0 )
298+
299+ for _ , chunk := range chunks {
300+ originalSize += chunk .Size
301+ if chunk .CompressedSize > 0 {
302+ compressedSize += chunk .CompressedSize
303+ } else {
304+ // If no compressed size is recorded, use original size
305+ compressedSize += chunk .Size
306+ }
307+ }
308+
309+ spaceSaved := originalSize - compressedSize
310+ var spaceSavedPct float64
311+ if originalSize > 0 {
312+ spaceSavedPct = float64 (spaceSaved ) / float64 (originalSize ) * 100
313+ }
314+
315+ return SpaceSavings {
316+ OriginalSize : originalSize ,
317+ CompressedSize : compressedSize ,
318+ SpaceSaved : spaceSaved ,
319+ SpaceSavedPct : spaceSavedPct ,
320+ }
321+ }
322+
260323// parseFileArguments parses command line arguments into source-destination pairs
261324// Supports two patterns:
262325// 1. Paired: source1 dest1 source2 dest2 ... (even number of args)
0 commit comments