@@ -73,6 +73,119 @@ struct survey_report_object_size_summary {
7373 size_t num_missing ;
7474};
7575
76+ typedef int (* survey_top_cmp )(void * v1 , void * v2 );
77+
78+ MAYBE_UNUSED
79+ static int cmp_by_nr (void * v1 , void * v2 )
80+ {
81+ struct survey_report_object_size_summary * s1 = v1 ;
82+ struct survey_report_object_size_summary * s2 = v2 ;
83+
84+ if (s1 -> nr < s2 -> nr )
85+ return -1 ;
86+ if (s1 -> nr > s2 -> nr )
87+ return 1 ;
88+ return 0 ;
89+ }
90+
91+ MAYBE_UNUSED
92+ static int cmp_by_disk_size (void * v1 , void * v2 )
93+ {
94+ struct survey_report_object_size_summary * s1 = v1 ;
95+ struct survey_report_object_size_summary * s2 = v2 ;
96+
97+ if (s1 -> disk_size < s2 -> disk_size )
98+ return -1 ;
99+ if (s1 -> disk_size > s2 -> disk_size )
100+ return 1 ;
101+ return 0 ;
102+ }
103+
104+ MAYBE_UNUSED
105+ static int cmp_by_inflated_size (void * v1 , void * v2 )
106+ {
107+ struct survey_report_object_size_summary * s1 = v1 ;
108+ struct survey_report_object_size_summary * s2 = v2 ;
109+
110+ if (s1 -> inflated_size < s2 -> inflated_size )
111+ return -1 ;
112+ if (s1 -> inflated_size > s2 -> inflated_size )
113+ return 1 ;
114+ return 0 ;
115+ }
116+
117+ /**
118+ * Store a list of "top" categories by some sorting function. When
119+ * inserting a new category, reorder the list and free the one that
120+ * got ejected (if any).
121+ */
122+ struct survey_report_top_table {
123+ const char * name ;
124+ survey_top_cmp cmp_fn ;
125+ size_t nr ;
126+ size_t alloc ;
127+
128+ /**
129+ * 'data' stores an array of structs and must be cast into
130+ * the proper array type before evaluating an index.
131+ */
132+ void * data ;
133+ };
134+
135+ MAYBE_UNUSED
136+ static void init_top_sizes (struct survey_report_top_table * top ,
137+ size_t limit , const char * name ,
138+ survey_top_cmp cmp )
139+ {
140+ struct survey_report_object_size_summary * sz_array ;
141+
142+ top -> name = name ;
143+ top -> cmp_fn = cmp ;
144+ top -> alloc = limit ;
145+ top -> nr = 0 ;
146+
147+ CALLOC_ARRAY (sz_array , limit );
148+ top -> data = sz_array ;
149+ }
150+
151+ MAYBE_UNUSED
152+ static void clear_top_sizes (struct survey_report_top_table * top )
153+ {
154+ struct survey_report_object_size_summary * sz_array = top -> data ;
155+
156+ for (size_t i = 0 ; i < top -> nr ; i ++ )
157+ free (sz_array [i ].label );
158+ free (sz_array );
159+ }
160+
161+ MAYBE_UNUSED
162+ static void maybe_insert_into_top_size (struct survey_report_top_table * top ,
163+ struct survey_report_object_size_summary * summary )
164+ {
165+ struct survey_report_object_size_summary * sz_array = top -> data ;
166+ size_t pos = top -> nr ;
167+
168+ /* Compare against list from the bottom. */
169+ while (pos > 0 && top -> cmp_fn (& sz_array [pos - 1 ], summary ) < 0 )
170+ pos -- ;
171+
172+ /* Not big enough! */
173+ if (pos >= top -> alloc )
174+ return ;
175+
176+ /* We need to shift the data. */
177+ if (top -> nr == top -> alloc )
178+ free (sz_array [top -> nr - 1 ].label );
179+ else
180+ top -> nr ++ ;
181+
182+ for (size_t i = top -> nr - 1 ; i > pos ; i -- )
183+ memcpy (& sz_array [i ], & sz_array [i - 1 ], sizeof (* sz_array ));
184+
185+ memcpy (& sz_array [pos ], summary , sizeof (* summary ));
186+ sz_array [pos ].label = xstrdup (summary -> label );
187+ }
188+
76189/**
77190 * This struct contains all of the information that needs to be printed
78191 * at the end of the exploration of the repository and its references.
0 commit comments