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