176
return is_hfs_dotgitmodules(path) || is_ntfs_dotgitmodules(path);
177
}
178
179
+/*
180
+ * A very simple, reproducible pseudo-random generator. Copied from
181
+ * `test-genrandom.c`.
182
+ */
183
+static uint64_t my_random_value = 1234;
184
+
185
+static uint64_t my_random(void)
186
+{
187
+ my_random_value = my_random_value * 1103515245 + 12345;
188
+ return my_random_value;
189
+}
190
+
191
+/*
192
+ * A fast approximation of the square root, without requiring math.h.
193
+ *
194
+ * It uses Newton's method to approximate the solution of 0 = x^2 - value.
195
+ */
196
+static double my_sqrt(double value)
197
+{
198
+ const double epsilon = 1e-6;
199
+ double x = value;
200
+
201
+ if (value == 0)
202
+ return 0;
203
+
204
+ for (;;) {
205
+ double delta = (value / x - x) / 2;
206
+ if (delta < epsilon && delta > -epsilon)
207
+ return x + delta;
208
+ x += delta;
209
+ }
210
+}
211
+
212
+static int protect_ntfs_hfs_benchmark(int argc, const char **argv)
213
+{
214
+ size_t i, j, nr, min_len = 3, max_len = 20;
215
+ char **names;
216
+ int repetitions = 15, file_mode = 0100644;
217
+ uint64_t begin, end;
218
+ double m[3][2], v[3][2];
219
+ uint64_t cumul;
220
+ double cumul2;
221
+
222
+ if (argc > 1 && !strcmp(argv[1], "--with-symlink-mode")) {
223
+ file_mode = 0120000;
224
+ argc--;
225
+ argv++;
226
+ }
227
+
228
+ nr = argc > 1 ? strtoul(argv[1], NULL, 0) : 1000000;
229
+ ALLOC_ARRAY(names, nr);
230
+
231
+ if (argc > 2) {
232
+ min_len = strtoul(argv[2], NULL, 0);
233
+ if (argc > 3)
234
+ max_len = strtoul(argv[3], NULL, 0);
235
+ if (min_len > max_len)
236
+ die("min_len > max_len");
237
+ }
238
+
239
+ for (i = 0; i < nr; i++) {
240
+ size_t len = min_len + (my_random() % (max_len + 1 - min_len));
241
+
242
+ names[i] = xmallocz(len);
243
+ while (len > 0)
244
+ names[i][--len] = (char)(' ' + (my_random() % ('\x7f' - ' ')));
245
+ }
246
+
247
+ for (protect_ntfs = 0; protect_ntfs < 2; protect_ntfs++)
248
+ for (protect_hfs = 0; protect_hfs < 2; protect_hfs++) {
249
+ cumul = 0;
250
+ cumul2 = 0;
251
+ for (i = 0; i < repetitions; i++) {
252
+ begin = getnanotime();
253
+ for (j = 0; j < nr; j++)
254
+ verify_path(names[j], file_mode);
255
+ end = getnanotime();
256
+ printf("protect_ntfs = %d, protect_hfs = %d: %lfms\n", protect_ntfs, protect_hfs, (end-begin) / (double)1e6);
257
+ cumul += end - begin;
258
+ cumul2 += (end - begin) * (end - begin);
259
+ }
260
+ m[protect_ntfs][protect_hfs] = cumul / (double)repetitions;
261
+ v[protect_ntfs][protect_hfs] = my_sqrt(cumul2 / (double)repetitions - m[protect_ntfs][protect_hfs] * m[protect_ntfs][protect_hfs]);
262
+ printf("mean: %lfms, stddev: %lfms\n", m[protect_ntfs][protect_hfs] / (double)1e6, v[protect_ntfs][protect_hfs] / (double)1e6);
263
+ }
264
+
265
+ for (protect_ntfs = 0; protect_ntfs < 2; protect_ntfs++)
266
+ for (protect_hfs = 0; protect_hfs < 2; protect_hfs++)
267
+ printf("ntfs=%d/hfs=%d: %lf%% slower\n", protect_ntfs, protect_hfs, (m[protect_ntfs][protect_hfs] - m[0][0]) * 100 / m[0][0]);
268
+
269
+ return 0;
270
+}
271
+
272
int cmd_main(int argc, const char **argv)
273
{
274
if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) {
383
return !!res;
384
}
385
386
+ if (argc > 1 && !strcmp(argv[1], "protect_ntfs_hfs"))
387
+ return !!protect_ntfs_hfs_benchmark(argc - 1, argv + 1);
388
+
389
fprintf(stderr, "%s: unknown function name: %s\n", argv[0],
390
argv[1] ? argv[1] : "(there was none)");
391
return 1;