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