DF-2645 / delsome.c
/* delsome: delete pct% of the named files under dir, randomized order, * in batches with syncs, so the flusher's indirect-maintenance sees * sparsified indirect blocks and collapses them. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> int main(int argc, char **argv) { const char *dir = argv[1]; const char *list = argv[2]; int pct = argc > 3 ? atoi(argv[3]) : 90; char line[512], path[1024]; char **names; int n = 0, i, del = 0; FILE *f; unsigned long st = 99991; if ((f = fopen(list, "r")) == NULL) { perror(list); exit(1); } names = calloc(200000, sizeof(char *)); while (fgets(line, sizeof(line), f)) { int len = strlen(line); if (len && line[len-1] == '\n') line[--len] = 0; if (len == 0) continue; asprintf(&names[n], "%s", line); ++n; } fclose(f); /* Fisher-Yates with cheap LCG */ for (i = n - 1; i > 0; --i) { int j; char *t; st = st * 6364136223846793005UL + 1442695040888963407UL; j = (int)((st >> 33) % (i + 1)); t = names[i]; names[i] = names[j]; names[j] = t; } for (i = 0; i < n; ++i) { if (i >= (long)n * pct / 100) break; snprintf(path, sizeof(path), "%s/%s", dir, names[i]); if (unlink(path) == 0) ++del; if ((i % 512) == 511) sync(); } sync(); fprintf(stderr, "deleted %d/%d\n", del, n); return 0; } |