From b9dcbd6455ab4f64a246df1ec59fe3540fc0139b Mon Sep 17 00:00:00 2001 From: Pedro Sousa Date: Fri, 16 Aug 2024 10:28:46 +0200 Subject: [PATCH] feat: improve sync-dir performance --- src/sync-dir.ts | 75 +++++++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 33 deletions(-) diff --git a/src/sync-dir.ts b/src/sync-dir.ts index 5d274d1..8562edf 100644 --- a/src/sync-dir.ts +++ b/src/sync-dir.ts @@ -67,41 +67,50 @@ export const copyDirSafe = async ( const dirsInDest: { [file: string]: boolean } = {} - for await (const file of commonFiles) { - srcCached[file] = srcCached[file] || {} - const srcFilePath = resolve(srcDir, file) - const destFilePath = resolve(destDir, file) - const srcFileStat = srcCached[file].stat || (await fs.stat(srcFilePath)) - srcCached[file].stat = srcFileStat - const destFileStat = await fs.stat(destFilePath) - - const areDirs = srcFileStat.isDirectory() && destFileStat.isDirectory() - dirsInDest[file] = destFileStat.isDirectory() - - const replacedFileWithDir = - srcFileStat.isDirectory() && !destFileStat.isDirectory() - const dirReplacedWithFile = - !srcFileStat.isDirectory() && destFileStat.isDirectory() - if (dirReplacedWithFile || replacedFileWithDir) { - filesToRemove.push(file) - } + const commonFilesStats = await Promise.all( + commonFiles.map(async (file) => { + const srcFilePath = resolve(srcDir, file) + const destFilePath = resolve(destDir, file) + const srcFileStat = srcCached[file]?.stat || (await fs.stat(srcFilePath)) + srcCached[file] = srcCached[file] || { stat: srcFileStat, hash: '' } + const destFileStat = await fs.stat(destFilePath) + return { file, srcFileStat, destFileStat, srcFilePath, destFilePath } + }) + ) - const compareByHash = async () => { - const srcHash = - srcCached[file].hash || (await getFileHash(srcFilePath, '')) - srcCached[file].hash = srcHash - const destHash = await getFileHash(destFilePath, '') - return srcHash === destHash - } - if ( - dirReplacedWithFile || - (!areDirs && - !theSameStats(srcFileStat, destFileStat) && - (!compareContent || !(await compareByHash()))) - ) { - filesToReplace.push(file) + const compareFilesPromises = commonFilesStats.map( + async ({ file, srcFileStat, destFileStat, srcFilePath, destFilePath }) => { + const areDirs = srcFileStat.isDirectory() && destFileStat.isDirectory() + dirsInDest[file] = destFileStat.isDirectory() + + const replacedFileWithDir = + srcFileStat.isDirectory() && !destFileStat.isDirectory() + const dirReplacedWithFile = + !srcFileStat.isDirectory() && destFileStat.isDirectory() + if (dirReplacedWithFile || replacedFileWithDir) { + filesToRemove.push(file) + } + + const compareByHash = async () => { + const srcHash = + srcCached[file].hash || (await getFileHash(srcFilePath, '')) + srcCached[file].hash = srcHash + const destHash = await getFileHash(destFilePath, '') + return srcHash === destHash + } + + if ( + dirReplacedWithFile || + (!areDirs && + !theSameStats(srcFileStat, destFileStat) && + (!compareContent || !(await compareByHash()))) + ) { + filesToReplace.push(file) + } } - } + ) + + await Promise.all(compareFilesPromises) // console.log('newFiles', newFiles) // console.log('filesToRemove', filesToRemove)