downloadPlanBuilder.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.computeOperations = computeOperations;
  6. exports.OperationKind = void 0;
  7. var OperationKind;
  8. exports.OperationKind = OperationKind;
  9. (function (OperationKind) {
  10. OperationKind[OperationKind["COPY"] = 0] = "COPY";
  11. OperationKind[OperationKind["DOWNLOAD"] = 1] = "DOWNLOAD";
  12. })(OperationKind || (exports.OperationKind = OperationKind = {}));
  13. function computeOperations(oldBlockMap, newBlockMap, logger) {
  14. const nameToOldBlocks = buildBlockFileMap(oldBlockMap.files);
  15. const nameToNewBlocks = buildBlockFileMap(newBlockMap.files);
  16. const oldEntryMap = buildEntryMap(oldBlockMap.files);
  17. let lastOperation = null;
  18. const operations = [];
  19. for (const blockMapFile of newBlockMap.files) {
  20. const name = blockMapFile.name;
  21. const oldEntry = oldEntryMap.get(name);
  22. if (oldEntry == null) {
  23. // new file
  24. operations.push({
  25. kind: OperationKind.DOWNLOAD,
  26. start: blockMapFile.offset,
  27. end: blockMapFile.offset + blockMapFile.sizes.reduce((accumulator, currentValue) => accumulator + currentValue)
  28. });
  29. continue;
  30. }
  31. const newFile = nameToNewBlocks.get(name);
  32. let changedBlockCount = 0;
  33. const {
  34. checksumToOffset: checksumToOldOffset,
  35. checksumToOldSize
  36. } = buildChecksumMap(nameToOldBlocks.get(name), oldEntry.offset);
  37. let newOffset = blockMapFile.offset;
  38. for (let i = 0; i < newFile.checksums.length; newOffset += newFile.sizes[i], i++) {
  39. const blockSize = newFile.sizes[i];
  40. const checksum = newFile.checksums[i];
  41. let oldOffset = checksumToOldOffset.get(checksum);
  42. if (oldOffset != null && checksumToOldSize.get(checksum) !== blockSize) {
  43. logger.warn(`Checksum ("${checksum}") matches, but size differs (old: ${checksumToOldSize.get(checksum)}, new: ${blockSize})`);
  44. oldOffset = null;
  45. }
  46. if (oldOffset == null) {
  47. changedBlockCount++;
  48. if (lastOperation == null || lastOperation.kind !== OperationKind.DOWNLOAD || lastOperation.end !== newOffset) {
  49. lastOperation = {
  50. kind: OperationKind.DOWNLOAD,
  51. start: newOffset,
  52. end: newOffset + blockSize
  53. };
  54. operations.push(lastOperation);
  55. } else {
  56. lastOperation.end += blockSize;
  57. }
  58. } else if (lastOperation == null || lastOperation.kind !== OperationKind.COPY || lastOperation.end !== oldOffset) {
  59. lastOperation = {
  60. kind: OperationKind.COPY,
  61. start: oldOffset,
  62. end: oldOffset + blockSize
  63. };
  64. operations.push(lastOperation);
  65. } else {
  66. lastOperation.end += blockSize;
  67. }
  68. }
  69. if (changedBlockCount > 0) {
  70. logger.info(`File${blockMapFile.name === "file" ? "" : " " + blockMapFile.name} has ${changedBlockCount} changed blocks`);
  71. }
  72. }
  73. return operations;
  74. }
  75. function buildChecksumMap(file, fileOffset) {
  76. const checksumToOffset = new Map();
  77. const checksumToSize = new Map();
  78. let offset = fileOffset;
  79. for (let i = 0; i < file.checksums.length; i++) {
  80. const checksum = file.checksums[i];
  81. const size = file.sizes[i];
  82. checksumToOffset.set(checksum, offset);
  83. checksumToSize.set(checksum, size);
  84. offset += size;
  85. }
  86. return {
  87. checksumToOffset,
  88. checksumToOldSize: checksumToSize
  89. };
  90. }
  91. function buildEntryMap(list) {
  92. const result = new Map();
  93. for (const item of list) {
  94. result.set(item.name, item);
  95. }
  96. return result;
  97. }
  98. function buildBlockFileMap(list) {
  99. const result = new Map();
  100. for (const item of list) {
  101. result.set(item.name, item);
  102. }
  103. return result;
  104. }
  105. //# sourceMappingURL=downloadPlanBuilder.js.map