return is_hfs_dotgitmodules(path) || is_ntfs_dotgitmodules(path);
}
+/*
+ * A very simple, reproducible pseudo-random generator. Copied from
+ * `test-genrandom.c`.
+ */
+static uint64_t my_random_value = 1234;
+
+static uint64_t my_random(void)
+{
+ my_random_value = my_random_value * 1103515245 + 12345;
+ return my_random_value;
+}
+
+/*
+ * A fast approximation of the square root, without requiring math.h.
+ *
+ * It uses Newton's method to approximate the solution of 0 = x^2 - value.
+ */
+static double my_sqrt(double value)
+{
+ const double epsilon = 1e-6;
+ double x = value;
+
+ if (value == 0)
+ return 0;
+
+ for (;;) {
+ double delta = (value / x - x) / 2;
+ if (delta < epsilon && delta > -epsilon)
+ return x + delta;
+ x += delta;
+ }
+}
+
+static int protect_ntfs_hfs_benchmark(int argc, const char **argv)
+{
+ size_t i, j, nr, min_len = 3, max_len = 20;
+ char **names;
+ int repetitions = 15, file_mode = 0100644;
+ uint64_t begin, end;
+ double m[3][2], v[3][2];
+ uint64_t cumul;
+ double cumul2;
+
+ if (argc > 1 && !strcmp(argv[1], "--with-symlink-mode")) {
+ file_mode = 0120000;
+ argc--;
+ argv++;
+ }
+
+ nr = argc > 1 ? strtoul(argv[1], NULL, 0) : 1000000;
+ ALLOC_ARRAY(names, nr);
+
+ if (argc > 2) {
+ min_len = strtoul(argv[2], NULL, 0);
+ if (argc > 3)
+ max_len = strtoul(argv[3], NULL, 0);
+ if (min_len > max_len)
+ die("min_len > max_len");
+ }
+
+ for (i = 0; i < nr; i++) {
+ size_t len = min_len + (my_random() % (max_len + 1 - min_len));
+
+ names[i] = xmallocz(len);
+ while (len > 0)
+ names[i][--len] = (char)(' ' + (my_random() % ('\x7f' - ' ')));
+ }
+
+ for (protect_ntfs = 0; protect_ntfs < 2; protect_ntfs++)
+ for (protect_hfs = 0; protect_hfs < 2; protect_hfs++) {
+ cumul = 0;
+ cumul2 = 0;
+ for (i = 0; i < repetitions; i++) {
+ begin = getnanotime();
+ for (j = 0; j < nr; j++)
+ verify_path(names[j], file_mode);
+ end = getnanotime();
+ printf("protect_ntfs = %d, protect_hfs = %d: %lfms\n", protect_ntfs, protect_hfs, (end-begin) / (double)1e6);
+ cumul += end - begin;
+ cumul2 += (end - begin) * (end - begin);
+ }
+ m[protect_ntfs][protect_hfs] = cumul / (double)repetitions;
+ v[protect_ntfs][protect_hfs] = my_sqrt(cumul2 / (double)repetitions - m[protect_ntfs][protect_hfs] * m[protect_ntfs][protect_hfs]);
+ printf("mean: %lfms, stddev: %lfms\n", m[protect_ntfs][protect_hfs] / (double)1e6, v[protect_ntfs][protect_hfs] / (double)1e6);
+ }
+
+ for (protect_ntfs = 0; protect_ntfs < 2; protect_ntfs++)
+ for (protect_hfs = 0; protect_hfs < 2; protect_hfs++)
+ printf("ntfs=%d/hfs=%d: %lf%% slower\n", protect_ntfs, protect_hfs, (m[protect_ntfs][protect_hfs] - m[0][0]) * 100 / m[0][0]);
+
+ return 0;
+}
+
int cmd_main(int argc, const char **argv)
{
if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) {
return !!res;
}
+ if (argc > 1 && !strcmp(argv[1], "protect_ntfs_hfs"))
+ return !!protect_ntfs_hfs_benchmark(argc - 1, argv + 1);
+
+ if (argc > 1 && !strcmp(argv[1], "is_valid_path")) {
+ int res = 0, expect = 1, i;
+
+ for (i = 2; i < argc; i++)
+ if (!strcmp("--not", argv[i]))
+ expect = 0;
+ else if (expect != is_valid_path(argv[i]))
+ res = error("'%s' is%s a valid path",
+ argv[i], expect ? " not" : "");
+ else
+ fprintf(stderr,
+ "'%s' is%s a valid path\n",
+ argv[i], expect ? "" : " not");
+
+ return !!res;
+ }
+
fprintf(stderr, "%s: unknown function name: %s\n", argv[0],
argv[1] ? argv[1] : "(there was none)");
return 1;