@@ -65,15 +65,36 @@ struct survey_report_object_summary {
65
65
size_t blobs_nr ;
66
66
};
67
67
68
+ /**
69
+ * For some category given by 'label', count the number of objects
70
+ * that match that label along with the on-disk size and the size
71
+ * after decompressing (both with delta bases and zlib).
72
+ */
73
+ struct survey_report_object_size_summary {
74
+ char * label ;
75
+ size_t nr ;
76
+ size_t disk_size ;
77
+ size_t inflated_size ;
78
+ size_t num_missing ;
79
+ };
80
+
68
81
/**
69
82
* This struct contains all of the information that needs to be printed
70
83
* at the end of the exploration of the repository and its references.
71
84
*/
72
85
struct survey_report {
73
86
struct survey_report_ref_summary refs ;
74
87
struct survey_report_object_summary reachable_objects ;
88
+
89
+ struct survey_report_object_size_summary * by_type ;
75
90
};
76
91
92
+ #define REPORT_TYPE_COMMIT 0
93
+ #define REPORT_TYPE_TREE 1
94
+ #define REPORT_TYPE_BLOB 2
95
+ #define REPORT_TYPE_TAG 3
96
+ #define REPORT_TYPE_COUNT 4
97
+
77
98
struct survey_context {
78
99
struct repository * repo ;
79
100
@@ -285,12 +306,48 @@ static void survey_report_plaintext_reachable_object_summary(struct survey_conte
285
306
clear_table (& table );
286
307
}
287
308
309
+ static void survey_report_object_sizes (const char * title ,
310
+ const char * categories ,
311
+ struct survey_report_object_size_summary * summary ,
312
+ size_t summary_nr )
313
+ {
314
+ struct survey_table table = SURVEY_TABLE_INIT ;
315
+ table .table_name = title ;
316
+
317
+ strvec_push (& table .header , categories );
318
+ strvec_push (& table .header , _ ("Count" ));
319
+ strvec_push (& table .header , _ ("Disk Size" ));
320
+ strvec_push (& table .header , _ ("Inflated Size" ));
321
+
322
+ for (size_t i = 0 ; i < summary_nr ; i ++ ) {
323
+ char * label_str = xstrdup (summary [i ].label );
324
+ char * nr_str = xstrfmt ("%" PRIuMAX , (uintmax_t )summary [i ].nr );
325
+ char * disk_str = xstrfmt ("%" PRIuMAX , (uintmax_t )summary [i ].disk_size );
326
+ char * inflate_str = xstrfmt ("%" PRIuMAX , (uintmax_t )summary [i ].inflated_size );
327
+
328
+ insert_table_rowv (& table , label_str , nr_str ,
329
+ disk_str , inflate_str , NULL );
330
+
331
+ free (label_str );
332
+ free (nr_str );
333
+ free (disk_str );
334
+ free (inflate_str );
335
+ }
336
+
337
+ print_table_plaintext (& table );
338
+ clear_table (& table );
339
+ }
340
+
288
341
static void survey_report_plaintext (struct survey_context * ctx )
289
342
{
290
343
printf ("GIT SURVEY for \"%s\"\n" , ctx -> repo -> worktree );
291
344
printf ("-----------------------------------------------------\n" );
292
345
survey_report_plaintext_refs (ctx );
293
346
survey_report_plaintext_reachable_object_summary (ctx );
347
+ survey_report_object_sizes (_ ("TOTAL OBJECT SIZES BY TYPE" ),
348
+ _ ("Object Type" ),
349
+ ctx -> report .by_type ,
350
+ REPORT_TYPE_COUNT );
294
351
}
295
352
296
353
/*
@@ -503,6 +560,68 @@ static void increment_object_counts(
503
560
}
504
561
}
505
562
563
+ static void increment_totals (struct survey_context * ctx ,
564
+ struct oid_array * oids ,
565
+ struct survey_report_object_size_summary * summary )
566
+ {
567
+ for (size_t i = 0 ; i < oids -> nr ; i ++ ) {
568
+ struct object_info oi = OBJECT_INFO_INIT ;
569
+ unsigned oi_flags = OBJECT_INFO_FOR_PREFETCH ;
570
+ unsigned long object_length = 0 ;
571
+ off_t disk_sizep = 0 ;
572
+ enum object_type type ;
573
+
574
+ oi .typep = & type ;
575
+ oi .sizep = & object_length ;
576
+ oi .disk_sizep = & disk_sizep ;
577
+
578
+ if (oid_object_info_extended (ctx -> repo , & oids -> oid [i ],
579
+ & oi , oi_flags ) < 0 ) {
580
+ summary -> num_missing ++ ;
581
+ } else {
582
+ summary -> nr ++ ;
583
+ summary -> disk_size += disk_sizep ;
584
+ summary -> inflated_size += object_length ;
585
+ }
586
+ }
587
+ }
588
+
589
+ static void increment_object_totals (struct survey_context * ctx ,
590
+ struct oid_array * oids ,
591
+ enum object_type type )
592
+ {
593
+ struct survey_report_object_size_summary * total ;
594
+ struct survey_report_object_size_summary summary = { 0 };
595
+
596
+ increment_totals (ctx , oids , & summary );
597
+
598
+ switch (type ) {
599
+ case OBJ_COMMIT :
600
+ total = & ctx -> report .by_type [REPORT_TYPE_COMMIT ];
601
+ break ;
602
+
603
+ case OBJ_TREE :
604
+ total = & ctx -> report .by_type [REPORT_TYPE_TREE ];
605
+ break ;
606
+
607
+ case OBJ_BLOB :
608
+ total = & ctx -> report .by_type [REPORT_TYPE_BLOB ];
609
+ break ;
610
+
611
+ case OBJ_TAG :
612
+ total = & ctx -> report .by_type [REPORT_TYPE_TAG ];
613
+ break ;
614
+
615
+ default :
616
+ BUG ("No other type allowed" );
617
+ }
618
+
619
+ total -> nr += summary .nr ;
620
+ total -> disk_size += summary .disk_size ;
621
+ total -> inflated_size += summary .inflated_size ;
622
+ total -> num_missing += summary .num_missing ;
623
+ }
624
+
506
625
static int survey_objects_path_walk_fn (const char * path UNUSED ,
507
626
struct oid_array * oids ,
508
627
enum object_type type ,
@@ -512,10 +631,20 @@ static int survey_objects_path_walk_fn(const char *path UNUSED,
512
631
513
632
increment_object_counts (& ctx -> report .reachable_objects ,
514
633
type , oids -> nr );
634
+ increment_object_totals (ctx , oids , type );
515
635
516
636
return 0 ;
517
637
}
518
638
639
+ static void initialize_report (struct survey_context * ctx )
640
+ {
641
+ CALLOC_ARRAY (ctx -> report .by_type , REPORT_TYPE_COUNT );
642
+ ctx -> report .by_type [REPORT_TYPE_COMMIT ].label = xstrdup (_ ("Commits" ));
643
+ ctx -> report .by_type [REPORT_TYPE_TREE ].label = xstrdup (_ ("Trees" ));
644
+ ctx -> report .by_type [REPORT_TYPE_BLOB ].label = xstrdup (_ ("Blobs" ));
645
+ ctx -> report .by_type [REPORT_TYPE_TAG ].label = xstrdup (_ ("Tags" ));
646
+ }
647
+
519
648
static void survey_phase_objects (struct survey_context * ctx )
520
649
{
521
650
struct rev_info revs = REV_INFO_INIT ;
@@ -528,12 +657,15 @@ static void survey_phase_objects(struct survey_context *ctx)
528
657
info .path_fn = survey_objects_path_walk_fn ;
529
658
info .path_fn_data = ctx ;
530
659
660
+ initialize_report (ctx );
661
+
531
662
repo_init_revisions (ctx -> repo , & revs , "" );
532
663
revs .tag_objects = 1 ;
533
664
534
665
for (int i = 0 ; i < ctx -> ref_array .nr ; i ++ ) {
535
666
struct ref_array_item * item = ctx -> ref_array .items [i ];
536
667
add_pending_oid (& revs , NULL , & item -> objectname , add_flags );
668
+ display_progress (ctx -> progress , ++ (ctx -> progress_nr ));
537
669
}
538
670
539
671
walk_objects_by_path (& info );
0 commit comments