MCPcopy Create free account
hub / github.com/Shazbot/WH3-Mod-Manager / writePackAppendFast

Function writePackAppendFast

src/packFileSerializer.ts:1686–1886  ·  view source on GitHub ↗
(
  packFiles: NewPackedFile[],
  path: string,
  existingPackToAppend?: Pack,
  replaceDuplicates?: boolean,
  dependencyPacks: string[] = [],
)

Source from the content-addressed store, hash-verified

1684};
1685// Fast append-only implementation for existing packs - much faster than sorted insertion
1686export const writePackAppendFast = async (
1687 packFiles: NewPackedFile[],
1688 path: string,
1689 existingPackToAppend?: Pack,
1690 replaceDuplicates?: boolean,
1691 dependencyPacks: string[] = [],
1692) => {
1693 let outFile: BinaryFile | undefined;
1694 let sourceFile: BinaryFile | undefined;
1695 const timestamp = format(new Date(), "ddMMyy_HHmmss");
1696 const outPath = existingPackToAppend ? `${path}_${timestamp}` : path;
1697 try {
1698 if (packFiles.length < 1) return;
1699 ensurePackFilesReadyForWrite(packFiles);
1700 if (existingPackToAppend) {
1701 // FAST PATH: Clone existing pack and append new files
1702 console.log("Fast append mode: cloning existing pack and appending new files");
1703 // Open source file for reading
1704 sourceFile = new BinaryFile(existingPackToAppend.path, "r", true);
1705 console.log("trying to open source file:", existingPackToAppend.path);
1706 await sourceFile.open();
1707 console.log("source file opened");
1708 // Open output file for writing
1709 outFile = new BinaryFile(outPath, "w", true);
1710 await outFile.open();
1711 // Handle duplicate replacement logic
1712 const newFileNames = new Set(packFiles.map((pf) => pf.name));
1713 const filesToKeep = replaceDuplicates
1714 ? existingPackToAppend.packedFiles.filter((pf) => !newFileNames.has(pf.name))
1715 : existingPackToAppend.packedFiles;
1716 // Calculate new counts and sizes
1717 const originalFileCount = existingPackToAppend.packedFiles.length;
1718 const keptFileCount = filesToKeep.length;
1719 const replacedFileCount = originalFileCount - keptFileCount;
1720 const newFileCount = keptFileCount + packFiles.length;
1721 // Use existing dependency packs if not provided
1722 const finalDependencyPacks =
1723 dependencyPacks.length > 0 ? dependencyPacks : existingPackToAppend.dependencyPacks || [];
1724 // Calculate pack_file_index_size based on dependency packs
1725 const pack_file_index_size = finalDependencyPacks.reduce(
1726 (acc, dep) => acc + Buffer.byteLength(dep, "utf8") + 1,
1727 0,
1728 );
1729 // Calculate additional index size needed for new files
1730 const newIndexSize = packFiles.reduce((acc, pack) => acc + new Blob([pack.name]).size + 1 + 5, 0);
1731 // For pack files, the packed_file_index_size in header refers to the file index section
1732 // We need to calculate the total size of existing + new file index entries
1733 const keptIndexSize = filesToKeep.reduce((acc, pf) => acc + new Blob([pf.name]).size + 1 + 5, 0);
1734 const totalIndexSize = keptIndexSize + newIndexSize;
1735 // Write updated header with new counts
1736 const headerAccumulator = new BufferAccumulator(outFile);
1737 headerAccumulator.addString(gameToPackHeader[appData.currentGame]);
1738 headerAccumulator.addInt32(existingPackToAppend.packHeader.byteMask);
1739 headerAccumulator.addInt32(existingPackToAppend.packHeader.refFileCount);
1740 headerAccumulator.addInt32(pack_file_index_size);
1741 headerAccumulator.addInt32(newFileCount); // Updated file count
1742 headerAccumulator.addInt32(totalIndexSize); // Updated index size
1743 headerAccumulator.addInt32(0x7fffffff); // header_buffer

Callers 1

writePackFunction · 0.85

Calls 9

addStringMethod · 0.95
addInt32Method · 0.95
flushMethod · 0.95
addInt8Method · 0.95
flushIfNeededMethod · 0.95
writeFieldBufferedFunction · 0.85
writePackSortedFunction · 0.85
closeMethod · 0.80

Tested by

no test coverage detected