list_files.job.agi 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /*
  2. List cluster files - the job half
  3. Walks the whole cluster:/ drive and returns every file with its size and
  4. extension, plus a total per extension. It can run on any node: cluster:/
  5. looks the same everywhere, so the scheduler is free to pick the least
  6. busy one.
  7. args (all optional):
  8. root folder to list, default "cluster:/"
  9. limit how many files to put in the list, default 5000. The totals
  10. always cover every file; the limit only keeps the reply small
  11. on a very large drive.
  12. */
  13. requirelib("filelib");
  14. function humanSize(bytes) {
  15. var units = ["B", "KB", "MB", "GB", "TB"];
  16. var i = 0;
  17. var v = bytes;
  18. while (v >= 1024 && i < units.length - 1) {
  19. v = v / 1024;
  20. i++;
  21. }
  22. return (i === 0 ? v : v.toFixed(1)) + " " + units[i];
  23. }
  24. function extensionOf(name) {
  25. var dot = name.lastIndexOf(".");
  26. if (dot <= 0 || dot === name.length - 1) {
  27. return ""; //no extension, or a dot file such as .gitignore
  28. }
  29. return name.substring(dot + 1).toLowerCase();
  30. }
  31. function run(job) {
  32. var args = job.args || {};
  33. var root = args.root || "cluster:/";
  34. var limit = args.limit > 0 ? args.limit : 5000;
  35. job.log("Walking " + root);
  36. var paths = filelib.walk(root, "file");
  37. if (!paths) {
  38. throw new Error("cannot read " + root);
  39. }
  40. var files = [];
  41. var byExtension = {};
  42. var totalBytes = 0;
  43. for (var i = 0; i < paths.length; i++) {
  44. job.abortIfCancelled();
  45. var path = paths[i];
  46. var name = path.split("/").pop();
  47. var ext = extensionOf(name);
  48. var size = filelib.filesize(path);
  49. totalBytes += size;
  50. var key = ext === "" ? "(none)" : ext;
  51. if (!byExtension[key]) {
  52. byExtension[key] = { files: 0, bytes: 0 };
  53. }
  54. byExtension[key].files++;
  55. byExtension[key].bytes += size;
  56. if (files.length < limit) {
  57. files.push({ path: path, name: name, extension: ext, size: size, sizeText: humanSize(size) });
  58. }
  59. if (i % 200 === 0) {
  60. job.progress(i / paths.length);
  61. }
  62. }
  63. for (var k in byExtension) {
  64. byExtension[k].sizeText = humanSize(byExtension[k].bytes);
  65. }
  66. return {
  67. root: root,
  68. listedOn: job.node,
  69. totalFiles: paths.length,
  70. totalBytes: totalBytes,
  71. totalSizeText: humanSize(totalBytes),
  72. truncated: paths.length > files.length,
  73. byExtension: byExtension,
  74. files: files
  75. };
  76. }