From 9248be7e3c24d1d70e0cf7324ac818bd5cf54e50 Mon Sep 17 00:00:00 2001 From: sisong Date: Sun, 28 Jun 2026 16:17:07 +0800 Subject: [PATCH 1/7] recode patch temp mem --- README_cn.md | 4 +- hpatchz.c | 155 +++++++++++++++-------------- libHDiffPatch/HPatch/patch_types.h | 4 + 3 files changed, 88 insertions(+), 75 deletions(-) diff --git a/README_cn.md b/README_cn.md index 3c827b69..0f6bc9a5 100644 --- a/README_cn.md +++ b/README_cn.md @@ -421,7 +421,7 @@ client sync diff&patch by `hsync_demo {old} {newi} {newz} {out_new} -p-1` **hsynz p1 zstd** run hsync_make with `-p-1 -c-zstd-21-24` **hsynz p8 zstd** run hsync_make with `-p-8 -c-zstd-21-24` (run `hsync_demo` with `-p-8`) -update 2026-06-25: adding test HDiffPatch v5.0.0 for WinDiff(optimized patch speed) +2026-06-25 更新: 为 HDiffPatch v5.0.0 的 WinDiff(优化了补丁速度) 添加相关测试 `w` mean diff with `-w-2m`, `WD` mean diff with `-WD -w-2m` **hdiffz w p1 -VCD** diff with `-s-64 -w-2m -VCD-9-8m -d -f -p-1 {old} {new} {pat}` **hdiffz w p8 -VCD** diff with `-s-64 -w-2m -VCD-9-8m -d -f -p-1 {old} {new} {pat}` @@ -545,7 +545,7 @@ update 2026-06-25: adding test HDiffPatch v5.0.0 for WinDiff(optimized patch spe adding test hpatchz&sfpatcher on Android, arm CPU 麒麟980(2×A76 2.6G + 2×A76 1.92G + 4×A55 1.8G) ( [archive-patcher]、[sfpatcher] diff&patch 时针对apk文件格式进行了优化 ) -update 2026-06-25: adding test HDiffPatch v5.0.0 for WinDiff(optimized patch speed) +2026-06-25 更新: 为 HDiffPatch v5.0.0 的 WinDiff(优化了补丁速度) 添加相关测试 `w` mean diff with `-w-2m`, `WD` mean diff with `-WD -w-2m` **测试结果取平均**: diff --git a/hpatchz.c b/hpatchz.c index 27bffcfe..46527573 100644 --- a/hpatchz.c +++ b/hpatchz.c @@ -142,7 +142,7 @@ #if (_IS_NEED_DEFAULT_ChecksumPlugin) //===== select needs checksum plugins or change to your plugin===== # define _ChecksumPlugin_crc32 // 32 bit effective //need zlib -# define _ChecksumPlugin_fadler64 // ? 63 bit effective +# define _ChecksumPlugin_fadler64 // ? 61 bit effective # define _ChecksumPlugin_md5 // 128 bit # define _ChecksumPlugin_xxh3 // 64 bit fast # define _ChecksumPlugin_xxh128 // 128 bit fast @@ -432,6 +432,7 @@ static hpatch_BOOL _toChecksumSet(const char* psets,TPatchChecksumSet* checksumS #define kPatchCacheSize_min (hpatch_kStreamCacheSize*8) #define kPatchCacheSize_default ((size_t)1<<23) #define kPatchCacheSize_bestmin kPatchCacheSize_default +#define kPatchCacheSize_bettermin (kPatchCacheSize_min*8) #define _kNULL_VALUE (-1) #define _kNULL_SIZE (~(size_t)0) @@ -513,6 +514,7 @@ int hpatch_cmd_line(int argc, const char * argv[]){ if (op[2]=='-'){ const char* pnum=op+3; _options_check(kmg_to_size(pnum,strlen(pnum),&patchCacheSize),"-s-?"); + patchCacheSize=_hpatch_pos_max(patchCacheSize,kPatchCacheSize_min); }else{ patchCacheSize=kPatchCacheSize_default; } @@ -968,9 +970,29 @@ static hpatch_BOOL findChecksum(hpatch_TChecksum** out_checksumPlugin,const char } #endif + static TByte* allocPatchMemCache(hpatch_StreamPos_t kMinCacheSize,hpatch_StreamPos_t betterCacheSize,hpatch_size_t* out_memCacheSize); + static hpatch_inline void getPatchMemSize(hpatch_StreamPos_t* out_minCacheSize,hpatch_StreamPos_t* out_betterCacheSize, + hpatch_BOOL isLoadOldAll,hpatch_StreamPos_t oldDataSize, + hpatch_StreamPos_t patchCacheSize,hpatch_StreamPos_t mustAppedSize){ + *out_minCacheSize=mustAppedSize+kPatchCacheSize_min; + if (isLoadOldAll) + *out_betterCacheSize=oldDataSize+mustAppedSize+kPatchCacheSize_bestmin; + else + *out_betterCacheSize=mustAppedSize+patchCacheSize; + } + #if (_IS_NEED_WINDOW_DIFF) + static void getWinPatchMemSize(hpatch_StreamPos_t* out_minCacheSize,hpatch_StreamPos_t* out_betterCacheSize, + hpatch_BOOL isLoadOldAll,hpatch_StreamPos_t oldDataSize,hpatch_StreamPos_t patchCacheSize, + hpatch_StreamPos_t maxWindowOldSize,hpatch_StreamPos_t maxStepMemSize,size_t threadNum){ + hpatch_StreamPos_t betterOldSize=_hpatch_pos_min(maxWindowOldSize*((threadNum>1)?2:1),oldDataSize); + *out_minCacheSize=maxWindowOldSize+maxStepMemSize+kPatchCacheSize_min; + *out_betterCacheSize=betterOldSize+maxStepMemSize+(isLoadOldAll?kPatchCacheSize_bestmin:patchCacheSize); + } + typedef struct _WinPatchListener_t { hpatch_TDecompress* decompressPlugin; + hpatch_BOOL isLoadOldAll; hpatch_StreamPos_t patchCacheSize; const TPatchChecksumSet* checksumSet; size_t threadNum; @@ -1000,23 +1022,11 @@ static hpatch_BOOL _win_onDiffInfo(struct winpatch_listener_t* listener,const hp } } {//memory - const hpatch_StreamPos_t minBufSize=info->maxWindowOldSize+info->maxStepMemSize+(hpatch_kFileIOBufBetterSize*3); - hpatch_StreamPos_t betterBufSize=(ctx->threadNum>1)?minBufSize*2-info->maxStepMemSize:minBufSize; - const hpatch_StreamPos_t idealBufSize=info->maxWindowOldSize+info->maxStepMemSize+ctx->patchCacheSize; - size_t allocSize; - *out_temp_cache=0; - if (((*out_temp_cache)==0)&&(betterBufSizeisLoadOldAll,info->oldDataSize, + ctx->patchCacheSize,info->maxWindowOldSize,info->maxStepMemSize,ctx->threadNum); + *out_temp_cache=allocPatchMemCache(minCacheSize,betterCacheSize,&allocSize); if ((*out_temp_cache)==0){ LOG_ERR("malloc window diff temp cache memory ERROR!\n"); return hpatch_FALSE; @@ -1269,29 +1279,22 @@ int hpatch_printFilesInfos(int fileCount,const char* fileNames[]){ #define _free_mem(p) { if (p) { free(p); p=0; } } -static TByte* getPatchMemCache(hpatch_BOOL isLoadOldAll,size_t patchCacheSize,size_t mustAppendMemSize, - hpatch_StreamPos_t oldDataSize,size_t* out_memCacheSize){ +static TByte* allocPatchMemCache(hpatch_StreamPos_t kMinCacheSize,hpatch_StreamPos_t betterCacheSize,size_t* out_memCacheSize){ TByte* temp_cache=0; size_t temp_cache_size; { - hpatch_StreamPos_t limitCacheSize; - const hpatch_StreamPos_t bestMaxCacheSize=oldDataSize+kPatchCacheSize_bestmin; - if (isLoadOldAll){ - limitCacheSize=bestMaxCacheSize; - }else{ - limitCacheSize=(patchCacheSize(size_t)(_kNULL_SIZE-mustAppendMemSize))//too large - limitCacheSize=(size_t)(_kNULL_SIZE-mustAppendMemSize); - temp_cache_size=(size_t)limitCacheSize; + betterCacheSize=_hpatch_pos_max(kMinCacheSize,betterCacheSize); + if ((sizeof(hpatch_StreamPos_t)>sizeof(size_t))&&(betterCacheSize>=(size_t)(_kNULL_SIZE)))//too large + betterCacheSize=(size_t)(_kNULL_SIZE/2); + temp_cache_size=(size_t)betterCacheSize; } - while (temp_cache_size>=kPatchCacheSize_min){ - temp_cache=(TByte*)malloc(mustAppendMemSize+temp_cache_size); - if (temp_cache) break; + while (temp_cache_size>=kMinCacheSize){ + temp_cache=(TByte*)malloc(temp_cache_size); + if ((temp_cache!=0)||(temp_cache_size==kMinCacheSize)) break; temp_cache_size>>=1; + temp_cache_size=_hpatch_pos_max(temp_cache_size,kMinCacheSize); } - *out_memCacheSize=(temp_cache)?(mustAppendMemSize+temp_cache_size):0; + *out_memCacheSize=(temp_cache)?temp_cache_size:0; return temp_cache; } @@ -1362,7 +1365,7 @@ int hpatch(const char* oldFileName,const char* diffFileName,const char* outNewFi const hpatch_TStreamInput* poldData=&oldData.base; const hpatch_TStreamOutput* pnewData=&newData.base; TByte* temp_cache=0; - size_t temp_cache_size; + size_t temp_cache_size=0; int patch_result=HPATCH_SUCCESS; #if (_IS_NEED_PRINT_PROGRESS) hpatch_TProgressStreamOutput _progressStreamOutput; @@ -1420,36 +1423,44 @@ int hpatch(const char* oldFileName,const char* diffFileName,const char* outNewFi if (diffInfos.isVcDiff) hpatch_TFileStreamOutput_setRandomOut(&newData,hpatch_TRUE); #endif { - hpatch_StreamPos_t maxWindowSize=poldData->streamSize; - hpatch_size_t mustAppendMemSize=0; #if (_IS_NEED_WINDOW_DIFF) - if (diffInfos.isWindowDiff){ - temp_cache=0; temp_cache_size=0; + if (diffInfos.isWindowDiff){ //alloc mem in _win_onDiffInfo }else #endif - { + { //alloc mem + hpatch_StreamPos_t minCacheSize,betterCacheSize; + getPatchMemSize(&minCacheSize,&betterCacheSize,isLoadOldAll,diffInfos.diffInfo.oldDataSize,patchCacheSize,0); #if (_IS_NEED_VCDIFF) - if (diffInfos.isVcDiff){ - hpatch_StreamPos_t maxSrcTargetSize=diffInfos.vcdiffInfo.maxSrcWindowsSize+diffInfos.vcdiffInfo.maxTargetWindowsSize; - maxWindowSize=((!diffInfos.vcdiffInfo.isHDiffzAppHead_a)&&(maxSrcTargetSize<=maxWindowSize+64*(1<<20)))? - maxSrcTargetSize:diffInfos.vcdiffInfo.maxSrcWindowsSize; - if (!diffInfos.vcdiffInfo.isHDiffzAppHead_a) - isLoadOldAll=hpatch_TRUE; + if (diffInfos.isVcDiff){//get vcd patch mem size + const hpatch_StreamPos_t maxSrcWindowsSize=diffInfos.vcdiffInfo.maxSrcWindowsSize; + hpatch_StreamPos_t _bestMaxCacheSize=maxSrcWindowsSize+diffInfos.vcdiffInfo.maxTargetWindowsSize+kPatchCacheSize_bestmin; + if (isLoadOldAll){ + betterCacheSize=_bestMaxCacheSize; + }else{ + betterCacheSize=diffInfos.vcdiffInfo.maxTargetWindowsSize+kPatchCacheSize_bettermin; + if (diffInfos.vcdiffInfo.isHDiffzAppHead_a){ + hpatch_StreamPos_t win2Size=diffInfos.vcdiffInfo.maxTargetWindowsSize*2; + betterCacheSize+=_hpatch_pos_min(win2Size,maxSrcWindowsSize); + }else{ + betterCacheSize+=maxSrcWindowsSize; + } + betterCacheSize=_hpatch_pos_max(betterCacheSize,patchCacheSize); + } } #endif #if (_IS_NEED_SINGLE_STREAM_DIFF) if (diffInfos.isSingleCompressedDiff){ - check(diffInfos.sdiffInfo.stepMemSize==(size_t)diffInfos.sdiffInfo.stepMemSize,HPATCH_MEM_ERROR,"stepMemSize too large"); - mustAppendMemSize=(size_t)diffInfos.sdiffInfo.stepMemSize; + getPatchMemSize(&minCacheSize,&betterCacheSize,isLoadOldAll,diffInfos.diffInfo.oldDataSize, + patchCacheSize,diffInfos.sdiffInfo.stepMemSize); } #endif - temp_cache=getPatchMemCache(isLoadOldAll,patchCacheSize,mustAppendMemSize,maxWindowSize, &temp_cache_size); + { + temp_cache=allocPatchMemCache(minCacheSize,betterCacheSize,&temp_cache_size); + check(temp_cache,HPATCH_MEM_ERROR,"alloc cache memory"); + } } } -#if (_IS_NEED_WINDOW_DIFF) - if (!diffInfos.isWindowDiff) -#endif - check(temp_cache,HPATCH_MEM_ERROR,"alloc cache memory"); + #if (_IS_NEED_PRINT_PROGRESS) pnewData=_progressStreamInput_wrapper(&_progressStreamOutput,pnewData); #endif @@ -1459,6 +1470,7 @@ int hpatch(const char* oldFileName,const char* diffFileName,const char* outNewFi struct winpatch_listener_t winListener; TWindowPatchResult wResult; winCtx.decompressPlugin=decompressPlugin; + winCtx.isLoadOldAll=isLoadOldAll; winCtx.patchCacheSize=patchCacheSize; winCtx.checksumSet=checksumSet; winCtx.threadNum=threadNum; @@ -1480,7 +1492,6 @@ int hpatch(const char* oldFileName,const char* diffFileName,const char* outNewFi #endif #if (_IS_NEED_SINGLE_STREAM_DIFF) if (diffInfos.isSingleCompressedDiff){ - check(temp_cache_size>=diffInfos.sdiffInfo.stepMemSize+hpatch_kStreamCacheSize*3,HPATCH_MEM_ERROR,"alloc cache memory"); if (!patch_single_compressed_diff(pnewData,poldData,&diffData.base,diffInfos.sdiffInfo.diffDataPos, diffInfos.sdiffInfo.uncompressedSize,diffInfos.sdiffInfo.compressedSize,decompressPlugin, diffInfos.sdiffInfo.coverCount,(size_t)diffInfos.sdiffInfo.stepMemSize, @@ -1545,7 +1556,6 @@ int hpatch_dir(const char* oldPath,const char* diffFileName,const char* outNewPa TByte* p_temp_mem=0; TByte* temp_cache=0; size_t temp_cache_size; - size_t min_temp_cache_size=kPatchCacheSize_min; hpatch_TDecompress _decompressPlugin={0}; const hpatch_TStreamInput* oldStream=0; const hpatch_TStreamOutput* newStream=0; @@ -1616,24 +1626,27 @@ int hpatch_dir(const char* oldPath,const char* diffFileName,const char* outNewPa } check(hlistener->patchBegin(hlistener,&dirPatcher), DIRPATCH_PATCHBEGIN_ERROR,"dir patch begin"); - {//mem cache - size_t mustAppendMemSize=0; + { //alloc mem + hpatch_StreamPos_t minCacheSize,betterCacheSize; + getPatchMemSize(&minCacheSize,&betterCacheSize,isLoadOldAll,dirDiffInfo->hdiffInfo.oldDataSize,patchCacheSize,0); +#if (_IS_NEED_WINDOW_DIFF) + if (dirDiffInfo->isWindowDiff){ + getWinPatchMemSize(&minCacheSize,&betterCacheSize,isLoadOldAll,dirDiffInfo->winDiffInfo.oldDataSize, + patchCacheSize,dirDiffInfo->winDiffInfo.maxWindowOldSize, + dirDiffInfo->winDiffInfo.maxStepMemSize,threadNum); + } +#endif #if (_IS_NEED_SINGLE_STREAM_DIFF) if (dirDiffInfo->isSingleCompressedDiff){ - mustAppendMemSize+=(size_t)dirDiffInfo->sdiffInfo.stepMemSize; - min_temp_cache_size+=(size_t)dirDiffInfo->sdiffInfo.stepMemSize; + getPatchMemSize(&minCacheSize,&betterCacheSize,isLoadOldAll,dirDiffInfo->hdiffInfo.oldDataSize, + patchCacheSize,dirDiffInfo->sdiffInfo.stepMemSize); } #endif -#if (_IS_NEED_WINDOW_DIFF) - if (dirDiffInfo->isWindowDiff){ - mustAppendMemSize+=(size_t)(dirDiffInfo->winDiffInfo.maxWindowOldSize+dirDiffInfo->winDiffInfo.maxStepMemSize); - min_temp_cache_size+=(size_t)(dirDiffInfo->winDiffInfo.maxWindowOldSize+dirDiffInfo->winDiffInfo.maxStepMemSize); + { + temp_cache=allocPatchMemCache(minCacheSize,betterCacheSize,&temp_cache_size); + check(temp_cache,HPATCH_MEM_ERROR,"alloc cache memory"); } -#endif - p_temp_mem=getPatchMemCache(isLoadOldAll,patchCacheSize,mustAppendMemSize, - dirDiffInfo->hdiffInfo.oldDataSize, &temp_cache_size); - check(p_temp_mem,HPATCH_MEM_ERROR,"alloc cache memory"); - temp_cache=p_temp_mem; + p_temp_mem=temp_cache; } {// checksumPlugin int wantChecksumCount = checksumSet->isCheck_diffData+checksumSet->isCheck_oldRefData+ @@ -1661,10 +1674,6 @@ int hpatch_dir(const char* oldPath,const char* diffFileName,const char* outNewPa } {//old data - if (temp_cache_size>=dirDiffInfo->hdiffInfo.oldDataSize+min_temp_cache_size){ - // all old while auto cache by patch; not need open old files at same time - kMaxOpenFileNumber=kMaxOpenFileNumber_limit_min; - } check(TDirPatcher_openOldRefAsStream(&dirPatcher,kMaxOpenFileNumber,&oldStream), DIRPATCH_OPEN_OLDPATH_ERROR,"open oldFile"); } diff --git a/libHDiffPatch/HPatch/patch_types.h b/libHDiffPatch/HPatch/patch_types.h index 717556c4..0e363c57 100644 --- a/libHDiffPatch/HPatch/patch_types.h +++ b/libHDiffPatch/HPatch/patch_types.h @@ -157,6 +157,10 @@ typedef hpatch_BOOL hpatch_FileError_t;// 0: no error; other: error; #define _hpatch_align_lower(p,align2pow) _hpatch_align_type_lower(hpatch_size_t,p,align2pow) #define _hpatch_align_upper(p,align2pow) _hpatch_align_lower(((hpatch_size_t)(p))+((align2pow)-1),align2pow) +static hpatch_force_inline hpatch_StreamPos_t _hpatch_pos_min(hpatch_StreamPos_t a,hpatch_StreamPos_t b){ return (ab)?a:b; } + + typedef void* hpatch_TStreamInputHandle; typedef void* hpatch_TStreamOutputHandle; From 78ded7b0f0292399a1d0884879d99e473f0a9a3f Mon Sep 17 00:00:00 2001 From: sisong Date: Sun, 28 Jun 2026 19:58:07 +0800 Subject: [PATCH 2/7] saved a tag in VCDiff format when diff by window mode(-w) ; recode vcd patch temp mem; --- hpatchz.c | 34 +++++++++++++------------------ vcdiff_wrapper/vcdiff_wrapper.cpp | 18 +++++++++++----- vcdiff_wrapper/vcpatch_wrapper.c | 10 +++++++-- vcdiff_wrapper/vcpatch_wrapper.h | 3 ++- 4 files changed, 37 insertions(+), 28 deletions(-) diff --git a/hpatchz.c b/hpatchz.c index 46527573..74c79f7f 100644 --- a/hpatchz.c +++ b/hpatchz.c @@ -196,6 +196,8 @@ static void printUsage(){ " DEFAULT -s-8m; oldPath loaded as Stream;\n" " cacheSize can like 262144 or 256k or 64m or 512m etc....\n" " requires (cacheSize + 4*decompress buffer size)+O(1) bytes of memory.\n" + " if diffFile is window diffData(created by hdiffz -WD-stepSize -w-oldWinSize), then requires\n" + " (cacheSize+ stepSize+oldWinSize + 1*decompress buffer size)+O(1) bytes of memory;\n" " if diffFile is single compressed diffData(created by hdiffz -SD-stepSize), then requires\n" " (cacheSize+ stepSize + 1*decompress buffer size)+O(1) bytes of memory;\n" #if (_IS_NEED_BSDIFF||_IS_NEED_VCDIFF) @@ -207,11 +209,11 @@ static void printUsage(){ " hdiffz -VCD," #endif " then requires\n" - " (cacheSize + 3*decompress buffer size)+O(1) bytes of memory;\n" + " (cacheSize+ 3*decompress buffer size)+O(1) bytes of memory;\n" #endif #if (_IS_NEED_VCDIFF) - " if diffFile is created by xdelta3,open-vcdiff, then requires\n" - " (sourceWindowSize+targetWindowSize + 3*decompress buffer size)+O(1) bytes of memory.\n" + " if diffFile is created by hdiffz -VCD -w,xdelta3,open-vcdiff, then requires\n" + " (cacheSize+ sourceWindowSize+targetWindowSize + 3*decompress buffer size)+O(1) bytes of memory.\n" #endif " -m oldPath all loaded into Memory;\n" " requires (oldFileSize + 4*decompress buffer size)+O(1) bytes of memory.\n" @@ -432,7 +434,6 @@ static hpatch_BOOL _toChecksumSet(const char* psets,TPatchChecksumSet* checksumS #define kPatchCacheSize_min (hpatch_kStreamCacheSize*8) #define kPatchCacheSize_default ((size_t)1<<23) #define kPatchCacheSize_bestmin kPatchCacheSize_default -#define kPatchCacheSize_bettermin (kPatchCacheSize_min*8) #define _kNULL_VALUE (-1) #define _kNULL_SIZE (~(size_t)0) @@ -1146,7 +1147,9 @@ static void _printHDiffInfos(const _THDiffInfos* diffInfos,hpatch_BOOL isInDirDi #endif #if (_IS_NEED_VCDIFF) if (diffInfos->isVcDiff){ - if (diffInfos->vcdiffInfo.isHDiffzAppHead_a) + if (diffInfos->vcdiffInfo.isHDiffzAppHead_window) + typeTag="VCDiff (with hdiffz & window tag)"; + else if (diffInfos->vcdiffInfo.isHDiffzAppHead_a) typeTag="VCDiff (with hdiffz tag)"; else if (diffInfos->vcdiffInfo.isGoogleVersion) typeTag="VCDiff (with google tag)"; @@ -1432,20 +1435,11 @@ int hpatch(const char* oldFileName,const char* diffFileName,const char* outNewFi getPatchMemSize(&minCacheSize,&betterCacheSize,isLoadOldAll,diffInfos.diffInfo.oldDataSize,patchCacheSize,0); #if (_IS_NEED_VCDIFF) if (diffInfos.isVcDiff){//get vcd patch mem size - const hpatch_StreamPos_t maxSrcWindowsSize=diffInfos.vcdiffInfo.maxSrcWindowsSize; - hpatch_StreamPos_t _bestMaxCacheSize=maxSrcWindowsSize+diffInfos.vcdiffInfo.maxTargetWindowsSize+kPatchCacheSize_bestmin; - if (isLoadOldAll){ - betterCacheSize=_bestMaxCacheSize; - }else{ - betterCacheSize=diffInfos.vcdiffInfo.maxTargetWindowsSize+kPatchCacheSize_bettermin; - if (diffInfos.vcdiffInfo.isHDiffzAppHead_a){ - hpatch_StreamPos_t win2Size=diffInfos.vcdiffInfo.maxTargetWindowsSize*2; - betterCacheSize+=_hpatch_pos_min(win2Size,maxSrcWindowsSize); - }else{ - betterCacheSize+=maxSrcWindowsSize; - } - betterCacheSize=_hpatch_pos_max(betterCacheSize,patchCacheSize); - } + hpatch_StreamPos_t stWindowsSize=diffInfos.vcdiffInfo.maxSrcWindowsSize+diffInfos.vcdiffInfo.maxTargetWindowsSize; + if (isLoadOldAll) + betterCacheSize=stWindowsSize+kPatchCacheSize_bestmin; + else if ((!diffInfos.vcdiffInfo.isHDiffzAppHead_a)||(diffInfos.vcdiffInfo.isHDiffzAppHead_window))// vcd default + betterCacheSize=stWindowsSize+patchCacheSize; } #endif #if (_IS_NEED_SINGLE_STREAM_DIFF) @@ -1638,7 +1632,7 @@ int hpatch_dir(const char* oldPath,const char* diffFileName,const char* outNewPa #endif #if (_IS_NEED_SINGLE_STREAM_DIFF) if (dirDiffInfo->isSingleCompressedDiff){ - getPatchMemSize(&minCacheSize,&betterCacheSize,isLoadOldAll,dirDiffInfo->hdiffInfo.oldDataSize, + getPatchMemSize(&minCacheSize,&betterCacheSize,isLoadOldAll,dirDiffInfo->sdiffInfo.oldDataSize, patchCacheSize,dirDiffInfo->sdiffInfo.stepMemSize); } #endif diff --git a/vcdiff_wrapper/vcdiff_wrapper.cpp b/vcdiff_wrapper/vcdiff_wrapper.cpp index 025452a2..a0adffe0 100644 --- a/vcdiff_wrapper/vcdiff_wrapper.cpp +++ b/vcdiff_wrapper/vcdiff_wrapper.cpp @@ -39,13 +39,19 @@ static const hpatch_byte kVcDiffType[3]={('V'|(1<<7)),('C'|(1<<7)),('D'|(1<<7))} #define kVcDiffVersion 0 static const char* kHDiffzAppHead="$hdiffz-VCDIFF&"; +static const char* kHDiffzAppHead_window="#w"; static const char* kHDiffzAppHead_version="#a"; +#define kHDiffzAppHead_maxLen (15+2+(256+4-1)) //fixed for compatible first version -static std::string getHDiffzAppHead(const vcdiff_TCompress* compressPlugin){ +static std::string getHDiffzAppHead(const vcdiff_TCompress* compressPlugin,bool isOutWindowTag){ std::string str(kHDiffzAppHead); if (compressPlugin&&compressPlugin->compress) str+=compressPlugin->compress->compressType(); - return str+kHDiffzAppHead_version; + if (isOutWindowTag) + str+=kHDiffzAppHead_window; + str+=kHDiffzAppHead_version; + _check(str.size()<=kHDiffzAppHead_maxLen,"appHead too long!"); + return str; } namespace hdiff_private{ @@ -444,7 +450,7 @@ static void _writeVcdiffWindowDelta(TDiffStream& outDiff,std::vector& matchWindows, const hpatch_TStreamOutput* out_diff,const vcdiff_TCompress* compressPlugin, - size_t kMaxTargetWindowsSize,size_t kMaxSrcWindowsSize=~(size_t)0){ + size_t kMaxTargetWindowsSize,size_t kMaxSrcWindowsSize=~(size_t)0,bool isOutWindowTag=false){ _out_diff_info(" serialize VCDIFF diffData ...\n"); std::vector buf; TDiffStream outDiff(out_diff); @@ -461,7 +467,7 @@ static void serialize_vcdiff_windows(const hpatch_TStreamInput* newData,const hp if (isHaveCompresser)//VCD_DECOMPRESS buf.push_back(compressPlugin->compress_type); { //VCD_APPHEADER // add HDiffzAppHead tag to out_diff - const std::string HDiffzAppHead=getHDiffzAppHead(compressPlugin); + const std::string HDiffzAppHead=getHDiffzAppHead(compressPlugin,isOutWindowTag); packUInt(buf,HDiffzAppHead.size()); pushCStr(buf,HDiffzAppHead.c_str()); } @@ -660,11 +666,13 @@ void create_vcdiff_window(const hpatch_TStreamInput* newData,const hpatch_TStrea std::vector windows; const bool isExtendCover=false; const bool isCollateMergeCover=false; + const bool isOutWindowTag=true; get_match_covers_and_window(newData,oldData,kNewWindowSize,kOldWindowSize,kSegSize, isCollateMergeCover,covers,windows, kBigCoverSize,kMatchBlockSize,fastMatchBlockSize,kMinSingleMatchScore, isUseBigCacheMatch,mtsets,isExtendCover); - serialize_vcdiff_windows(newData,oldData,covers,windows,out_diff,compressPlugin,kNewWindowSize,kOldWindowSize); + serialize_vcdiff_windows(newData,oldData,covers,windows,out_diff,compressPlugin, + kNewWindowSize,kOldWindowSize,isOutWindowTag); } diff --git a/vcdiff_wrapper/vcpatch_wrapper.c b/vcdiff_wrapper/vcpatch_wrapper.c index 30e2a20e..64df2dac 100644 --- a/vcdiff_wrapper/vcpatch_wrapper.c +++ b/vcdiff_wrapper/vcpatch_wrapper.c @@ -50,10 +50,12 @@ static const hpatch_byte kVcDiffType[3]={('V'|(1<<7)),('C'|(1<<7)),('D'|(1<<7))} #define kVcDiffMinHeadLen (sizeof(kVcDiffType)+1+1) static const char* kHDiffzAppHead="$hdiffz-VCDIFF&"; +static const char* kHDiffzAppHead_window="#w"; static const char* kHDiffzAppHead_version="#a"; #define kHDiffzAppHead_len 15 // = strlen(kHDiffzAppHead); +#define kHDiffzAppHead_window_len 2 // = strlen(kHDiffzAppHead_window); #define kHDiffzAppHead_version_len 2 // = strlen(kHDiffzAppHead_version); -#define kHDiffzAppHead_maxLen (kHDiffzAppHead_len+kHDiffzAppHead_version_len+hpatch_kMaxPluginTypeLength) +#define kHDiffzAppHead_maxLen (kHDiffzAppHead_len+kHDiffzAppHead_window_len+kHDiffzAppHead_version_len+hpatch_kMaxPluginTypeLength) #define _clip_unpackUInt64(_clip,_result) { \ if (!_TStreamCacheClip_unpackUIntWithTag(_clip,_result,0)) \ @@ -309,6 +311,7 @@ hpatch_BOOL getVcDiffInfo(hpatch_VcDiffInfo* out_diffinfo,const hpatch_TStreamIn } #endif assert(kHDiffzAppHead_len==strlen(kHDiffzAppHead)); + assert(kHDiffzAppHead_window_len==strlen(kHDiffzAppHead_window)); assert(kHDiffzAppHead_version_len==strlen(kHDiffzAppHead_version)); assert(kHDiffzAppHead_maxLen<=_kWindowCacheSize); if ((out_diffinfo->appHeadDataLen>=kHDiffzAppHead_len+kHDiffzAppHead_version_len) @@ -317,8 +320,11 @@ hpatch_BOOL getVcDiffInfo(hpatch_VcDiffInfo* out_diffinfo,const hpatch_TStreamIn if (pAppHead==0) return _hpatch_FALSE; if ((0==memcmp(pAppHead,kHDiffzAppHead,kHDiffzAppHead_len)) - &&(0==memcmp(pAppHead+out_diffinfo->appHeadDataLen-kHDiffzAppHead_version_len,kHDiffzAppHead_version,kHDiffzAppHead_version_len))) + &&(0==memcmp(pAppHead+out_diffinfo->appHeadDataLen-kHDiffzAppHead_version_len,kHDiffzAppHead_version,kHDiffzAppHead_version_len))){ out_diffinfo->isHDiffzAppHead_a=hpatch_TRUE; + if (0==memcmp(pAppHead+out_diffinfo->appHeadDataLen-(kHDiffzAppHead_version_len+kHDiffzAppHead_window_len),kHDiffzAppHead_window,kHDiffzAppHead_window_len)) + out_diffinfo->isHDiffzAppHead_window=hpatch_TRUE; + } } if (isNeedWindowSize){ return _getVcDiffWindowSizes(out_diffinfo,diffStream); diff --git a/vcdiff_wrapper/vcpatch_wrapper.h b/vcdiff_wrapper/vcpatch_wrapper.h index 0eb04729..f9c2cb74 100644 --- a/vcdiff_wrapper/vcpatch_wrapper.h +++ b/vcdiff_wrapper/vcpatch_wrapper.h @@ -44,7 +44,8 @@ typedef struct hpatch_VcDiffInfo{ hpatch_StreamPos_t appHeadDataLen; hpatch_StreamPos_t windowOffset; hpatch_BOOL isGoogleVersion; - hpatch_BOOL isHDiffzAppHead_a; + hpatch_BOOL isHDiffzAppHead_a; //version + hpatch_BOOL isHDiffzAppHead_window; vcdiff_compressType compressorID; //WindowInfo hpatch_StreamPos_t maxSrcWindowsSize; From 78a763a0273039a51bc6179cbfe1fdac1d5c3d40 Mon Sep 17 00:00:00 2001 From: sisong Date: Mon, 29 Jun 2026 10:04:40 +0800 Subject: [PATCH 3/7] add bsd&vcd in unit_test; bsd&vcd fix support empty newData; bsd allow no compress; --- bsdiff_wrapper/bspatch_wrapper.c | 25 ++--- builds/vc/unitTest.vcxproj | 4 + test/unit_test.cpp | 170 ++++++++++++++++++++++++++----- vcdiff_wrapper/vcpatch_wrapper.c | 2 +- 4 files changed, 160 insertions(+), 41 deletions(-) diff --git a/bsdiff_wrapper/bspatch_wrapper.c b/bsdiff_wrapper/bspatch_wrapper.c index 3856277d..62f9c4f8 100644 --- a/bsdiff_wrapper/bspatch_wrapper.c +++ b/bsdiff_wrapper/bspatch_wrapper.c @@ -94,7 +94,7 @@ hpatch_BOOL getBsDiffInfo(hpatch_BsDiffInfo* out_diffinfo,const hpatch_TStreamIn } return (out_diffinfo->ctrlDataSizestreamSize)&& (out_diffinfo->subDataSizestreamSize)&& - (out_diffinfo->headSize+out_diffinfo->ctrlDataSize+out_diffinfo->subDataSizestreamSize); + (out_diffinfo->headSize+out_diffinfo->ctrlDataSize+out_diffinfo->subDataSize<=diffStream->streamSize); } hpatch_BOOL getBsDiffInfo_mem(hpatch_BsDiffInfo* out_diffinfo,const unsigned char* diffData,const unsigned char* diffData_end){ @@ -185,6 +185,11 @@ hpatch_BOOL bspatchByClip(_TOutStreamCache* outCache,const hpatch_TStreamInput* static const hpatch_uint64_t _kUnknowMaxSize=~(hpatch_uint64_t)0; #define _clear_return(exitValue) { result=exitValue; goto clear; } +#define _getStreamClip(_diffClip,_decompresser,_dataSize) \ + getStreamClip(_diffClip,_decompresser, \ + decompressPlugin?_kUnknowMaxSize:(_dataSize),decompressPlugin?(_dataSize):0, \ + compressedDiff,&diffPos0,decompressPlugin,temp_cache,cacheSize) + hpatch_BOOL bspatch_with_cache(const hpatch_TStreamOutput* out_newData, const hpatch_TStreamInput* oldData, const hpatch_TStreamInput* compressedDiff, @@ -202,7 +207,7 @@ hpatch_BOOL bspatch_with_cache(const hpatch_TStreamOutput* out_newData, hpatch_StreamPos_t diffPos0; hpatch_size_t cacheSize; hpatch_BOOL isReadError=hpatch_FALSE; - assert(decompressPlugin!=0); + //assert(decompressPlugin!=0); assert(out_newData!=0); assert(out_newData->write!=0); assert(oldData!=0); @@ -224,24 +229,16 @@ hpatch_BOOL bspatch_with_cache(const hpatch_TStreamOutput* out_newData, diffPos0=diffInfo.headSize; if (diffInfo.isEndsleyBsdiff){ - if (!getStreamClip(&newDataDiffClip,&decompressers[0], - _kUnknowMaxSize,compressedDiff->streamSize-diffPos0,compressedDiff,&diffPos0, - decompressPlugin,temp_cache,cacheSize)) _clear_return(_hpatch_FALSE); + if (!_getStreamClip(&newDataDiffClip,&decompressers[0],compressedDiff->streamSize-diffPos0)) _clear_return(_hpatch_FALSE); temp_cache+=cacheSize; _ctrlClip=&newDataDiffClip; _subClip=&newDataDiffClip; }else{ - if (!getStreamClip(&ctrlClip,&decompressers[0], - _kUnknowMaxSize,diffInfo.ctrlDataSize,compressedDiff,&diffPos0, - decompressPlugin,temp_cache,cacheSize)) _clear_return(_hpatch_FALSE); + if (!_getStreamClip(&ctrlClip,&decompressers[0],diffInfo.ctrlDataSize)) _clear_return(_hpatch_FALSE); temp_cache+=cacheSize; - if (!getStreamClip(&subClip,&decompressers[1], - _kUnknowMaxSize,diffInfo.subDataSize,compressedDiff,&diffPos0, - decompressPlugin,temp_cache,cacheSize)) _clear_return(_hpatch_FALSE); + if (!_getStreamClip(&subClip,&decompressers[1],diffInfo.subDataSize)) _clear_return(_hpatch_FALSE); temp_cache+=cacheSize; - if (!getStreamClip(&newDataDiffClip,&decompressers[2], - _kUnknowMaxSize,compressedDiff->streamSize-diffPos0,compressedDiff,&diffPos0, - decompressPlugin,temp_cache,cacheSize)) _clear_return(_hpatch_FALSE); + if (!_getStreamClip(&newDataDiffClip,&decompressers[2],compressedDiff->streamSize-diffPos0)) _clear_return(_hpatch_FALSE); temp_cache+=cacheSize; } assert(diffPos0==compressedDiff->streamSize); diff --git a/builds/vc/unitTest.vcxproj b/builds/vc/unitTest.vcxproj index 8f72fdbb..220cbfed 100644 --- a/builds/vc/unitTest.vcxproj +++ b/builds/vc/unitTest.vcxproj @@ -237,6 +237,8 @@ + + @@ -276,6 +278,8 @@ + + diff --git a/test/unit_test.cpp b/test/unit_test.cpp index 12703bd8..698229a8 100644 --- a/test/unit_test.cpp +++ b/test/unit_test.cpp @@ -43,6 +43,10 @@ #include "../libHDiffPatch/HDiff/private_diff/limit_mem_diff/stream_serialize.h" #include "../libhsync/sync_make/sync_make.h" #include "../libhsync/sync_client/sync_client.h" +#include "../vcdiff_wrapper/vcdiff_wrapper.h" +#include "../vcdiff_wrapper/vcpatch_wrapper.h" +#include "../bsdiff_wrapper/bsdiff_wrapper.h" +#include "../bsdiff_wrapper/bspatch_wrapper.h" using namespace hdiff_private; typedef unsigned char TByte; typedef ptrdiff_t TInt; @@ -51,6 +55,27 @@ const long kRandTestCount=5000; const size_t patch_threadNum=1; // 1..5; 1 single-thread, >1 multi-threads //#define _AttackPacth_ON +enum TDiffType{ + kDiffO, + kDiffZ, //compressed diff + kDiffZs, + kDiffS, //single compressed diff + kDiffSs, + kDiffi, //lite + kDiffiI, //inplace-patch + kDiffW, //winDiff + kHSynz, //hsynz + kDiffV, //vcdiff + kDiffVs, + kDiffB, //BSDiff + kDiffBs, + + kDiffTypeCount, +}; + +static const hpatch_byte g_testControl[kDiffTypeCount]={ 1, 1,1, 1,1, 1,1, 1, 1, 1,1, 1,1 }; +//static const hpatch_byte g_testControl[kDiffTypeCount]={ 0, 0,0, 0,0, 0,0, 0, 0, 0,0, 0,0 }; + //===== select compress plugin ===== #define _CompressPlugin_no //#define _CompressPlugin_zlib @@ -428,19 +453,6 @@ bool _check_hsynz_sync_patch(const TByte* newData,const TByte* newData_end, return true; } -enum TDiffType{ - kDiffO, - kDiffZ, - kDiffZs, - kDiffS, - kDiffSs, - kDiffi, - kDiffiI, //inplace-patch - kDiffW, - kHSynz, -}; -static const size_t kDiffTypeCount=kHSynz+1; - #ifdef _AttackPacth_ON static unsigned char* _get_temp_cache(size_t temp_cache_size){ @@ -476,7 +488,7 @@ static hpatch_BOOL _winpatch_onDiffInfo(struct winpatch_listener_t* listener, hpatch_BOOL* isChecksumNew,hpatch_BOOL* isChecksumOld,hpatch_BOOL* isChecksumDiff, unsigned char** out_temp_cache, unsigned char** out_temp_cacheEnd){ - size_t temp_cache_size=(size_t)(info->maxWindowOldSize+info->maxStepMemSize)+hpatch_kFileIOBufBetterSize*3; + size_t temp_cache_size=(size_t)(info->maxWindowOldSize*2+info->maxStepMemSize)+hpatch_kFileIOBufBetterSize*3; unsigned char* temp_cache=_get_temp_cache(temp_cache_size); if (temp_cache==0) return hpatch_FALSE; *out_temp_cache=temp_cache; @@ -551,6 +563,7 @@ long _attackPacth(TByte* out_newData,TByte* out_newData_end, const TByte* oldData,const TByte* oldData_end, const TByte* diffData,const TByte* diffData_end, const char* error_tag,TDiffType diffType){ + static std::vector _temp_cache((size_t)hdiff_kFileIOBufBestSize*4); switch (diffType){ case kDiffO: { hpatch_BOOL rt0=patch(out_newData,out_newData_end,oldData,oldData_end,diffData,diffData_end); @@ -589,6 +602,26 @@ long _attackPacth(TByte* out_newData,TByte* out_newData_end, mem_as_hStreamInput(&diffStream,diffData,diffData_end); patch_window_diff(&listener,&out_newStream,&oldStream,&diffStream,0,patch_threadNum); } break; + case kDiffV: case kDiffVs: { + struct hpatch_TStreamOutput out_newStream; + struct hpatch_TStreamInput oldStream; + struct hpatch_TStreamInput diffStream; + mem_as_hStreamOutput(&out_newStream,out_newData,out_newData_end); + mem_as_hStreamInput(&oldStream,oldData,oldData_end); + mem_as_hStreamInput(&diffStream,diffData,diffData_end); + vcpatch_with_cache(&out_newStream,&oldStream,&diffStream,decompressPlugin,hpatch_FALSE, + _temp_cache.data(),_temp_cache.data()+_temp_cache.size()); + } break; + case kDiffB: case kDiffBs: { + struct hpatch_TStreamOutput out_newStream; + struct hpatch_TStreamInput oldStream; + struct hpatch_TStreamInput diffStream; + mem_as_hStreamOutput(&out_newStream,out_newData,out_newData_end); + mem_as_hStreamInput(&oldStream,oldData,oldData_end); + mem_as_hStreamInput(&diffStream,diffData,diffData_end); + bspatch_with_cache(&out_newStream,&oldStream,&diffStream,decompressPlugin, + _temp_cache.data(),_temp_cache.data()+_temp_cache.size()); + } break; } return 0; } @@ -651,7 +684,7 @@ long test(const TByte* newData,const TByte* newData_end, const TByte* oldData,const TByte* oldData_end,const char* tag,hpatch_StreamPos_t* out_diffSizes){ printf("%s newSize:%ld oldSize:%ld ",tag, (long)(newData_end-newData), (long)(oldData_end-oldData)); long result=0; - {//test diffs + if (g_testControl[kDiffS]){//test diffs std::vector diffData; create_single_compressed_diff(newData,newData_end,oldData,oldData_end,diffData,compressPlugin); if (out_diffSizes) out_diffSizes[kDiffS]+=diffData.size(); @@ -668,7 +701,7 @@ long test(const TByte* newData,const TByte* newData_end, #endif } } - {//test diffs stream + if (g_testControl[kDiffSs]){//test diffs stream std::vector diffData; struct hpatch_TStreamInput newStream; struct hpatch_TStreamInput oldStream; @@ -692,7 +725,7 @@ long test(const TByte* newData,const TByte* newData_end, #endif } } - {//test diffz + if (g_testControl[kDiffZ]){//test diffz std::vector diffData; create_compressed_diff(newData,newData_end,oldData,oldData_end,diffData,compressPlugin); if (out_diffSizes) out_diffSizes[kDiffZ]+=diffData.size(); @@ -709,7 +742,7 @@ long test(const TByte* newData,const TByte* newData_end, #endif } } - {//test diffz stream + if (g_testControl[kDiffZs]){//test diffz stream std::vector diffData; struct hpatch_TStreamInput newStream; struct hpatch_TStreamInput oldStream; @@ -733,7 +766,7 @@ long test(const TByte* newData,const TByte* newData_end, #endif } } - {//test diffi + if (g_testControl[kDiffi]){//test diffi std::vector diffData; hdiffi_TCompress compressPlugini={compressPlugin,compressHpiType}; create_lite_diff(newData,newData_end,oldData,oldData_end,diffData,&compressPlugini); @@ -752,7 +785,7 @@ long test(const TByte* newData,const TByte* newData_end, } } - {//test diffi inplace-patch + if (g_testControl[kDiffiI]){//test diffi inplace-patch std::vector diffData; hdiffi_TCompress compressPlugini={compressPlugin,compressHpiType}; size_t extraSafeSize=(size_t)(_rand()*(1.0/RAND_MAX)*(size_t)(oldData_end-oldData)); @@ -771,7 +804,7 @@ long test(const TByte* newData,const TByte* newData_end, #endif } } - {//test diff + if (g_testControl[kDiffO]){//test diff std::vector diffData; create_diff(newData,newData_end,oldData,oldData_end, diffData); if (out_diffSizes) out_diffSizes[kDiffO]+=diffData.size(); @@ -789,7 +822,7 @@ long test(const TByte* newData,const TByte* newData_end, #endif } } - {//test diffw + if (g_testControl[kDiffW]){//test diffw std::vector diffData; struct hpatch_TStreamInput newStream; struct hpatch_TStreamInput oldStream; @@ -817,7 +850,89 @@ long test(const TByte* newData,const TByte* newData_end, #endif } } - {//test hsynz + if (g_testControl[kDiffV]){//test vcdiff + std::vector diffData; + TVectorAsStreamOutput out_diffStream(diffData); + create_vcdiff(newData,newData_end,oldData,oldData_end,&out_diffStream); + if (out_diffSizes) out_diffSizes[kDiffV]+=diffData.size(); + if (!check_vcdiff(newData,newData_end,oldData,oldData_end, + diffData.data(),diffData.data()+diffData.size(),decompressPlugin)){ + printf("\n vcdiff error!!! tag:%s\n",tag); + ++result; + }else{ + printf(" vcdiff:%ld", (long)(diffData.size())); +#ifdef _AttackPacth_ON + long exceptionCount=attackPacth(newData_end-newData,oldData,oldData_end, + diffData.data(),diffData.data()+diffData.size(),_rand(),kDiffV); + if (exceptionCount>0) return exceptionCount; +#endif + } + } + if (g_testControl[kDiffVs]){//test vcdiff stream + std::vector diffData; + struct hpatch_TStreamInput newStream; + struct hpatch_TStreamInput oldStream; + TVectorAsStreamOutput out_diffStream(diffData); + mem_as_hStreamInput(&newStream,newData,newData_end); + mem_as_hStreamInput(&oldStream,oldData,oldData_end); + create_vcdiff_stream(&newStream,&oldStream,&out_diffStream); + if (out_diffSizes) out_diffSizes[kDiffVs]+=diffData.size(); + struct hpatch_TStreamInput in_diffStream; + mem_as_hStreamInput(&in_diffStream,diffData.data(),diffData.data()+diffData.size()); + if (!check_vcdiff(&newStream,&oldStream,&in_diffStream,decompressPlugin)){ + printf("\n vcdiff(stream) error!!! tag:%s\n",tag); + ++result; + }else{ + printf(" vcdiff(stream):%ld", (long)(diffData.size())); +#ifdef _AttackPacth_ON + long exceptionCount=attackPacth(newData_end-newData,oldData,oldData_end, + diffData.data(),diffData.data()+diffData.size(),_rand(),kDiffVs); + if (exceptionCount>0) return exceptionCount; +#endif + } + } + if (g_testControl[kDiffB]){//test bsdiff + std::vector diffData; + TVectorAsStreamOutput out_diffStream(diffData); + create_bsdiff(newData,newData_end,oldData,oldData_end,&out_diffStream,compressPlugin); + if (out_diffSizes) out_diffSizes[kDiffB]+=diffData.size(); + if (!check_bsdiff(newData,newData_end,oldData,oldData_end, + diffData.data(),diffData.data()+diffData.size(),decompressPlugin)){ + printf("\n bsdiff error!!! tag:%s\n",tag); + ++result; + }else{ + printf(" bsdiff:%ld", (long)(diffData.size())); +#ifdef _AttackPacth_ON + long exceptionCount=attackPacth(newData_end-newData,oldData,oldData_end, + diffData.data(),diffData.data()+diffData.size(),_rand(),kDiffB); + if (exceptionCount>0) return exceptionCount; +#endif + } + } + if (g_testControl[kDiffBs]){//test bsdiff stream + std::vector diffData; + struct hpatch_TStreamInput newStream; + struct hpatch_TStreamInput oldStream; + TVectorAsStreamOutput out_diffStream(diffData); + mem_as_hStreamInput(&newStream,newData,newData_end); + mem_as_hStreamInput(&oldStream,oldData,oldData_end); + create_bsdiff_stream(&newStream,&oldStream,&out_diffStream,compressPlugin); + if (out_diffSizes) out_diffSizes[kDiffBs]+=diffData.size(); + struct hpatch_TStreamInput in_diffStream; + mem_as_hStreamInput(&in_diffStream,diffData.data(),diffData.data()+diffData.size()); + if (!check_bsdiff(&newStream,&oldStream,&in_diffStream,decompressPlugin)){ + printf("\n bsdiff(stream) error!!! tag:%s\n",tag); + ++result; + }else{ + printf(" bsdiff(stream):%ld", (long)(diffData.size())); +#ifdef _AttackPacth_ON + long exceptionCount=attackPacth(newData_end-newData,oldData,oldData_end, + diffData.data(),diffData.data()+diffData.size(),_rand(),kDiffBs); + if (exceptionCount>0) return exceptionCount; +#endif + } + } + if (g_testControl[kHSynz]){//test hsynz std::vector diffData; _create_hsynz_diff(newData,newData_end,oldData,oldData_end,diffData); if (out_diffSizes) out_diffSizes[kHSynz]+=diffData.size(); @@ -893,7 +1008,7 @@ int main(int argc, const char * argv[]){ hpatch_StreamPos_t diffSize14[kDiffTypeCount]={0}; errorCount+=test(data14, data14+dataSize,data14, data14+dataSize, "14",diffSize14); for (int i=0;i=dataSize){ + if ((diffSize14[i]>=dataSize)&&((i!=kDiffB)&&(i!=kDiffBs))){ ++errorCount; printf("error!!! tag:%s\n","14 test diff size"); } @@ -948,12 +1063,15 @@ int main(int argc, const char * argv[]){ printf("\nchecked:%ld errorCount:%ld\n",kRandTestCount,errorCount); printf("newSize:100%% oldSize:%2.2f%% diffO:%2.2f%% diffZ:%2.2f%%(s:%2.2f%%)" - " diffS:%2.2f%%(s:%2.2f%%) diffi:%2.2f%% diffiI:%2.2f%% diffW:%2.2f%% hsynz:%2.2f%%\n", + " diffS:%2.2f%%(s:%2.2f%%) diffi:%2.2f%% diffiI:%2.2f%% diffW:%2.2f%%" + " hsynz:%2.2f%% vcdiff:%2.2f%%(s:%2.2f%%) bsdiff:%2.2f%%(s:%2.2f%%)\n", sumOldSize*100.0/sumNewSize,sumDiffSizes[kDiffO]*100.0/sumNewSize, sumDiffSizes[kDiffZ]*100.0/sumNewSize,sumDiffSizes[kDiffZs]*100.0/sumNewSize, sumDiffSizes[kDiffS]*100.0/sumNewSize,sumDiffSizes[kDiffSs]*100.0/sumNewSize, sumDiffSizes[kDiffi]*100.0/sumNewSize,sumDiffSizes[kDiffiI]*100.0/sumNewSize, - sumDiffSizes[kDiffW]*100.0/sumNewSize,sumDiffSizes[kHSynz]*100.0/sumNewSize); + sumDiffSizes[kDiffW]*100.0/sumNewSize,sumDiffSizes[kHSynz]*100.0/sumNewSize, + sumDiffSizes[kDiffV]*100.0/sumNewSize,sumDiffSizes[kDiffVs]*100.0/sumNewSize, + sumDiffSizes[kDiffB]*100.0/sumNewSize,sumDiffSizes[kDiffBs]*100.0/sumNewSize); clock_t time2=clock(); printf("\nrun time:%.1f s\n",(time2-time1)*(1.0/CLOCKS_PER_SEC)); diff --git a/vcdiff_wrapper/vcpatch_wrapper.c b/vcdiff_wrapper/vcpatch_wrapper.c index 64df2dac..424f0090 100644 --- a/vcdiff_wrapper/vcpatch_wrapper.c +++ b/vcdiff_wrapper/vcpatch_wrapper.c @@ -306,7 +306,7 @@ hpatch_BOOL getVcDiffInfo(hpatch_VcDiffInfo* out_diffinfo,const hpatch_TStreamIn #ifdef __RUN_MEM_SAFE_CHECK { const hpatch_StreamPos_t maxPos=_TStreamCacheClip_leaveSize(&diffClip); - if ( (out_diffinfo->appHeadDataLen>maxPos)||(out_diffinfo->windowOffset>maxPos) ) + if ( (out_diffinfo->appHeadDataLen>maxPos)||(out_diffinfo->windowOffset>diffStream->streamSize) ) return _hpatch_FALSE; //data size error } #endif From ecd21dc40247a5f42985a8b34c6b8904fa548d4b Mon Sep 17 00:00:00 2001 From: sisong Date: Tue, 30 Jun 2026 17:22:27 +0800 Subject: [PATCH 4/7] update func doc; update readme & test result; --- README.md | 229 +++++++++++++------------- README_cn.md | 254 +++++++++++++++-------------- hdiffz.cpp | 2 +- hpatchz.c | 18 +- libHDiffPatch/HDiff/diff.cpp | 8 +- libHDiffPatch/HDiff/diff.h | 26 ++- libHDiffPatch/HPatch/patch.c | 3 +- libHDiffPatch/HPatch/patch.h | 16 -- libHDiffPatch/HPatch/patch_types.h | 26 ++- 9 files changed, 303 insertions(+), 279 deletions(-) diff --git a/README.md b/README.md index 4c88dcdd..a5e7a27a 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,11 @@ apply the delta: Tip: `-WD` format supports multi-thread to speed up patching, for example add `-p-5` parameter (multi-thread not recommended on HDD) ## Build it yourself ``` +git clone --recurse-submodules https://github.com/sisong/HDiffPatch5.git +cd +``` +or +``` cd git clone https://github.com/sisong/HDiffPatch.git HDiffPatch git clone https://github.com/sisong/libmd5.git libmd5 @@ -119,7 +124,7 @@ options: big cache max used O(oldFileSize) memory, and build slow(diff speed--) -w[-oldWinSize-segSize] diff by window mode; optimize read old data when patch; - in -m mode, outDiffFile size+, in -s mode, outDiffFile size-- & patch speed-; + in -m mode, outDiffFile size+, in -s mode, outDiffFile size--; if oldWinSize+ or segSize-, outDiffFile size-, but diff & patch speed-- oldWinSize: max window bytes on old data, DEFAULT -w-2m; for big file, recommended -w-4m-128k, -w-16m-256k, etc... @@ -189,7 +194,6 @@ options: support run by multi-thread parallel, fast! -C-checksumType set outDiffFile Checksum type, for directory diff, DEFAULT -C-fadler64; for -WD, DEFAULT -C-xxh128; - (if need checksum for diff between two files, add -D) support checksum type: -C-no no checksum -C-crc32 @@ -254,20 +258,26 @@ options: -s[-cacheSize] DEFAULT -s-8m; oldPath loaded as Stream; cacheSize can like 262144 or 256k or 64m or 512m etc.... - requires (cacheSize + 4*decompress buffer size)+O(1) bytes of memory. + if diffFile is window diffData(created by hdiffz -WD-stepSize -w-oldWinSize), then requires + (cacheSize+ oldWinSize+stepSize + 1*decompress buffer size)+O(1) bytes of memory; if diffFile is single compressed diffData(created by hdiffz -SD-stepSize), then requires (cacheSize+ stepSize + 1*decompress buffer size)+O(1) bytes of memory; + if diffFile is compressed diffData(created by hdiffz), then requires + (cacheSize + 4*decompress buffer size)+O(1) bytes of memory. if diffFile is created by hdiffz -BSD,bsdiff4, hdiffz -VCD, then requires - (cacheSize + 3*decompress buffer size)+O(1) bytes of memory; - if diffFile is created by xdelta3,open-vcdiff, then requires - (sourceWindowSize+targetWindowSize + 3*decompress buffer size)+O(1) bytes of memory. + (cacheSize+ 3*decompress buffer size)+O(1) bytes of memory; + if diffFile is created by hdiffz -VCD -w,xdelta3,open-vcdiff, then requires + (cacheSize+ sourceWindowSize+targetWindowSize + 3*decompress buffer size)+O(1) bytes of memory. -m oldPath all loaded into Memory; - requires (oldFileSize + 4*decompress buffer size)+O(1) bytes of memory. + if diffFile is window diffData(created by hdiffz -WD-stepSize -w-oldWinSize), then requires + (oldWinSize + stepSize + 1*decompress buffer size)+O(1) bytes of memory; if diffFile is single compressed diffData(created by hdiffz -SD-stepSize), then requires - (oldFileSize+ stepSize + 1*decompress buffer size)+O(1) bytes of memory. + (oldFileSize + stepSize + 1*decompress buffer size)+O(1) bytes of memory. + if diffFile is compressed diffData(created by hdiffz), then requires + (oldFileSize + 4*decompress buffer size)+O(1) bytes of memory. if diffFile is created by hdiffz -BSD,bsdiff4, then requires (oldFileSize + 3*decompress buffer size)+O(1) bytes of memory. - if diffFile is VCDIFF(created by hdiffz -VCD,xdelta3,open-vcdiff), then requires + if diffFile is VCDIFF(created by hdiffz -VCD,hdiffz -VCD -w,xdelta3,open-vcdiff), then requires (sourceWindowSize+targetWindowSize + 3*decompress buffer size)+O(1) bytes of memory. -p-parallelThreadNumber if parallelThreadNumber>1 then open multi-thread Parallel mode; @@ -324,7 +334,7 @@ options: * **patch_decompress()** * **patch_decompress_with_cache()** * **patch_decompress_mem()** -### v3 API, **diff**&**patch** between directories(folder): +### v3 API, **diff**&**patch** between directories (HDIFF19): * **dir_diff()** * **TDirPatcher_\*()** functions with **struct TDirPatcher** ### v4 API, single compressed diffData (HDIFFSF20): @@ -357,13 +367,10 @@ options: #### hsynz API, diff&patch by sync (demo [hsynz]): * **create_sync_data()** * **create_dir_sync_data()** -* **sync_patch()** -* **sync_patch_...()** -* **sync_local_diff()** -* **sync_local_diff_...()** -* **sync_local_patch()** -* **sync_local_patch_...()** -* **create_hdiff_by_sign()** (patched by patch_single_stream()...) +* **sync_patch...()** +* **sync_local_diff...()** +* **sync_local_patch...()** +* **create_hdiff_by_sign()** (patched by patch_single_stream(), scenario like [rsync]) #### [zsync] wrapper API, (demo [hsynz]): * **create_zsync_data()** * **zsync_patch...()** @@ -398,19 +405,20 @@ case list([download from OneDrive](https://1drv.ms/u/s!Aj8ygMPeifoQgULlawtabR9lh **test PC**: Windows11, CPU R9-7945HX, SSD PCIe4.0x4 4T, DDR5 5200MHz 32Gx2 -**Program version**: HDiffPatch4.6.3, hsynz 1.1.0, BsDiff4.3, xdelta3.1, zstd1.5.2 +**Program version**: HDiffPatch5.0.1, hsynz1.1.0, BsDiff4.3, xdelta3.1, zstd1.5.7 **test Program**: **zstd --patch-from** diff with `--ultra -21 --long=24 -f --patch-from={old} {new} -o {pat}` zstd patch with `-d -f --memory=2047MB --patch-from={old} {pat} -o {new}` **xdelta3** diff with `-S lzma -e -9 -n -f -s {old} {new} {pat}` -**xdelta3** patch with `-d -f -s {old} {pat} {new}` -& adding **hpatchz** test: `hpatchz -m -f {old} {xdelta3-pat} {new}` + xdelta3 patch with `-n -d -f -s {old} {pat} {new}` + & adding **hpatchz** test: `hpatchz -f {old} {xdelta3-pat} {new}` **xdelta3 -B** diff with `-S lzma -B {oldSize} -e -9 -n -f -s {old} {new} {pat}` -**xdelta3 -B** patch with `-B {oldSize} -d -f -s {old} {pat} {new}` -& adding **hpatchz** test: `hpatchz -m -f {old} {xdelta3-B-pat} {new}` +xdelta3 -B patch with `-B {oldSize} -d -f -s {old} {pat} {new}` + & adding **hpatchz** test: `hpatchz -f {old} {xdelta3-B-pat} {new}` **bsdiff** diff with `{old} {new} {pat}` -**bspatch** patch with `{old} {new} {pat}` -& adding **hpatchz** test: `hpatchz -m -f {old} {bsdiff-pat} {new}` + bspatch patch with `{old} {new} {pat}` + & adding **hpatchz** test: `hpatchz -m -f {old} {bsdiff-pat} {new}` + & adding **hpatchz** test: `hpatchz -s -f {old} {bsdiff-pat} {new}` **hdiffz -BSD** diff with `-m-6 -BSD -d -f -p-1 {old} {new} {pat}` **hdiffz zlib** diff with `-m-6 -SD -d -f -p-1 -c-zlib-9 {old} {new} {pat}` **hdiffz lzma2** diff with `-m-6 -SD -d -f -p-1 -c-lzma2-9-16m {old} {new} {pat}` @@ -418,19 +426,19 @@ case list([download from OneDrive](https://1drv.ms/u/s!Aj8ygMPeifoQgULlawtabR9lh **hdiffz s zlib** diff with `-s-64 -SD -d -f -p-1 -c-zlib-9 {old} {new} {pat}` **hdiffz s lzma2** diff with `-s-64 -SD -d -f -p-1 -c-lzma2-9-16m {old} {new} {pat}` **hdiffz s zstd** diff with `-s-64 -SD -d -f -p-1 -c-zstd-21-24 {old} {new} {pat}` -& adding all **hdiffz** test with -p-8 -**hpatchz** patch with `-s-3m -f {old} {pat} {new}` + & adding all **hdiffz** test with -p-8 + hpatchz patch with `-f {old} {pat} {new}` **hsynz** test, make sync info by `hsync_make -s-2k {new} {out_newi} {out_newz}`, -client sync diff&patch by `hsync_demo {old} {newi} {newz} {out_new} -p-1` + client sync diff&patch by `hsync_demo {old} {newi} {newz} {out_new} -p-1` **hsynz p1 zlib** run hsync_make with `-p-1 -c-zlib-9` **hsynz p8 zlib** run hsync_make with `-p-8 -c-zlib-9` (run `hsync_demo` with `-p-8`) **hsynz p1 zstd** run hsync_make with `-p-1 -c-zstd-21-24` **hsynz p8 zstd** run hsync_make with `-p-8 -c-zstd-21-24` (run `hsync_demo` with `-p-8`) -update 2026-06-25: adding test HDiffPatch v5.0.0 for WinDiff(optimized patch speed) -`w` mean diff with `-w-2m`, `WD` mean diff with `-WD -w-2m` -**hdiffz w p1 -VCD** diff with `-s-64 -w-2m -VCD-9-8m -d -f -p-1 {old} {new} {pat}` -**hdiffz w p8 -VCD** diff with `-s-64 -w-2m -VCD-9-8m -d -f -p-1 {old} {new} {pat}` +adding test for Window Diff(optimized patch speed) +`s` mean diff with `-s-64`, `w` mean diff with `-w-2m`, `WD` mean diff with `-WD -w-2m` +**hdiffz sw p1 -VCD** diff with `-s-64 -w-2m -VCD-9-8m -d -f -p-1 {old} {new} {pat}` +**hdiffz sw p8 -VCD** diff with `-s-64 -w-2m -VCD-9-8m -d -f -p-8 {old} {new} {pat}` **hdiffz w p8 lzma2** diff with `-m-6 -SD -w-2m -d -f -p-8 -c-lzma2-9-16m {old} {new} {pat}` **hdiffz w p8 zstd** diff with `-m-6 -SD -w-2m -d -f -p-8 -c-zstd-21-24 {old} {new} {pat}` **hdiffz sw p8 lzma2** diff with `-s-64 -SD -w-2m -d -f -p-8 -c-lzma2-9-16m {old} {new} {pat}` @@ -443,8 +451,8 @@ update 2026-06-25: adding test HDiffPatch v5.0.0 for WinDiff(optimized patch spe **hdiffz sWD p8 lzma2** diff with `-s-64 -WD -w-2m -d -f -p-8 -c-lzma2-9-16m {old} {new} {pat}` **hdiffz sWD p1 zstd** diff with `-s-64 -WD -w-2m -d -f -p-1 -c-zstd-21-24 {old} {new} {pat}` **hdiffz sWD p8 zstd** diff with `-s-64 -WD -w-2m -d -f -p-8 -c-zstd-21-24 {old} {new} {pat}` - & **hpatchz** patch with `-s-8m -C-no -p-1 -f {old} {pat} {new}` when diff with `-WD -p-1` - & **hpatchz** patch with `-s-8m -C-no -p-5 -f {old} {pat} {new}` when diff with `-WD -p-8` + & hpatchz patch with `-C-no -p-1 -f {old} {pat} {new}` when diff with `-WD -p-1` + & hpatchz patch with `-C-no -p-5 -f {old} {pat} {new}` when diff with `-WD -p-8` or `-SD -w-2m -p-8` **test result average**: |Program|compress|diff mem|speed|patch mem|max mem|speed| @@ -452,50 +460,51 @@ update 2026-06-25: adding test HDiffPatch v5.0.0 for WinDiff(optimized patch spe |bzip2-9 |33.67%||22.9MB/s|||66MB/s| |zlib-9 |36.53%||19.8MB/s|||539MB/s| |lzma2-9-16m |25.85%||5.3MB/s|||215MB/s| -|zstd-21-24 |27.21%||4.2MB/s|||976MB/s| +|zstd-21-24|27.17%||4.0MB/s|||935MB/s| || -|zstd --patch-from|7.96%|2798M|3.3MB/s|629M|2303M|828MB/s| -|xdelta3|13.60%|409M|6.9MB/s|86M|102M|159MB/s| -|xdelta3 +hpatchz|13.60%|409M|6.9MB/s|70M|82M|377MB/s| -|xdelta3 -B|9.63%|2282M|10.9MB/s|460M|2070M|267MB/s| -|xdelta3 -B +hpatchz|9.63%|2282M|10.9MB/s|315M|1100M|477MB/s| -|hdiffz sw p1 -VCD|9.22%|329M|15.9MB/s|31M|33M|519MB/s| -|hdiffz sw p8 -VCD|9.22%|506M|48.2MB/s|31M|33M|515MB/s| -|bsdiff|8.17%|2773M|2.5MB/s|637M|2312M|167MB/s| -|bsdiff +hpatchz -m|8.17%|2773M|2.5MB/s|321M|1101M|197MB/s| -|hdiffz p1 -BSD|7.72%|1210M|13.4MB/s|14M|14M|172MB/s| -|hdiffz p8 -BSD|7.72%|1191M|31.2MB/s|14M|14M|172MB/s| +|zstd --patch-from|7.57%|2730M|5.5MB/s|629M|2306M|1462MB/s| +|xdelta3|13.60%|409M|6.7MB/s|85M|102M|154MB/s| +|xdelta3 +hpatchz|13.60%|409M|6.7MB/s|74M|88M|372MB/s| +|xdelta3 -B|9.63%|2282M|10.5MB/s|460M|2071M|256MB/s| +|xdelta3 -B +hpatchz|9.63%|2282M|10.5MB/s|320M|1106M|467MB/s| +|hdiffz sw p1 -VCD|9.22%|329M|15.9MB/s|34M|36M|526MB/s| +|hdiffz sw p8 -VCD|9.22%|505M|52.0MB/s|32M|36M|522MB/s| +|bsdiff|8.17%|2773M|2.5MB/s|637M|2313M|146MB/s| +|bsdiff +hpatchz -m|8.17%|2773M|2.5MB/s|327M|1107M|188MB/s| +|bsdiff +hpatchz -s|8.17%|2773M|2.5MB/s|19M|19M|84MB/s| +|hdiffz p1 -BSD|7.74%|676M|14.3MB/s|19M|19M|164MB/s| +|hdiffz p8 -BSD|7.73%|662M|33.8MB/s|19M|19M|164MB/s| || |hsynz p1 zlib|20.05%|6M|17.3MB/s|6M|22M|273MB/s| |hsynz p8 zlib|20.05%|30M|115.1MB/s|13M|29M|435MB/s| |hsynz p1 zstd|14.96%|532M|1.9MB/s|24M|34M|264MB/s| |hsynz p8 zstd|14.95%|3349M|10.1MB/s|24M|34M|410MB/s| || -|hdiffz p1 zlib|7.79%|1214M|14.4MB/s|4M|4M|564MB/s| -|hdiffz p8 zlib|7.79%|1190M|44.8MB/s|4M|4M|559MB/s| -|hdiffz p1 lzma2|6.44%|1209M|11.4MB/s|16M|20M|431MB/s| -|hdiffz p8 lzma2|6.44%|1191M|33.4MB/s|16M|20M|428MB/s| -|hdiffz p1 zstd|6.74%|1211M|11.5MB/s|16M|21M|592MB/s| -|hdiffz p8 zstd|6.74%|1531M|24.3MB/s|16M|21M|586MB/s| -|hdiffz w p8 lzma2|6.49%|666M|24.3MB/s|20M|25M|730MB/s| -|hdiffz w p8 zstd|6.78%|966M|19.2MB/s|20M|26M|1253MB/s| -|hdiffz WD p1 lzma2|6.52%|679M|7.9MB/s|22M|27M|749MB/s| -|hdiffz WD p8 lzma2|6.52%|666M|24.8MB/s|22M|27M|1020MB/s| -|hdiffz WD p1 zstd|6.82%|678M|7.9MB/s|22M|28M|1548MB/s| -|hdiffz WD p8 zstd|6.82%|971M|19.2MB/s|22M|28M|2527MB/s| +|hdiffz p1 zlib|7.81%|676M|15.3MB/s|8M|9M|674MB/s| +|hdiffz p8 zlib|7.80%|663M|50.5MB/s|8M|9M|727MB/s| +|hdiffz p1 lzma2|6.45%|674M|12.0MB/s|20M|25M|480MB/s| +|hdiffz p8 lzma2|6.45%|666M|36.2MB/s|21M|25M|525MB/s| +|hdiffz p1 zstd|6.74%|682M|12.0MB/s|20M|26M|716MB/s| +|hdiffz p8 zstd|6.74%|1117M|25.3MB/s|20M|26M|752MB/s| +|hdiffz w p8 lzma2|6.49%|666M|26.5MB/s|20M|25M|761MB/s| +|hdiffz w p8 zstd|6.78%|965M|20.4MB/s|20M|26M|1326MB/s| +|hdiffz WD p1 lzma2|6.52%|674M|8.0MB/s|22M|27M|758MB/s| +|hdiffz WD p8 lzma2|6.52%|665M|26.9MB/s|24M|29M|1027MB/s| +|hdiffz WD p1 zstd|6.82%|682M|8.0MB/s|22M|28M|1611MB/s| +|hdiffz WD p8 zstd|6.82%|970M|20.6MB/s|24M|30M|2529MB/s| || -|hdiffz s p1 zlib|12.52%|91M|46.4MB/s|3M|4M|611MB/s| -|hdiffz s p8 zlib|12.53%|95M|178.9MB/s|3M|4M|609MB/s| -|hdiffz s p1 lzma2|9.11%|170M|18.1MB/s|17M|20M|402MB/s| -|hdiffz s p8 lzma2|9.13%|370M|50.6MB/s|17M|20M|400MB/s| -|hdiffz s p1 zstd|9.60%|195M|18.0MB/s|17M|21M|677MB/s| -|hdiffz s p8 zstd|9.60%|976M|28.5MB/s|17M|21M|678MB/s| -|hdiffz sw p8 lzma2|6.76%|253M|33.7MB/s|20M|25M|584MB/s| -|hdiffz sw p8 zstd|7.07%|851M|24.9MB/s|20M|26M|873MB/s| -|hdiffz sWD p1 lzma2|6.80%|177M|13.0MB/s|22M|27M|710MB/s| -|hdiffz sWD p8 lzma2|6.80%|269M|39.6MB/s|22M|27M|988MB/s| -|hdiffz sWD p1 zstd|7.12%|211M|13.2MB/s|21M|28M|1449MB/s| -|hdiffz sWD p8 zstd|7.12%|869M|27.9MB/s|21M|28M|2326MB/s| +|hdiffz s p1 zlib|12.52%|80M|45.2MB/s|8M|9M|831MB/s| +|hdiffz s p8 zlib|12.52%|85M|184.1MB/s|8M|9M|828MB/s| +|hdiffz s p1 lzma2|9.11%|169M|17.8MB/s|22M|25M|474MB/s| +|hdiffz s p8 lzma2|9.13%|375M|50.1MB/s|22M|25M|474MB/s| +|hdiffz s p1 zstd|9.58%|195M|17.5MB/s|21M|26M|979MB/s| +|hdiffz s p8 zstd|9.58%|980M|27.4MB/s|21M|26M|969MB/s| +|hdiffz sw p8 lzma2|6.76%|252M|36.1MB/s|20M|25M|609MB/s| +|hdiffz sw p8 zstd|7.07%|851M|26.2MB/s|20M|26M|921MB/s| +|hdiffz sWD p1 lzma2|6.80%|177M|13.0MB/s|22M|27M|721MB/s| +|hdiffz sWD p8 lzma2|6.80%|269M|43.2MB/s|23M|29M|987MB/s| +|hdiffz sWD p1 zstd|7.12%|211M|13.2MB/s|21M|28M|1497MB/s| +|hdiffz sWD p8 zstd|7.12%|870M|29.8MB/s|23M|30M|2440MB/s| ## input Apk Files for test: @@ -537,8 +546,7 @@ case list: **changed test Program**: -**hdiffz ...** `-m-6 -SD` changed to `-m-1 -SD-2m -cache`, `-s-64 -SD` changed to `-s-16 -SD-2m` -**hdiffz ...** lzma2 dict size `16m` changed to `8m`, zstd dict bit `24` changed to `23` +**hdiffz ...** `-m-6` changed to `-m-2 -cache`, `-s-64` changed to `-s-16` **hsynz ...** make `-s-2k` changed to `-s-1k` & adding **hsynz p1**, **hsynz p8** make without compressor **archive-patcher** v1.0, diff with `--generate --old {old} --new {new} --patch {pat}`, @@ -548,25 +556,23 @@ case list: & **sfpatcher -2 lzma2** diff with `-o-2 -c-lzma2-9-4m -m-1 -step-2m -lp-8m -p-8 -cache -d {old} {new} {pat}` sfpatcher patch with `-lp -p-8 {old} {pat} {new}` **sfpatcher -1 clA zstd** v1.3.0 used `$sf_normalize -cl-A` normalized apks before diff -adding test hpatchz&sfpatcher on Android, arm CPU Kirin980(2×A76 2.6G + 2×A76 1.92G + 4×A55 1.8G) -( [archive-patcher], [sfpatcher] optimized diff&patch between apk files ) - -update 2026-06-25: adding test HDiffPatch v5.0.0 for WinDiff(optimized patch speed) -`w` mean diff with `-w-2m`, `WD` mean diff with `-WD -w-2m` +adding test hpatchz v4.6.9 & sfpatcher on Android, arm CPU Kirin980(2×A76 2.6G + 2×A76 1.92G + 4×A55 1.8G) +( [archive-patcher], [sfpatcher] optimized diff&patch between apk files ) **test result average**: |Program|compress|diff mem|speed|patch mem|max mem|speed|arm Kirin980| |:----|----:|----:|----:|----:|----:|----:|----:| -|zstd --patch-from|53.18%|2199M|3.6MB/s|209M|596M|609MB/s| -|xdelta3|54.51%|422M|3.8MB/s|98M|99M|170MB/s| -|xdelta3 +hpatchz|54.51%|422M|3.8MB/s|70M|81M|438MB/s| -|hdiffz sw p1 -VCD|53.73%|288M|9.0MB/s|33M|33M|317MB/s| -|hdiffz sw p8 -VCD|53.73%|459M|26.2MB/s|33M|33M|318MB/s| -|bsdiff|53.84%|931M|1.2MB/s|218M|605M|54MB/s| -|bsdiff +hpatchz -m|53.84%|931M|1.2MB/s|116M|310M|57MB/s| -|bsdiff +hpatchz -s|53.84%|931M|1.2MB/s|14M|14M|54MB/s| -|hdiffz p1 -BSD|53.69%|509M|6.8MB/s|14M|14M|55MB/s| -|hdiffz p8 -BSD|53.70%|514M|15.3MB/s|14M|14M|55MB/s| +|zstd --patch-from|53.15%|2251M|3.2MB/s|204M|599M|1266MB/s| +|xdelta3|54.51%|422M|3.8MB/s|97M|100M|162MB/s| +|xdelta3 +hpatchz|54.51%|422M|3.8MB/s|76M|87M|417MB/s| +|hdiffz sw p1 -VCD|53.73%|288M|9.6MB/s|36M|36M|325MB/s| +|hdiffz sw p8 -VCD|53.73%|459M|27.8MB/s|36M|36M|323MB/s| +|bsdiff|53.84%|931M|1.2MB/s|218M|605M|52MB/s| +|bsdiff +hpatchz -m|53.84%|931M|1.2MB/s|123M|316M|54MB/s| +|bsdiff +hpatchz -s|53.84%|931M|1.2MB/s|19M|19M|51MB/s| +|hdiffz p1 -BSD|53.70%|412M|7.2MB/s|19M|19M|53MB/s| +|hdiffz p8 -BSD|53.72%|416M|15.5MB/s|19M|19M|53MB/s| +|| |hsynz p1|62.43%|4M|1533.5MB/s|4M|10M|236MB/s| |hsynz p8|62.43%|18M|2336.4MB/s|12M|18M|394MB/s| |hsynz p1 zlib|58.67%|5M|22.7MB/s|4M|11M|243MB/s| @@ -574,32 +580,31 @@ update 2026-06-25: adding test HDiffPatch v5.0.0 for WinDiff(optimized patch spe |hsynz p1 zstd|57.74%|534M|2.7MB/s|24M|28M|234MB/s| |hsynz p8 zstd|57.74%|3434M|13.4MB/s|24M|28M|390MB/s| || -|hdiffz p1|54.40%|509M|8.8MB/s|5M|6M|682MB/s| -|hdiffz p8|54.41%|514M|32.4MB/s|5M|6M|686MB/s|443MB/s| -|hdiffz p1 zlib|53.21%|509M|8.2MB/s|5M|6M|514MB/s| -|hdiffz p8 zlib|53.22%|514M|31.1MB/s|5M|6M|512MB/s|343MB/s| -|hdiffz p1 lzma2|52.93%|525M|4.1MB/s|21M|22M|260MB/s| -|hdiffz p8 lzma2|52.94%|557M|18.9MB/s|21M|22M|261MB/s|131MB/s| -|hdiffz p1 zstd|53.04%|537M|5.4MB/s|21M|22M|598MB/s| -|hdiffz p8 zstd|53.05%|1251M|11.1MB/s|21M|22M|604MB/s|371MB/s| -|hdiffz w p8 lzma2|53.25%|389M|8.0MB/s|25M|25M|322MB/s| -|hdiffz w p8 zstd|53.36%|1042M|6.3MB/s|24M|26M|1098MB/s| -|hdiffz WD p1 lzma2|53.27%|374M|1.7MB/s|27M|27M|303MB/s| -|hdiffz WD p8 lzma2|53.27%|390M|8.0MB/s|27M|27M|350MB/s| -|hdiffz WD p1 zstd|53.38%|384M|1.9MB/s|25M|28M|1171MB/s| -|hdiffz WD p8 zstd|53.38%|1045M|6.2MB/s|20M|28M|1768MB/s| -|hdiffz s p1 zlib|53.73%|118M|26.8MB/s|4M|6M|513MB/s| -|hdiffz s p8 zlib|53.73%|122M|97.3MB/s|4M|6M|513MB/s| -|hdiffz s p1 lzma2|53.30%|197M|6.4MB/s|20M|22M|258MB/s| -|hdiffz s p8 lzma2|53.30%|309M|32.4MB/s|20M|22M|258MB/s| -|hdiffz s p1 zstd|53.44%|221M|10.1MB/s|20M|22M|620MB/s| -|hdiffz s p8 zstd|53.44%|1048M|14.4MB/s|20M|22M|613MB/s| -|hdiffz sw p8 lzma2|53.27%|299M|19.3MB/s|25M|25M|319MB/s| -|hdiffz sw p8 zstd|53.38%|1042M|11.3MB/s|25M|26M|1068MB/s| -|hdiffz sWD p1 lzma2|53.29%|196M|4.6MB/s|27M|27M|306MB/s| -|hdiffz sWD p8 lzma2|53.29%|303M|19.8MB/s|27M|27M|350MB/s| -|hdiffz sWD p1 zstd|53.41%|222M|6.3MB/s|25M|28M|1179MB/s| -|hdiffz sWD p8 zstd|53.41%|1045M|11.5MB/s|20M|28M|1770MB/s| +|hdiffz p1 zlib|53.22%|412M|8.8MB/s|10M|11M|827MB/s|343MB/s| +|hdiffz p8 zlib|53.23%|415M|32.6MB/s|10M|11M|916MB/s| +|hdiffz p1 lzma2|52.92%|429M|4.3MB/s|26M|27M|310MB/s|131MB/s| +|hdiffz p8 lzma2|52.94%|464M|19.4MB/s|26M|27M|327MB/s| +|hdiffz p1 zstd|53.04%|442M|5.7MB/s|25M|27M|1072MB/s|371MB/s| +|hdiffz p8 zstd|53.05%|1164M|11.2MB/s|25M|28M|1104MB/s| +|hdiffz w p8 lzma2|53.24%|426M|14.4MB/s|26M|27M|322MB/s| +|hdiffz w p8 zstd|53.35%|1044M|9.3MB/s|24M|28M|1135MB/s| +|hdiffz WD p1 lzma2|53.27%|417M|3.2MB/s|27M|27M|312MB/s| +|hdiffz WD p8 lzma2|53.27%|426M|14.6MB/s|29M|29M|353MB/s| +|hdiffz WD p1 zstd|53.38%|425M|3.9MB/s|25M|28M|1266MB/s| +|hdiffz WD p8 zstd|53.38%|1045M|9.4MB/s|22M|30M|1877MB/s| +|| +|hdiffz s p1 zlib|53.73%|100M|27.0MB/s|9M|11M|780MB/s| +|hdiffz s p8 zlib|53.73%|104M|97.1MB/s|9M|11M|885MB/s| +|hdiffz s p1 lzma2|53.30%|193M|6.5MB/s|25M|27M|296MB/s| +|hdiffz s p8 lzma2|53.30%|312M|32.4MB/s|25M|27M|317MB/s| +|hdiffz s p1 zstd|53.44%|218M|10.3MB/s|24M|27M|1021MB/s| +|hdiffz s p8 zstd|53.44%|1049M|14.3MB/s|23M|28M|1091MB/s| +|hdiffz sw p8 lzma2|53.26%|302M|22.4MB/s|26M|27M|322MB/s| +|hdiffz sw p8 zstd|53.37%|1044M|12.1MB/s|25M|28M|1086MB/s| +|hdiffz sWD p1 lzma2|53.29%|196M|4.7MB/s|27M|27M|315MB/s| +|hdiffz sWD p8 lzma2|53.29%|303M|23.1MB/s|29M|29M|352MB/s| +|hdiffz sWD p1 zstd|53.41%|222M|6.5MB/s|25M|28M|1281MB/s| +|hdiffz sWD p8 zstd|53.41%|1045M|12.2MB/s|21M|30M|1874MB/s| || |archive-patcher|31.65%|1448M|0.9MB/s|558M|587M|14MB/s| |sfpatcher-1 p1 zstd|31.08%|818M|2.3MB/s|15M|19M|201MB/s|92MB/s| diff --git a/README_cn.md b/README_cn.md index 0f6bc9a5..000196ee 100644 --- a/README_cn.md +++ b/README_cn.md @@ -8,7 +8,7 @@ [![Build status](https://ci.appveyor.com/api/projects/status/t9ow8dft8lt898cv/branch/master?svg=true)](https://ci.appveyor.com/project/sisong/hdiffpatch/branch/master) 中文版 | [english](README.md) -[HDiffPatch] 是一个C\C++库和命令行工具,用于在二进制文件或文件夹之间执行 **diff**(创建补丁) 和 **patch**(打补丁);跨平台、运行速度快、创建的补丁小、支持巨大的文件并且diff和patch时都可以控制内存占用量。 +[HDiffPatch] 是一个C\C++库和命令行工具,用于在二进制文件或目录(文件夹)之间执行 **diff**(创建补丁) 和 **patch**(打补丁);跨平台、运行速度快、创建的补丁小、支持巨大的文件并且diff和patch时都可以控制内存占用量。 [HDiffPatch] 定义了自己的补丁包格式,同时这个库也完全兼容了 [bsdiff4] 和 [endsley/bsdiff] 的补丁包格式,并[兼容](https://github.com/sisong/HDiffPatch/issues/369#issuecomment-1869798843)了 [open-vcdiff] 和 [xdelta3] 的补丁包格式 [VCDIFF(RFC 3284)]。 @@ -55,6 +55,11 @@ hsynz 支持 zstd 压缩算法并且比 zsync 速度快得多;而且可以兼 ## 自己编译 ``` +git clone --recurse-submodules https://github.com/sisong/HDiffPatch5.git +cd +``` +或者 +``` cd git clone https://github.com/sisong/HDiffPatch.git HDiffPatch git clone https://github.com/sisong/libmd5.git libmd5 @@ -119,13 +124,10 @@ make -j 给较慢的匹配开启一个大型缓冲区,来加快匹配速度(不影响补丁大小), 默认不开启; 如果新版本和旧版本不相同数据比较多,那diff速度就会比较快; 该大型缓冲区最大占用O(旧版本文件大小)的内存, 并且需要较多的时间来创建(从而可能降低diff速度)。 - -SD[-stepSize] - 创建单压缩流的补丁文件(HDIFFSF20格式), 这样patch时就只需要一个解压缩缓冲区, 并且可以 - 支持边下载边patch, 并支持多线程patch; 压缩步长stepSize>=(1024*4), 默认为256k, 推荐64k,2m等。 -w[-oldWinSize-segSize] 窗口模式diff, 优化patch时old data的读取访问; - 在 -m 模式下, 补丁文件会稍大, 在 -s 模式下, 补丁文件更小但patch速度稍慢; - 如果增大oldWinSize或减小segSize, 补丁文件会更小, 但diff和patch速度会变慢。 + 在 -m 模式下配合使用, 补丁文件会稍变大, 在 -s 模式下, 补丁文件很可能更小; + 如果增大oldWinSize或减小segSize, 补丁文件会更小, 但diff和patch速度可能会变慢。 oldWinSize: old data上最大的窗口字节数, 默认 -w-2m; 对大文件, 推荐 -w-4m-128k, -w-16m-256k 等。 segSize: 窗口匹配的初始数据粒度, 默认为 oldWinSize/64; @@ -137,6 +139,9 @@ make -j 默认压缩算法为zstd, 可以通过-c-no关闭压缩; 默认checksum为xxh128, 可以通过-C-no关闭checksum; stepSize>=(1024*4), 默认 -WD-256k, 推荐128k,512k等。 + -SD[-stepSize] + 创建单压缩流的补丁文件(HDIFFSF20格式), 这样patch时就只需要一个解压缩缓冲区, 并且可以 + 支持边下载边patch, 并支持多线程patch; 压缩步长stepSize>=(1024*4), 默认为256k, 推荐64k,2m等。 -BSD 创建一个和bsdiff4兼容的补丁, 不支持参数为文件夹。 也支持和-SD选项一起运行(不使用其stepSize), 从而创建单压缩流的补丁文件, @@ -185,7 +190,7 @@ make -j 压缩字典比特数dictBits 可以为10到30, 默认为23。 支持多线程并行压缩,较快(但内存占用会比较大)。 -C-checksumType - 为文件夹间diff设置数据校验算法, 默认为fadler64; + 设置数据校验算法, 文件夹间diff时默认为fadler64; 而窗口diff时默认为xxh128; 支持的校验选项: -C-no 不校验 -C-crc32 @@ -216,7 +221,7 @@ make -j 设置oldPath的清单文件oldManifestFile; 如果没有oldPath,那就不需要设置-M-old; -M-new#newManifestFile 设置newPath的清单文件newManifestFile; - -D 强制执行文件夹间的diff, 即使输入的是2个文件; 从而为文件间的补丁添加校验功能。 + -D 强制执行文件夹间的diff, 即使输入的是2个文件; 默认情况下oldPath或newPath有一个是文件夹时才会执行文件夹间的diff。 -neq 打开检查: 如果newPath和oldPath的数据都相同,则返回错误; @@ -248,23 +253,29 @@ make -j oldPath可以为空, 输入参数为 "" 选项: -s[-cacheSize] - 默认选项,并且默认设置为-s-8m; oldPath所有文件被当作文件流来加载; + 默认推荐选项,并且默认设置为-s-8m; oldPath所有文件被当作文件流来加载; cacheSize可以设置为262144 或 256k, 64m, 512m 等 - 需要的内存大小: (cacheSize + 4*解压缩缓冲区)+O(1) - 而如果diffFile是单压缩流的补丁文件(用hdiffz -SD-stepSize所创建) + 如果diffFile是窗口补丁文件(用hdiffz -WD-stepSize -w-oldWinSize所创建), + 那需要的内存大小: (cacheSize+ oldWinSize+stepSize + 1*解压缩缓冲区)+O(1); + 如果diffFile是单压缩流的补丁文件(用hdiffz -SD-stepSize所创建), 那需要的内存大小: (cacheSize+ stepSize + 1*解压缩缓冲区)+O(1); - 如果diffFile是用hdiffz -BSD、bsdiff4、hdiffz -VCD、xdelta3、open-vcdiff所创建 - 那需要的内存大小: (cacheSize + 3*解压缩缓冲区); - 如果diffFile是VCDIFF格式补丁文件: 如果是用hdiffz -VCD创建,那推荐用-s模式; - 如果是xdelta、open-vcdiff所创建,那推荐用-m模式。 - -m oldPath所有文件数据被加载到内存中; - 需要的内存大小: (oldFileSize + 4*解压缩缓冲区)+O(1) - 而如果diffFile是单压缩流的补丁文件(用hdiffz -SD-stepSize所创建) + 如果diffFile是用hdiffz默认压缩格式所创建, + 那需要的内存大小: (cacheSize + 4*解压缩缓冲区)+O(1); + 如果diffFile是用hdiffz -BSD、bsdiff4、hdiffz -VCD所创建, + 那需要的内存大小: (cacheSize + 3*解压缩缓冲区)+O(1); + 如果diffFile是用hdiffz -VCD -w,xdelta3,open-vcdiff所创建, + 那需要的内存大小: (cacheSize + 源窗口大小+目标窗口大小 + 3*解压缩缓冲区)+O(1)。 + -m 需要时oldPath所有文件数据被加载到内存中; + 如果diffFile是窗口补丁文件(用hdiffz -WD-stepSize -w-oldWinSize所创建), + 那需要的内存大小: (oldWinSize + stepSize + 1*解压缩缓冲区)+O(1); + 如果diffFile是单压缩流的补丁文件(用hdiffz -SD-stepSize所创建), 那需要的内存大小: (oldFileSize+ stepSize + 1*解压缩缓冲区)+O(1); - 如果diffFile是用hdiffz -BSD、bsdiff4所创建 + 如果diffFile是用hdiffz默认压缩格式所创建, + 那需要的内存大小: (oldFileSize + 4*解压缩缓冲区)+O(1); + 如果diffFile是用hdiffz -BSD、bsdiff4所创建, 那需要的内存大小: (oldFileSize + 3*解压缩缓冲区); - 如果diffFile是VCDIFF格式补丁文件(用hdiffz -VCD、xdelta3、open-vcdiff所创建) - 那需要的内存大小: (源窗口大小+目标窗口大小 + 3*解压缩缓冲区); + 如果diffFile是VCDIFF格式补丁文件(用hdiffz -VCD、hdiffz -VCD -w、xdelta3、open-vcdiff所创建), + 那需要的内存大小: (源窗口大小+目标窗口大小 + 3*解压缩缓冲区)+O(1)。 -p-parallelThreadNumber 设置线程数 parallelThreadNumber>1 时,开启多线程并行模式; 当前支持单压缩流补丁文件(用hdiffz -SD-stepSize创建)和window diff格式补丁文件(用hdiffz -WD所创建); @@ -318,7 +329,7 @@ make -j * **patch_decompress()** * **patch_decompress_with_cache()** * **patch_decompress_mem()** -### v3 API, 在文件夹间 **diff**&**patch**: +### v3 API, 在文件夹间 **diff**&**patch** (HDIFF19): * **dir_diff()** * **TDirPatcher_\*()** functions with **struct TDirPatcher** ### v4 API, 单压缩流补丁包 (HDIFFSF20): @@ -351,13 +362,10 @@ make -j #### hsynz API, 同步 diff&patch (例子 [hsynz]): * **create_sync_data()** * **create_dir_sync_data()** -* **sync_patch()** -* **sync_patch_...()** -* **sync_local_diff()** -* **sync_local_diff_...()** -* **sync_local_patch()** -* **sync_local_patch_...()** -* **create_hdiff_by_sign()** (patched by patch_single_stream()...) +* **sync_patch...()** +* **sync_local_diff...()** +* **sync_local_patch...()** +* **create_hdiff_by_sign()** (应用补丁时用 patch_single_stream(), 场景类似[rsync]) #### [zsync] 兼容包装 API, (例子 [hsynz]): * **create_zsync_data()** * **zsync_patch...()** @@ -392,19 +400,20 @@ make -j **测试 PC**: Windows11, CPU R9-7945HX, SSD PCIe4.0x4 4T, DDR5 5200MHz 32Gx2 -**参与测试的程序和版本**: HDiffPatch4.6.3, hsynz 1.1.0, BsDiff4.3, xdelta3.1, zstd1.5.2 +**参与测试的程序和版本**: HDiffPatch5.0.1, hsynz1.1.0, BsDiff4.3, xdelta3.1, zstd1.5.7 **参与测试的程序的参数**: **zstd --patch-from** diff with `--ultra -21 --long=24 -f --patch-from={old} {new} -o {pat}` zstd patch with `-d -f --memory=2047MB --patch-from={old} {pat} -o {new}` **xdelta3** diff with `-S lzma -e -9 -n -f -s {old} {new} {pat}` -**xdelta3** patch with `-d -f -s {old} {pat} {new}` -& adding **hpatchz** test: `hpatchz -m -f {old} {xdelta3-pat} {new}` + xdelta3 patch with `-n -d -f -s {old} {pat} {new}` + & adding **hpatchz** test: `hpatchz -f {old} {xdelta3-pat} {new}` **xdelta3 -B** diff with `-S lzma -B {oldSize} -e -9 -n -f -s {old} {new} {pat}` -**xdelta3 -B** patch with `-B {oldSize} -d -f -s {old} {pat} {new}` -& adding **hpatchz** test: `hpatchz -m -f {old} {xdelta3-B-pat} {new}` +xdelta3 -B patch with `-B {oldSize} -d -f -s {old} {pat} {new}` + & adding **hpatchz** test: `hpatchz -f {old} {xdelta3-B-pat} {new}` **bsdiff** diff with `{old} {new} {pat}` -**bspatch** patch with `{old} {new} {pat}` -& adding **hpatchz** test: `hpatchz -m -f {old} {bsdiff-pat} {new}` + bspatch patch with `{old} {new} {pat}` + & adding **hpatchz** test: `hpatchz -m -f {old} {bsdiff-pat} {new}` + & adding **hpatchz** test: `hpatchz -s -f {old} {bsdiff-pat} {new}` **hdiffz -BSD** diff with `-m-6 -BSD -d -f -p-1 {old} {new} {pat}` **hdiffz zlib** diff with `-m-6 -SD -d -f -p-1 -c-zlib-9 {old} {new} {pat}` **hdiffz lzma2** diff with `-m-6 -SD -d -f -p-1 -c-lzma2-9-16m {old} {new} {pat}` @@ -412,19 +421,19 @@ make -j **hdiffz s zlib** diff with `-s-64 -SD -d -f -p-1 -c-zlib-9 {old} {new} {pat}` **hdiffz s lzma2** diff with `-s-64 -SD -d -f -p-1 -c-lzma2-9-16m {old} {new} {pat}` **hdiffz s zstd** diff with `-s-64 -SD -d -f -p-1 -c-zstd-21-24 {old} {new} {pat}` -& adding all **hdiffz** test with -p-8 -**hpatchz** patch with `-s-3m -f {old} {pat} {new}` + & adding all **hdiffz** test with -p-8 + hpatchz patch with `-f {old} {pat} {new}` **hsynz** test, make sync info by `hsync_make -s-2k {new} {out_newi} {out_newz}`, -client sync diff&patch by `hsync_demo {old} {newi} {newz} {out_new} -p-1` + client sync diff&patch by `hsync_demo {old} {newi} {newz} {out_new} -p-1` **hsynz p1 zlib** run hsync_make with `-p-1 -c-zlib-9` **hsynz p8 zlib** run hsync_make with `-p-8 -c-zlib-9` (run `hsync_demo` with `-p-8`) **hsynz p1 zstd** run hsync_make with `-p-1 -c-zstd-21-24` **hsynz p8 zstd** run hsync_make with `-p-8 -c-zstd-21-24` (run `hsync_demo` with `-p-8`) -2026-06-25 更新: 为 HDiffPatch v5.0.0 的 WinDiff(优化了补丁速度) 添加相关测试 -`w` mean diff with `-w-2m`, `WD` mean diff with `-WD -w-2m` -**hdiffz w p1 -VCD** diff with `-s-64 -w-2m -VCD-9-8m -d -f -p-1 {old} {new} {pat}` -**hdiffz w p8 -VCD** diff with `-s-64 -w-2m -VCD-9-8m -d -f -p-1 {old} {new} {pat}` +添加 Window Diff(优化了补丁速度) 相关测试 +`s` mean diff with `-s-64`, `w` mean diff with `-w-2m`, `WD` mean diff with `-WD -w-2m` +**hdiffz sw p1 -VCD** diff with `-s-64 -w-2m -VCD-9-8m -d -f -p-1 {old} {new} {pat}` +**hdiffz sw p8 -VCD** diff with `-s-64 -w-2m -VCD-9-8m -d -f -p-8 {old} {new} {pat}` **hdiffz w p8 lzma2** diff with `-m-6 -SD -w-2m -d -f -p-8 -c-lzma2-9-16m {old} {new} {pat}` **hdiffz w p8 zstd** diff with `-m-6 -SD -w-2m -d -f -p-8 -c-zstd-21-24 {old} {new} {pat}` **hdiffz sw p8 lzma2** diff with `-s-64 -SD -w-2m -d -f -p-8 -c-lzma2-9-16m {old} {new} {pat}` @@ -437,8 +446,8 @@ client sync diff&patch by `hsync_demo {old} {newi} {newz} {out_new} -p-1` **hdiffz sWD p8 lzma2** diff with `-s-64 -WD -w-2m -d -f -p-8 -c-lzma2-9-16m {old} {new} {pat}` **hdiffz sWD p1 zstd** diff with `-s-64 -WD -w-2m -d -f -p-1 -c-zstd-21-24 {old} {new} {pat}` **hdiffz sWD p8 zstd** diff with `-s-64 -WD -w-2m -d -f -p-8 -c-zstd-21-24 {old} {new} {pat}` - & **hpatchz** patch with `-s-8m -C-no -p-1 -f {old} {pat} {new}` when diff with `-WD -p-1` - & **hpatchz** patch with `-s-8m -C-no -p-5 -f {old} {pat} {new}` when diff with `-WD -p-8` + & hpatchz patch with `-C-no -p-1 -f {old} {pat} {new}` when diff with `-WD -p-1` + & hpatchz patch with `-C-no -p-5 -f {old} {pat} {new}` when diff with `-WD -p-8` or `-SD -w-2m -p-8` **测试结果取平均**: |程序|包大小|diff内存|速度|patch内存|最大内存|速度| @@ -446,50 +455,51 @@ client sync diff&patch by `hsync_demo {old} {newi} {newz} {out_new} -p-1` |bzip2-9 |33.67%||22.9MB/s|||66MB/s| |zlib-9 |36.53%||19.8MB/s|||539MB/s| |lzma2-9-16m |25.85%||5.3MB/s|||215MB/s| -|zstd-21-24 |27.21%||4.2MB/s|||976MB/s| +|zstd-21-24|27.17%||4.0MB/s|||935MB/s| || -|zstd --patch-from|7.96%|2798M|3.3MB/s|629M|2303M|828MB/s| -|xdelta3|13.60%|409M|6.9MB/s|86M|102M|159MB/s| -|xdelta3 +hpatchz|13.60%|409M|6.9MB/s|70M|82M|377MB/s| -|xdelta3 -B|9.63%|2282M|10.9MB/s|460M|2070M|267MB/s| -|xdelta3 -B +hpatchz|9.63%|2282M|10.9MB/s|315M|1100M|477MB/s| -|hdiffz sw p1 -VCD|9.22%|329M|15.9MB/s|31M|33M|519MB/s| -|hdiffz sw p8 -VCD|9.22%|506M|48.2MB/s|31M|33M|515MB/s| -|bsdiff|8.17%|2773M|2.5MB/s|637M|2312M|167MB/s| -|bsdiff +hpatchz -m|8.17%|2773M|2.5MB/s|321M|1101M|197MB/s| -|hdiffz p1 -BSD|7.72%|1210M|13.4MB/s|14M|14M|172MB/s| -|hdiffz p8 -BSD|7.72%|1191M|31.2MB/s|14M|14M|172MB/s| +|zstd --patch-from|7.57%|2730M|5.5MB/s|629M|2306M|1462MB/s| +|xdelta3|13.60%|409M|6.7MB/s|85M|102M|154MB/s| +|xdelta3 +hpatchz|13.60%|409M|6.7MB/s|74M|88M|372MB/s| +|xdelta3 -B|9.63%|2282M|10.5MB/s|460M|2071M|256MB/s| +|xdelta3 -B +hpatchz|9.63%|2282M|10.5MB/s|320M|1106M|467MB/s| +|hdiffz sw p1 -VCD|9.22%|329M|15.9MB/s|34M|36M|526MB/s| +|hdiffz sw p8 -VCD|9.22%|505M|52.0MB/s|32M|36M|522MB/s| +|bsdiff|8.17%|2773M|2.5MB/s|637M|2313M|146MB/s| +|bsdiff +hpatchz -m|8.17%|2773M|2.5MB/s|327M|1107M|188MB/s| +|bsdiff +hpatchz -s|8.17%|2773M|2.5MB/s|19M|19M|84MB/s| +|hdiffz p1 -BSD|7.74%|676M|14.3MB/s|19M|19M|164MB/s| +|hdiffz p8 -BSD|7.73%|662M|33.8MB/s|19M|19M|164MB/s| || |hsynz p1 zlib|20.05%|6M|17.3MB/s|6M|22M|273MB/s| |hsynz p8 zlib|20.05%|30M|115.1MB/s|13M|29M|435MB/s| |hsynz p1 zstd|14.96%|532M|1.9MB/s|24M|34M|264MB/s| |hsynz p8 zstd|14.95%|3349M|10.1MB/s|24M|34M|410MB/s| || -|hdiffz p1 zlib|7.79%|1214M|14.4MB/s|4M|4M|564MB/s| -|hdiffz p8 zlib|7.79%|1190M|44.8MB/s|4M|4M|559MB/s| -|hdiffz p1 lzma2|6.44%|1209M|11.4MB/s|16M|20M|431MB/s| -|hdiffz p8 lzma2|6.44%|1191M|33.4MB/s|16M|20M|428MB/s| -|hdiffz p1 zstd|6.74%|1211M|11.5MB/s|16M|21M|592MB/s| -|hdiffz p8 zstd|6.74%|1531M|24.3MB/s|16M|21M|586MB/s| -|hdiffz w p8 lzma2|6.49%|666M|24.3MB/s|20M|25M|730MB/s| -|hdiffz w p8 zstd|6.78%|966M|19.2MB/s|20M|26M|1253MB/s| -|hdiffz WD p1 lzma2|6.52%|679M|7.9MB/s|22M|27M|749MB/s| -|hdiffz WD p8 lzma2|6.52%|666M|24.8MB/s|22M|27M|1020MB/s| -|hdiffz WD p1 zstd|6.82%|678M|7.9MB/s|22M|28M|1548MB/s| -|hdiffz WD p8 zstd|6.82%|971M|19.2MB/s|22M|28M|2527MB/s| +|hdiffz p1 zlib|7.81%|676M|15.3MB/s|8M|9M|674MB/s| +|hdiffz p8 zlib|7.80%|663M|50.5MB/s|8M|9M|727MB/s| +|hdiffz p1 lzma2|6.45%|674M|12.0MB/s|20M|25M|480MB/s| +|hdiffz p8 lzma2|6.45%|666M|36.2MB/s|21M|25M|525MB/s| +|hdiffz p1 zstd|6.74%|682M|12.0MB/s|20M|26M|716MB/s| +|hdiffz p8 zstd|6.74%|1117M|25.3MB/s|20M|26M|752MB/s| +|hdiffz w p8 lzma2|6.49%|666M|26.5MB/s|20M|25M|761MB/s| +|hdiffz w p8 zstd|6.78%|965M|20.4MB/s|20M|26M|1326MB/s| +|hdiffz WD p1 lzma2|6.52%|674M|8.0MB/s|22M|27M|758MB/s| +|hdiffz WD p8 lzma2|6.52%|665M|26.9MB/s|24M|29M|1027MB/s| +|hdiffz WD p1 zstd|6.82%|682M|8.0MB/s|22M|28M|1611MB/s| +|hdiffz WD p8 zstd|6.82%|970M|20.6MB/s|24M|30M|2529MB/s| || -|hdiffz s p1 zlib|12.52%|91M|46.4MB/s|3M|4M|611MB/s| -|hdiffz s p8 zlib|12.53%|95M|178.9MB/s|3M|4M|609MB/s| -|hdiffz s p1 lzma2|9.11%|170M|18.1MB/s|17M|20M|402MB/s| -|hdiffz s p8 lzma2|9.13%|370M|50.6MB/s|17M|20M|400MB/s| -|hdiffz s p1 zstd|9.60%|195M|18.0MB/s|17M|21M|677MB/s| -|hdiffz s p8 zstd|9.60%|976M|28.5MB/s|17M|21M|678MB/s| -|hdiffz sw p8 lzma2|6.76%|253M|33.7MB/s|20M|25M|584MB/s| -|hdiffz sw p8 zstd|7.07%|851M|24.9MB/s|20M|26M|873MB/s| -|hdiffz sWD p1 lzma2|6.80%|177M|13.0MB/s|22M|27M|710MB/s| -|hdiffz sWD p8 lzma2|6.80%|269M|39.6MB/s|22M|27M|988MB/s| -|hdiffz sWD p1 zstd|7.12%|211M|13.2MB/s|21M|28M|1449MB/s| -|hdiffz sWD p8 zstd|7.12%|869M|27.9MB/s|21M|28M|2326MB/s| +|hdiffz s p1 zlib|12.52%|80M|45.2MB/s|8M|9M|831MB/s| +|hdiffz s p8 zlib|12.52%|85M|184.1MB/s|8M|9M|828MB/s| +|hdiffz s p1 lzma2|9.11%|169M|17.8MB/s|22M|25M|474MB/s| +|hdiffz s p8 lzma2|9.13%|375M|50.1MB/s|22M|25M|474MB/s| +|hdiffz s p1 zstd|9.58%|195M|17.5MB/s|21M|26M|979MB/s| +|hdiffz s p8 zstd|9.58%|980M|27.4MB/s|21M|26M|969MB/s| +|hdiffz sw p8 lzma2|6.76%|252M|36.1MB/s|20M|25M|609MB/s| +|hdiffz sw p8 zstd|7.07%|851M|26.2MB/s|20M|26M|921MB/s| +|hdiffz sWD p1 lzma2|6.80%|177M|13.0MB/s|22M|27M|721MB/s| +|hdiffz sWD p8 lzma2|6.80%|269M|43.2MB/s|23M|29M|987MB/s| +|hdiffz sWD p1 zstd|7.12%|211M|13.2MB/s|21M|28M|1497MB/s| +|hdiffz sWD p8 zstd|7.12%|870M|29.8MB/s|23M|30M|2440MB/s| ## 使用 Apk 文件来测试: @@ -531,8 +541,7 @@ client sync diff&patch by `hsync_demo {old} {newi} {newz} {out_new} -p-1` **对测试程序的参数进行一些调整**: -**hdiffz ...** `-m-6 -SD` changed to `-m-1 -SD-2m -cache`, `-s-64 -SD` changed to `-s-16 -SD-2m` -**hdiffz ...** lzma2 dict size `16m` changed to `8m`, zstd dict bit `24` changed to `23` +**hdiffz ...** `-m-6` changed to `-m-2 -cache`, `-s-64` changed to `-s-16` **hsynz ...** make `-s-2k` changed to `-s-1k` & adding **hsynz p1**, **hsynz p8** make without compressor **archive-patcher** v1.0, diff with `--generate --old {old} --new {new} --patch {pat}`, @@ -542,25 +551,23 @@ client sync diff&patch by `hsync_demo {old} {newi} {newz} {out_new} -p-1` & **sfpatcher -2 lzma2** diff with `-o-2 -c-lzma2-9-4m -m-1 -step-2m -lp-8m -p-8 -cache -d {old} {new} {pat}` **sfpatcher -1 clA zstd** v1.3.0 used `$sf_normalize -cl-A` normalized apks before diff sfpatcher patch with `-lp -p-8 {old} {pat} {new}` -adding test hpatchz&sfpatcher on Android, arm CPU 麒麟980(2×A76 2.6G + 2×A76 1.92G + 4×A55 1.8G) -( [archive-patcher]、[sfpatcher] diff&patch 时针对apk文件格式进行了优化 ) - -2026-06-25 更新: 为 HDiffPatch v5.0.0 的 WinDiff(优化了补丁速度) 添加相关测试 -`w` mean diff with `-w-2m`, `WD` mean diff with `-WD -w-2m` + adding test hpatchz v4.6.9 & sfpatcher on Android, arm CPU 麒麟980(2×A76 2.6G + 2×A76 1.92G + 4×A55 1.8G) +( [archive-patcher]、[sfpatcher] diff&patch 时针对apk文件格式进行了优化 ) **测试结果取平均**: |程序|包大小|diff内存|速度|patch内存|最大内存|速度|arm 麒麟980| |:----|----:|----:|----:|----:|----:|----:|----:| -|zstd --patch-from|53.18%|2199M|3.6MB/s|209M|596M|609MB/s| -|xdelta3|54.51%|422M|3.8MB/s|98M|99M|170MB/s| -|xdelta3 +hpatchz|54.51%|422M|3.8MB/s|70M|81M|438MB/s| -|hdiffz sw p1 -VCD|53.73%|288M|9.0MB/s|33M|33M|317MB/s| -|hdiffz sw p8 -VCD|53.73%|459M|26.2MB/s|33M|33M|318MB/s| -|bsdiff|53.84%|931M|1.2MB/s|218M|605M|54MB/s| -|bsdiff +hpatchz -m|53.84%|931M|1.2MB/s|116M|310M|57MB/s| -|bsdiff +hpatchz -s|53.84%|931M|1.2MB/s|14M|14M|54MB/s| -|hdiffz p1 -BSD|53.69%|509M|6.8MB/s|14M|14M|55MB/s| -|hdiffz p8 -BSD|53.70%|514M|15.3MB/s|14M|14M|55MB/s| +|zstd --patch-from|53.15%|2251M|3.2MB/s|204M|599M|1266MB/s| +|xdelta3|54.51%|422M|3.8MB/s|97M|100M|162MB/s| +|xdelta3 +hpatchz|54.51%|422M|3.8MB/s|76M|87M|417MB/s| +|hdiffz sw p1 -VCD|53.73%|288M|9.6MB/s|36M|36M|325MB/s| +|hdiffz sw p8 -VCD|53.73%|459M|27.8MB/s|36M|36M|323MB/s| +|bsdiff|53.84%|931M|1.2MB/s|218M|605M|52MB/s| +|bsdiff +hpatchz -m|53.84%|931M|1.2MB/s|123M|316M|54MB/s| +|bsdiff +hpatchz -s|53.84%|931M|1.2MB/s|19M|19M|51MB/s| +|hdiffz p1 -BSD|53.70%|412M|7.2MB/s|19M|19M|53MB/s| +|hdiffz p8 -BSD|53.72%|416M|15.5MB/s|19M|19M|53MB/s| +|| |hsynz p1|62.43%|4M|1533.5MB/s|4M|10M|236MB/s| |hsynz p8|62.43%|18M|2336.4MB/s|12M|18M|394MB/s| |hsynz p1 zlib|58.67%|5M|22.7MB/s|4M|11M|243MB/s| @@ -568,32 +575,31 @@ adding test hpatchz&sfpatcher on Android, arm CPU 麒麟980(2×A76 2.6G + 2×A76 |hsynz p1 zstd|57.74%|534M|2.7MB/s|24M|28M|234MB/s| |hsynz p8 zstd|57.74%|3434M|13.4MB/s|24M|28M|390MB/s| || -|hdiffz p1|54.40%|509M|8.8MB/s|5M|6M|682MB/s| -|hdiffz p8|54.41%|514M|32.4MB/s|5M|6M|686MB/s|443MB/s| -|hdiffz p1 zlib|53.21%|509M|8.2MB/s|5M|6M|514MB/s| -|hdiffz p8 zlib|53.22%|514M|31.1MB/s|5M|6M|512MB/s|343MB/s| -|hdiffz p1 lzma2|52.93%|525M|4.1MB/s|21M|22M|260MB/s| -|hdiffz p8 lzma2|52.94%|557M|18.9MB/s|21M|22M|261MB/s|131MB/s| -|hdiffz p1 zstd|53.04%|537M|5.4MB/s|21M|22M|598MB/s| -|hdiffz p8 zstd|53.05%|1251M|11.1MB/s|21M|22M|604MB/s|371MB/s| -|hdiffz w p8 lzma2|53.25%|389M|8.0MB/s|25M|25M|322MB/s| -|hdiffz w p8 zstd|53.36%|1042M|6.3MB/s|24M|26M|1098MB/s| -|hdiffz WD p1 lzma2|53.27%|374M|1.7MB/s|27M|27M|303MB/s| -|hdiffz WD p8 lzma2|53.27%|390M|8.0MB/s|27M|27M|350MB/s| -|hdiffz WD p1 zstd|53.38%|384M|1.9MB/s|25M|28M|1171MB/s| -|hdiffz WD p8 zstd|53.38%|1045M|6.2MB/s|20M|28M|1768MB/s| -|hdiffz s p1 zlib|53.73%|118M|26.8MB/s|4M|6M|513MB/s| -|hdiffz s p8 zlib|53.73%|122M|97.3MB/s|4M|6M|513MB/s| -|hdiffz s p1 lzma2|53.30%|197M|6.4MB/s|20M|22M|258MB/s| -|hdiffz s p8 lzma2|53.30%|309M|32.4MB/s|20M|22M|258MB/s| -|hdiffz s p1 zstd|53.44%|221M|10.1MB/s|20M|22M|620MB/s| -|hdiffz s p8 zstd|53.44%|1048M|14.4MB/s|20M|22M|613MB/s| -|hdiffz sw p8 lzma2|53.27%|299M|19.3MB/s|25M|25M|319MB/s| -|hdiffz sw p8 zstd|53.38%|1042M|11.3MB/s|25M|26M|1068MB/s| -|hdiffz sWD p1 lzma2|53.29%|196M|4.6MB/s|27M|27M|306MB/s| -|hdiffz sWD p8 lzma2|53.29%|303M|19.8MB/s|27M|27M|350MB/s| -|hdiffz sWD p1 zstd|53.41%|222M|6.3MB/s|25M|28M|1179MB/s| -|hdiffz sWD p8 zstd|53.41%|1045M|11.5MB/s|20M|28M|1770MB/s| +|hdiffz p1 zlib|53.22%|412M|8.8MB/s|10M|11M|827MB/s|343MB/s| +|hdiffz p8 zlib|53.23%|415M|32.6MB/s|10M|11M|916MB/s| +|hdiffz p1 lzma2|52.92%|429M|4.3MB/s|26M|27M|310MB/s|131MB/s| +|hdiffz p8 lzma2|52.94%|464M|19.4MB/s|26M|27M|327MB/s| +|hdiffz p1 zstd|53.04%|442M|5.7MB/s|25M|27M|1072MB/s|371MB/s| +|hdiffz p8 zstd|53.05%|1164M|11.2MB/s|25M|28M|1104MB/s| +|hdiffz w p8 lzma2|53.24%|426M|14.4MB/s|26M|27M|322MB/s| +|hdiffz w p8 zstd|53.35%|1044M|9.3MB/s|24M|28M|1135MB/s| +|hdiffz WD p1 lzma2|53.27%|417M|3.2MB/s|27M|27M|312MB/s| +|hdiffz WD p8 lzma2|53.27%|426M|14.6MB/s|29M|29M|353MB/s| +|hdiffz WD p1 zstd|53.38%|425M|3.9MB/s|25M|28M|1266MB/s| +|hdiffz WD p8 zstd|53.38%|1045M|9.4MB/s|22M|30M|1877MB/s| +|| +|hdiffz s p1 zlib|53.73%|100M|27.0MB/s|9M|11M|780MB/s| +|hdiffz s p8 zlib|53.73%|104M|97.1MB/s|9M|11M|885MB/s| +|hdiffz s p1 lzma2|53.30%|193M|6.5MB/s|25M|27M|296MB/s| +|hdiffz s p8 lzma2|53.30%|312M|32.4MB/s|25M|27M|317MB/s| +|hdiffz s p1 zstd|53.44%|218M|10.3MB/s|24M|27M|1021MB/s| +|hdiffz s p8 zstd|53.44%|1049M|14.3MB/s|23M|28M|1091MB/s| +|hdiffz sw p8 lzma2|53.26%|302M|22.4MB/s|26M|27M|322MB/s| +|hdiffz sw p8 zstd|53.37%|1044M|12.1MB/s|25M|28M|1086MB/s| +|hdiffz sWD p1 lzma2|53.29%|196M|4.7MB/s|27M|27M|315MB/s| +|hdiffz sWD p8 lzma2|53.29%|303M|23.1MB/s|29M|29M|352MB/s| +|hdiffz sWD p1 zstd|53.41%|222M|6.5MB/s|25M|28M|1281MB/s| +|hdiffz sWD p8 zstd|53.41%|1045M|12.2MB/s|21M|30M|1874MB/s| || |archive-patcher|31.65%|1448M|0.9MB/s|558M|587M|14MB/s| |sfpatcher-1 p1 zstd|31.08%|818M|2.3MB/s|15M|19M|201MB/s|92MB/s| diff --git a/hdiffz.cpp b/hdiffz.cpp index 3901f5b9..bab18d42 100644 --- a/hdiffz.cpp +++ b/hdiffz.cpp @@ -185,7 +185,7 @@ static void printUsage(){ " big cache max used O(oldFileSize) memory, and build slow(diff speed--)\n" " -w[-oldWinSize-segSize]\n" " diff by window mode; optimize read old data when patch;\n" - " in -m mode, outDiffFile size+, in -s mode, outDiffFile size-- & patch speed-;\n" + " in -m mode, outDiffFile size+, in -s mode, outDiffFile size--;\n" " if oldWinSize+ or segSize-, outDiffFile size-, but diff & patch speed--\n" " oldWinSize: max window bytes on old data, DEFAULT -w-2m;\n" " for big file, recommended -w-4m-128k, -w-16m-256k, etc...\n" diff --git a/hpatchz.c b/hpatchz.c index 74c79f7f..3ae059c0 100644 --- a/hpatchz.c +++ b/hpatchz.c @@ -195,11 +195,12 @@ static void printUsage(){ " -s[-cacheSize] \n" " DEFAULT -s-8m; oldPath loaded as Stream;\n" " cacheSize can like 262144 or 256k or 64m or 512m etc....\n" - " requires (cacheSize + 4*decompress buffer size)+O(1) bytes of memory.\n" " if diffFile is window diffData(created by hdiffz -WD-stepSize -w-oldWinSize), then requires\n" - " (cacheSize+ stepSize+oldWinSize + 1*decompress buffer size)+O(1) bytes of memory;\n" + " (cacheSize+ oldWinSize+stepSize + 1*decompress buffer size)+O(1) bytes of memory;\n" " if diffFile is single compressed diffData(created by hdiffz -SD-stepSize), then requires\n" " (cacheSize+ stepSize + 1*decompress buffer size)+O(1) bytes of memory;\n" + " if diffFile is compressed diffData(created by hdiffz), then requires\n" + " (cacheSize + 4*decompress buffer size)+O(1) bytes of memory.\n" #if (_IS_NEED_BSDIFF||_IS_NEED_VCDIFF) " if diffFile is created by" #if (_IS_NEED_BSDIFF) @@ -216,15 +217,18 @@ static void printUsage(){ " (cacheSize+ sourceWindowSize+targetWindowSize + 3*decompress buffer size)+O(1) bytes of memory.\n" #endif " -m oldPath all loaded into Memory;\n" - " requires (oldFileSize + 4*decompress buffer size)+O(1) bytes of memory.\n" + " if diffFile is window diffData(created by hdiffz -WD-stepSize -w-oldWinSize), then requires\n" + " (oldWinSize + stepSize + 1*decompress buffer size)+O(1) bytes of memory;\n" " if diffFile is single compressed diffData(created by hdiffz -SD-stepSize), then requires\n" - " (oldFileSize+ stepSize + 1*decompress buffer size)+O(1) bytes of memory.\n" + " (oldFileSize + stepSize + 1*decompress buffer size)+O(1) bytes of memory.\n" + " if diffFile is compressed diffData(created by hdiffz), then requires\n" + " (oldFileSize + 4*decompress buffer size)+O(1) bytes of memory.\n" #if (_IS_NEED_BSDIFF) " if diffFile is created by hdiffz -BSD,bsdiff4, then requires\n" " (oldFileSize + 3*decompress buffer size)+O(1) bytes of memory.\n" #endif #if (_IS_NEED_VCDIFF) - " if diffFile is VCDIFF(created by hdiffz -VCD,xdelta3,open-vcdiff), then requires\n" + " if diffFile is VCDIFF(created by hdiffz -VCD,hdiffz -VCD -w,xdelta3,open-vcdiff), then requires\n" " (sourceWindowSize+targetWindowSize + 3*decompress buffer size)+O(1) bytes of memory.\n" #endif #if (_IS_USED_MULTITHREAD) @@ -1432,7 +1436,7 @@ int hpatch(const char* oldFileName,const char* diffFileName,const char* outNewFi #endif { //alloc mem hpatch_StreamPos_t minCacheSize,betterCacheSize; - getPatchMemSize(&minCacheSize,&betterCacheSize,isLoadOldAll,diffInfos.diffInfo.oldDataSize,patchCacheSize,0); + getPatchMemSize(&minCacheSize,&betterCacheSize,isLoadOldAll,poldData->streamSize,patchCacheSize,0); #if (_IS_NEED_VCDIFF) if (diffInfos.isVcDiff){//get vcd patch mem size hpatch_StreamPos_t stWindowsSize=diffInfos.vcdiffInfo.maxSrcWindowsSize+diffInfos.vcdiffInfo.maxTargetWindowsSize; @@ -1444,7 +1448,7 @@ int hpatch(const char* oldFileName,const char* diffFileName,const char* outNewFi #endif #if (_IS_NEED_SINGLE_STREAM_DIFF) if (diffInfos.isSingleCompressedDiff){ - getPatchMemSize(&minCacheSize,&betterCacheSize,isLoadOldAll,diffInfos.diffInfo.oldDataSize, + getPatchMemSize(&minCacheSize,&betterCacheSize,isLoadOldAll,poldData->streamSize, patchCacheSize,diffInfos.sdiffInfo.stepMemSize); } #endif diff --git a/libHDiffPatch/HDiff/diff.cpp b/libHDiffPatch/HDiff/diff.cpp index b7a34438..462786f4 100644 --- a/libHDiffPatch/HDiff/diff.cpp +++ b/libHDiffPatch/HDiff/diff.cpp @@ -1163,9 +1163,9 @@ static void _check_window_onPatchFinish(struct winpatch_listener_t* listener, if (temp_cache) free(temp_cache); } -int check_window_diff(const hpatch_TStreamInput* newData,const hpatch_TStreamInput* oldData, - const hpatch_TStreamInput* diffData,hpatch_TDecompress* decompressPlugin, - hpatch_TChecksum* checksumPlugin,size_t threadNum){ +TWindowPatchResult check_window_diff(const hpatch_TStreamInput* newData,const hpatch_TStreamInput* oldData, + const hpatch_TStreamInput* diffData,hpatch_TDecompress* decompressPlugin, + hpatch_TChecksum* checksumPlugin,size_t threadNum){ TWindowCheckImport import; import.decompressPlugin=decompressPlugin; import.checksumPlugin=checksumPlugin; @@ -1180,7 +1180,7 @@ int check_window_diff(const hpatch_TStreamInput* newData,const hpatch_TStreamInp TAutoMem _cache(kACacheBufSize*1); _TCheckOutNewDataStream out_newData(newData,_cache.data(),kACacheBufSize); - enum TWindowPatchResult result=patch_window_diff(&listener,&out_newData,oldData,diffData,0,threadNum); + TWindowPatchResult result=patch_window_diff(&listener,&out_newData,oldData,diffData,0,threadNum); if (result==kWindowPatch_ok) check(out_newData.isWriteFinish()); return result; diff --git a/libHDiffPatch/HDiff/diff.h b/libHDiffPatch/HDiff/diff.h index 94011215..58a35506 100644 --- a/libHDiffPatch/HDiff/diff.h +++ b/libHDiffPatch/HDiff/diff.h @@ -100,12 +100,12 @@ static const size_t kDefaultFastMatchBlockSize = 1024*1; static const size_t kMatchWindowsBlockSize_default = (1<<6); static const size_t kDefaultBigCoverSize = 1024*16; static const size_t kDefaultWindowOldSize = 1024*1024*2; -static const size_t kDefaultSegRatioInWindowOldSize = 64; // default segSize=windowOldSize/kDefaultSegRatioInWindowOldSize +static const size_t kDefaultSegRatioInWindowOldSize = 64; // default segSize=kOldWindowSize/kDefaultSegRatioInWindowOldSize //create a compressed diff data by window mode: // optimize the access speed of old data when patch // kOldWindowSize: max window bytes on old data; -// kSegSize: initial data granularity in a window matching, DEFAULT kOldWindowSize/16; +// kSegSize: initial data granularity in a window matching, if set 0 mean used default; // throw std::runtime_error when I/O error or kSegSize too large,etc. void create_compressed_diff_window(const hpatch_TStreamInput* newData,const hpatch_TStreamInput* oldData, const hpatch_TStreamOutput* out_diff, @@ -175,7 +175,7 @@ void create_single_compressed_diff_stream(const hpatch_TStreamInput* newData, //create single compressed diff data by window mode: // optimize the access speed of old data when patch // kOldWindowSize: max window bytes on old data; -// kSegSize: initial data granularity during window matching, DEFAULT kOldWindowSize/64; +// kSegSize: initial data granularity during window matching, if set 0 mean used default; // throw std::runtime_error when I/O error or kSegSize too large,etc. void create_single_compressed_diff_window(const hpatch_TStreamInput* newData,const hpatch_TStreamInput* oldData, const hpatch_TStreamOutput* out_diff, @@ -260,7 +260,16 @@ void create_single_compressed_diff_block(unsigned char* newData,unsigned char* n int kMinSingleMatchScore=kMinSingleMatchScore_default, bool isUseBigCacheMatch=false,size_t threadNum=1); - +//create window diff data between oldData and newData: +// kMatchBlockSize: recommended (1<<4)--(1<<14) +// if (kMatchBlockSize==0) diff by sstring, else diff by stream(for large file) +// kOldWindowSize: max window bytes on old data; +// requires kOldWindowSize + patchStepMemSize + (I/O cache memory) when patch; +// kSegSize: initial data granularity in a window matching, if set 0 mean used default; +// recommended kOldWindowSize/128<=kSegSize<=kOldWindowSize/4; +// kBigCoverSize: skip big cover when rematching in window, for optimize diff speed; +// NOTICE: out_diff->write()'s writeToPos may be back to update headData! +// throw std::runtime_error when I/O error or kSegSize too large,etc. void create_window_diff(const hpatch_TStreamInput* newData,const hpatch_TStreamInput* oldData, const hpatch_TStreamOutput* out_diff, const hdiff_TCompress* compressPlugin,hpatch_TChecksum* checksumPlugin, @@ -271,10 +280,9 @@ void create_window_diff(const hpatch_TStreamInput* newData,const hpatch_TStreamI int kMinSingleMatchScore=kMinSingleMatchScore_default,bool isUseBigCacheMatch=false, const hdiff_TMTSets_s* mtsets=0,bool isExtendCover=true); -//result type: enum TWindowPatchResult -int check_window_diff(const hpatch_TStreamInput* newData,const hpatch_TStreamInput* oldData, - const hpatch_TStreamInput* diffData,hpatch_TDecompress* decompressPlugin, - hpatch_TChecksum* checksumPlugin,size_t threadNum=1); +TWindowPatchResult check_window_diff(const hpatch_TStreamInput* newData,const hpatch_TStreamInput* oldData, + const hpatch_TStreamInput* diffData,hpatch_TDecompress* decompressPlugin, + hpatch_TChecksum* checksumPlugin,size_t threadNum=1); //resave window_diff hpatch_StreamPos_t resave_window_diff(const hpatch_TStreamInput* in_diff, @@ -338,7 +346,7 @@ void get_match_covers_and_window(const hpatch_TStreamInput* newData,const hpatch const hdiff_TMTSets_s* mtsets=0,bool isExtendCover=true); void get_match_windows_from_baseCovers(hpatch_StreamPos_t newSize,hpatch_StreamPos_t oldSize, - size_t kNewWindowSize,size_t kOldWindowSize,size_t kSegSize,//if (kSegSize==0) kSegSize=kOldWindowSize/16; + size_t kNewWindowSize,size_t kOldWindowSize,size_t kSegSize,//if (kSegSize==0) mean used default; std::vector& baseCovers,std::vector& out_windows, std::vector >& out_bigCoverss,size_t kBigCoverSize); void get_match_covers_in_a_window(const hpatch_TStreamInput* newData,const hpatch_TStreamInput* oldData, diff --git a/libHDiffPatch/HPatch/patch.c b/libHDiffPatch/HPatch/patch.c index e662f67f..11521e7d 100644 --- a/libHDiffPatch/HPatch/patch.c +++ b/libHDiffPatch/HPatch/patch.c @@ -3161,7 +3161,7 @@ TWindowPatchResult patch_window_diff(winpatch_listener_t* listener, unsigned char* temp_cache_back=0; unsigned char* temp_cache=0; unsigned char* temp_cacheEnd=0; - hpatch_BOOL isChecksumNew=hpatch_TRUE; + hpatch_BOOL isChecksumNew; hpatch_BOOL isChecksumOld=hpatch_FALSE; hpatch_BOOL isChecksumDiff=hpatch_FALSE; hpatch_checksumHandle checksumHandle_old=0; @@ -3191,6 +3191,7 @@ TWindowPatchResult patch_window_diff(winpatch_listener_t* listener, return kWindowPatch_new_size_error; out_newData->streamSize=diffInfo.newDataSize;//adjust output stream size + isChecksumNew=(diffInfo.checksumByteSize>0); if (!listener->onDiffInfo(listener,&diffInfo,&decompressPlugin,&checksumPlugin, &isChecksumNew,&isChecksumOld,&isChecksumDiff,&temp_cache,&temp_cacheEnd)) return kWindowPatch_onDiffInfo_error; diff --git a/libHDiffPatch/HPatch/patch.h b/libHDiffPatch/HPatch/patch.h index 61c33197..2fb14e2c 100644 --- a/libHDiffPatch/HPatch/patch.h +++ b/libHDiffPatch/HPatch/patch.h @@ -253,22 +253,6 @@ hpatch_BOOL getWindowDiffInfo(hpatch_windowDiffInfo* out_diffInfo, hpatch_StreamPos_t diffInfo_pos//default 0, begin pos in windowDiff ); -typedef enum TWindowPatchResult{ - kWindowPatch_ok=0, - kWindowPatch_load_head_error, - kWindowPatch_new_size_error, - kWindowPatch_old_size_error, - kWindowPatch_onDiffInfo_error, - kWindowPatch_temp_mem_error, - kWindowPatch_decompress_open_error, - kWindowPatch_patch_error, - kWindowPatch_checksum_plugin_error, - kWindowPatch_checksum_open_error, - kWindowPatch_checksum_old_error, - kWindowPatch_checksum_new_error, - kWindowPatch_checksum_diff_error, -} TWindowPatchResult; - TWindowPatchResult patch_window_diff(struct winpatch_listener_t* listener, const hpatch_TStreamOutput* out_newData, //sequential write const hpatch_TStreamInput* oldData, //random read diff --git a/libHDiffPatch/HPatch/patch_types.h b/libHDiffPatch/HPatch/patch_types.h index 0e363c57..cbde26cc 100644 --- a/libHDiffPatch/HPatch/patch_types.h +++ b/libHDiffPatch/HPatch/patch_types.h @@ -376,10 +376,10 @@ static hpatch_force_inline hpatch_StreamPos_t _hpatch_pos_max(hpatch_StreamPos_t hpatch_StreamPos_t maxStepMemSize; hpatch_StreamPos_t maxSubCoverCount; hpatch_StreamPos_t maxWindowOldSize; - hpatch_StreamPos_t checksumByteSize; //0=no checksum + hpatch_StreamPos_t checksumByteSize; //0 no checksum hpatch_StreamPos_t extraDataSize; hpatch_StreamPos_t uncompressedSize; //windowDiffStreamSize - hpatch_StreamPos_t compressedSize; //0=uncompressed, >0=compressed + hpatch_StreamPos_t compressedSize; //0 uncompressed, >0 compressed hpatch_StreamPos_t otherInfoPos; hpatch_StreamPos_t otherInfoEndPos; hpatch_StreamPos_t windowDataPos; //window data begin pos; old,new,diff's checksum begin pos=windowDataPos-3*checksumByteSize @@ -388,6 +388,22 @@ static hpatch_force_inline hpatch_StreamPos_t _hpatch_pos_max(hpatch_StreamPos_t char checksumType[hpatch_kMaxPluginTypeLength+1]; } hpatch_windowDiffInfo; + typedef enum TWindowPatchResult{ + kWindowPatch_ok=0, + kWindowPatch_load_head_error, + kWindowPatch_new_size_error, + kWindowPatch_old_size_error, + kWindowPatch_onDiffInfo_error, + kWindowPatch_temp_mem_error, + kWindowPatch_decompress_open_error, + kWindowPatch_patch_error, + kWindowPatch_checksum_plugin_error, + kWindowPatch_checksum_open_error, + kWindowPatch_checksum_old_error, + kWindowPatch_checksum_new_error, + kWindowPatch_checksum_diff_error, + } TWindowPatchResult; + hpatch_inline static void _winDiffInfoToHDiffInfo(hpatch_compressedDiffInfo* out_diffInfo,const hpatch_windowDiffInfo* winDiffInfo){ out_diffInfo->newDataSize=winDiffInfo->newDataSize; out_diffInfo->oldDataSize=winDiffInfo->oldDataSize; @@ -402,10 +418,10 @@ static hpatch_force_inline hpatch_StreamPos_t _hpatch_pos_max(hpatch_StreamPos_t const hpatch_windowDiffInfo* info, hpatch_TDecompress** out_decompressPlugin,//find decompressPlugin by info->compressType struct hpatch_TChecksum** out_checksumPlugin, //find checksumPlugin by info->checksumType - hpatch_BOOL* isChecksumNew, // *isChecksumNew default true when have info->checksumType - hpatch_BOOL* isChecksumOld,hpatch_BOOL* isChecksumDiff, + hpatch_BOOL* isChecksumNew, // *isChecksumNew default true when info->checksumByteSize>0 + hpatch_BOOL* isChecksumOld,hpatch_BOOL* isChecksumDiff,//*isChecksumOld & *isChecksumDiff default false unsigned char** out_temp_cache, //*out_temp_cacheEnd-*out_temp_cache == info->maxWindowOldSize + info->stepMemSize + (I/O cache memory) - unsigned char** out_temp_cacheEnd);// note: (I/O cache memory) >= hpatch_kStreamCacheSize*3 + unsigned char** out_temp_cacheEnd);// note: (I/O cache memory) >= hpatch_kStreamCacheSize*3 void (*onPatchFinish)(struct winpatch_listener_t* listener, //onPatchFinish can null unsigned char* temp_cache, unsigned char* temp_cacheEnd); } winpatch_listener_t; From 816472ef02e70b9538f1ba4addb3242ec578a2e1 Mon Sep 17 00:00:00 2001 From: sisong Date: Tue, 30 Jun 2026 17:23:59 +0800 Subject: [PATCH 5/7] update version; --- README.md | 2 +- README_cn.md | 2 +- libHDiffPatch/HPatch/patch_types.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a5e7a27a..5b6ec458 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # [HDiffPatch] -[![release](https://img.shields.io/badge/release-v5.0.0-blue.svg)](https://github.com/sisong/HDiffPatch/releases) +[![release](https://img.shields.io/badge/release-v5.0.1-blue.svg)](https://github.com/sisong/HDiffPatch/releases) [![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/sisong/HDiffPatch/blob/master/LICENSE) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-blue.svg)](https://github.com/sisong/HDiffPatch/pulls) [![+issue Welcome](https://img.shields.io/github/issues-raw/sisong/HDiffPatch?color=green&label=%2Bissue%20welcome)](https://github.com/sisong/HDiffPatch/issues) diff --git a/README_cn.md b/README_cn.md index 000196ee..cbf3292e 100644 --- a/README_cn.md +++ b/README_cn.md @@ -1,5 +1,5 @@ # [HDiffPatch] -[![release](https://img.shields.io/badge/release-v5.0.0-blue.svg)](https://github.com/sisong/HDiffPatch/releases) +[![release](https://img.shields.io/badge/release-v5.0.1-blue.svg)](https://github.com/sisong/HDiffPatch/releases) [![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/sisong/HDiffPatch/blob/master/LICENSE) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-blue.svg)](https://github.com/sisong/HDiffPatch/pulls) [![+issue Welcome](https://img.shields.io/github/issues-raw/sisong/HDiffPatch?color=green&label=%2Bissue%20welcome)](https://github.com/sisong/HDiffPatch/issues) diff --git a/libHDiffPatch/HPatch/patch_types.h b/libHDiffPatch/HPatch/patch_types.h index cbde26cc..d2dc4996 100644 --- a/libHDiffPatch/HPatch/patch_types.h +++ b/libHDiffPatch/HPatch/patch_types.h @@ -38,7 +38,7 @@ extern "C" { #define HDIFFPATCH_VERSION_MAJOR 5 #define HDIFFPATCH_VERSION_MINOR 0 -#define HDIFFPATCH_VERSION_RELEASE 0 +#define HDIFFPATCH_VERSION_RELEASE 1 #define _HDIFFPATCH_VERSION HDIFFPATCH_VERSION_MAJOR.HDIFFPATCH_VERSION_MINOR.HDIFFPATCH_VERSION_RELEASE #define _HDIFFPATCH_QUOTE(str) #str From 878677dfab85fcf25adf198839a1be46a69c21d9 Mon Sep 17 00:00:00 2001 From: sisong Date: Wed, 1 Jul 2026 12:02:13 +0800 Subject: [PATCH 6/7] update doc; var diffDataOffert rename to diffDataOffset ...; --- README.md | 30 ++++---- README_cn.md | 8 +-- builds/android_ndk_jni_mk/hpatch.h | 1 + .../java/com/github/sisong/HPatch.java | 2 +- .../hpatch_objc/hpatch_objc.h | 2 +- dirDiffPatch/dir_patch/dir_patch.c | 6 +- dirDiffPatch/dir_patch/dir_patch.h | 2 +- dirDiffPatch/dir_patch/dir_patch_types.h | 6 +- hdiffz.cpp | 31 ++++---- hpatchz.c | 70 +++++++++---------- libHDiffPatch/HDiff/diff.h | 36 +++++----- libHDiffPatch/HPatch/patch.h | 10 +-- libHDiffPatch/HPatch/patch_types.h | 13 ++-- 13 files changed, 108 insertions(+), 109 deletions(-) diff --git a/README.md b/README.md index 5b6ec458..5ba7180f 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,9 @@ [HDiffPatch] defines its own patch file format, this lib is also compatible with the [bsdiff4] & [endsley/bsdiff] patch file format and [compatible](https://github.com/sisong/HDiffPatch/issues/369#issuecomment-1869798843) with the [open-vcdiff] & [xdelta3] patch file format [VCDIFF(RFC 3284)]. -if need patch (OTA) on embedded systems,MCU,NB-IoT..., see demo [HPatchLite], +[tinyuz] decompressor can run on 1KB RAM devices! HPatchLite also supports a simple inplace-patch implementation to support storage-constrained devices. +if need patch (OTA) on embedded systems,MCU,NB-IoT..., see demo [HPatchLite], with [tinyuz] decompressor can run on 1KB RAM devices! HPatchLite also supports a simple inplace-patch implementation to support storage-constrained devices. -update your own Android Apk? Jar or Zip file diff & patch? try [ApkDiffPatch], to create smaller delta/differential! NOTE: *ApkDiffPath can't be used by Android app store, because it requires re-signing apks before diff.* +update your own Android Apk? Jar or Zip file diff & patch? try [ApkDiffPatch], to create smaller delta/differential! NOTE: *ApkDiffPatch can't be used by Android app store, because it requires re-signing apks before diff.* [sfpatcher] not require re-signing apks (like [archive-patcher]), is designed for Android app store, create smaller patch file for apk, patch speed up by a factor of xx than archive-patcher & run with O(1) memory. @@ -92,11 +92,11 @@ build `HDiffPatch/builds/vc/HDiffPatch.sln` by [`Visual Studio`](https://visuals ## **diff** command line usage: diff usage: **hdiffz** [options] **oldPath newPath outDiffFile** compress usage: **hdiffz** [-c-...] **"" newPath outDiffFile** -test usage: **hdiffz** -t **oldPath newPath testDiffFile** -resave usage: **hdiffz** [-c-...] **diffFile outDiffFile** -print info: **hdiffz** -info **diffFile** -get manifest: **hdiffz** [-g#...] [-C-checksumType] **inputPath -M#outManifestTxtFile** -manifest diff: **hdiffz** [options] **-M-old#oldManifestFile -M-new#newManifestFile oldPath newPath outDiffFile** +test usage: **hdiffz** -t **oldPath newPath testDiffFile** +resave usage: **hdiffz** [-c-...] **diffFile outDiffFile** +print info: **hdiffz** -info **diffFile** +get manifest: **hdiffz** [-g#...] [-C-checksumType] **inputPath -M#outManifestTxtFile** +manifest diff: **hdiffz** [options] **-M-old#oldManifestFile -M-new#newManifestFile oldPath newPath outDiffFile** ``` oldPath newPath inputPath can be file or directory(folder), oldPath can empty, and input parameter "" @@ -132,17 +132,17 @@ options: recommended oldWinSize/128<=segSize<=oldWinSize/4; -WD[-stepSize] (need v5.0 patcher) create window diffData(HDIFFW26), optimize read old data when patch; - recommended as the primary diff format; when patch, and support step by step - patching when step by step downloading! and supports multi-thread patching! - requires diff by window mode, auto enable -w if not set; + recommended as the primary diff format; supports step-by-step patching + during step-by-step downloading, and supports multi-thread patching! + requires diff by window mode, auto enable -w-2m if not set; default compress by zstd, can set -c-no for no compress; default checksum by xxh128, can set -C-no for no checksum; - stepSize>=(1024*4), DEFAULT -WD-256k, recommended 128k,512k etc... + stepSize>=4096, DEFAULT -WD-256k, recommended 128k,512k etc... -SD[-stepSize] create single compressed diffData(HDIFFSF20 format), only need one decompress buffer when patch, and support step by step patching when step by step downloading! and supports multi-thread patching! - stepSize>=(1024*4), DEFAULT -SD-256k, recommended 64k,2m etc... + stepSize>=4096, DEFAULT -SD-256k, recommended 64k,2m etc... -BSD create diffFile compatible with bsdiff4, unsupport input directory(folder). also support run with -SD (not used stepSize), then create single compressed @@ -210,7 +210,7 @@ options: #.DS_Store#desktop.ini#*thumbs*.db#.git*#.svn/#cache_*/00*11/*.tmp # means separator between names; (if char # in name, need write #: ) * means can match any chars in name; (if char * in name, need write *: ); - / at the end of name means must match directory; + / at the end of name means match the directory (including its contents); -g-old#ignorePath[#ignorePath#...] set iGnore path list in oldPath when Directory Diff; if oldFile can be changed, need add it in old ignore list; @@ -231,7 +231,7 @@ options: -neq open check: if newPath & oldPath's all datas are equal, then return error; DEFAULT not check equal. - -d Diff only, do't run patch check, DEFAULT run patch check. + -d Diff only, don't run patch check, DEFAULT run patch check. -t Test only, run patch check, patch(oldPath,testDiffFile)==newPath ? -f Force overwrite, ignore write path already exists; DEFAULT (no -f) not overwrite and then return error; @@ -281,7 +281,7 @@ options: (sourceWindowSize+targetWindowSize + 3*decompress buffer size)+O(1) bytes of memory. -p-parallelThreadNumber if parallelThreadNumber>1 then open multi-thread Parallel mode; - now only support single compressed diffData(created by hdiffz -SD-stepSize); + now support window diffData(created by hdiffz -WD) and single compressed diffData(created by hdiffz -SD); can set 1..5, DEFAULT -p-1! -C-checksumSets set Checksum data for window patch & directory patch & VCDIFF patch, DEFAULT -C-new-copy; diff --git a/README_cn.md b/README_cn.md index cbf3292e..2aaa0df9 100644 --- a/README_cn.md +++ b/README_cn.md @@ -12,7 +12,7 @@ [HDiffPatch] 定义了自己的补丁包格式,同时这个库也完全兼容了 [bsdiff4] 和 [endsley/bsdiff] 的补丁包格式,并[兼容](https://github.com/sisong/HDiffPatch/issues/369#issuecomment-1869798843)了 [open-vcdiff] 和 [xdelta3] 的补丁包格式 [VCDIFF(RFC 3284)]。 -如果你需要在嵌入式系统(MCU、NB-IoT)等设备上进行增量更新(OTA), 可以看看例子 [HPatchLite], +[tinyuz] 解压缩器可以在1KB内存的设备上运行! HPatchLite也支持一种简单的原地更新(inplace-patch)实现,用以支持存储受限的设备。 +如果你需要在嵌入式系统(MCU、NB-IoT)等设备上进行增量更新(OTA), 可以看看例子 [HPatchLite], 配合 [tinyuz] 解压缩器可以在1KB内存的设备上运行! HPatchLite也支持一种简单的原地更新(inplace-patch)实现,用以支持存储受限的设备。 需要更新你自己的安卓apk? 需要对Jar或Zip文件执行 diff 和 patch ? 可以试试 [ApkDiffPatch], 可以创建更小的补丁! 注意: *ApkDiffPath 不能被安卓应用商店作为增量更新所用,因为该算法要求在diff前对apk文件进行重新签名。* @@ -135,7 +135,7 @@ make -j -WD[-stepSize] (需要 v5.0 版本 patcher) 创建窗口diff格式(HDIFFW26), 优化patch时old data读取访问; 推荐作为主要的diff格式; patch时支持边下载边patch! 并支持多线程patch! - 需要窗口模式diff, 如果没有设置-w则自动启用; + 需要窗口模式diff, 如果没有设置则自动启用-w-2m; 默认压缩算法为zstd, 可以通过-c-no关闭压缩; 默认checksum为xxh128, 可以通过-C-no关闭checksum; stepSize>=(1024*4), 默认 -WD-256k, 推荐128k,512k等。 @@ -206,7 +206,7 @@ make -j #.DS_Store#desktop.ini#*thumbs*.db#.git*#.svn/#cache_*/00*11/*.tmp # 意味着路径名称之间的间隔; (如果名称中有“#”号, 需要改写为“#:” ) * 意味着匹配名称中的任意一段字符; (如果名称中有“*”号, 需要改写为“*:” ) - / 如果该符号放在名称末尾,意味着必须匹配文件夹; + / 如果该符号放在名称末尾,意味着匹配文件夹(包括文件夹内的所有文件与子目录); -g-old#ignorePath[#ignorePath#...] 为文件夹间的diff设置忽略旧版本的路径; 如果旧版本中的某个文件数据可以被运行中的程序改动,那可以将该文件放到该忽略列表中; @@ -281,7 +281,7 @@ make -j 当前支持单压缩流补丁文件(用hdiffz -SD-stepSize创建)和window diff格式补丁文件(用hdiffz -WD所创建); 可以设置值 1..5, 默认 -p-1 (即单线程)! -C-checksumSets - 为窗口补丁、文件夹补丁、VCDIFF补丁设置校验方式, 默认设置为 -C-new; + 为窗口补丁、文件夹补丁、VCDIFF补丁设置校验方式, 默认设置为 -C-new-copy; 校验设置支持(可以多选): -C-no 不执行校验; -C-new 校验有修改过的新版本的文件; diff --git a/builds/android_ndk_jni_mk/hpatch.h b/builds/android_ndk_jni_mk/hpatch.h index f3f3e7e0..839a7580 100644 --- a/builds/android_ndk_jni_mk/hpatch.h +++ b/builds/android_ndk_jni_mk/hpatch.h @@ -22,6 +22,7 @@ extern "C" { // cacheMemory: // cacheMemory is used for file IO, different cacheMemory only affects patch speed; // recommended 1M,8M,... if cacheMemory<0 then default 1024*1024*4; + // isChecksumNewData: 0 or 1, recommended 1; auto checksum newData when patching VCDIFF and window diffData; int hpatchz(const char *oldFileName,const char *diffFileName,const char *outNewFileName, int64_t cacheMemory,size_t threadNum,unsigned int isChecksumNewData) H_PATCH_EXPORT; diff --git a/builds/android_ndk_jni_mk/java/com/github/sisong/HPatch.java b/builds/android_ndk_jni_mk/java/com/github/sisong/HPatch.java index 09273da2..3032bede 100644 --- a/builds/android_ndk_jni_mk/java/com/github/sisong/HPatch.java +++ b/builds/android_ndk_jni_mk/java/com/github/sisong/HPatch.java @@ -17,7 +17,7 @@ public class HPatch{ // if need supported oldFileName or outNewFileName is directory, build .so with DIR=1 can opened; // threadNum: 1..5, default 1; >1 opened multi-thread patching; // now support single compressed diffData(created by hdiffz -SD) & window diffData(created by hdiffz -WD, recommended) - // isChecksumNewData: default true; checsum newData when patching VCDIFF and window diffData; + // isChecksumNewData: default true; auto checksum newData when patching VCDIFF and window diffData; public static native int patch(String oldFileName,String diffFileName,String outNewFileName,long cacheMemory,int _threadNum,boolean isChecksumNewData); public static final int patch(String oldFileName,String diffFileName,String outNewFileName,long cacheMemory,int _threadNum){ return patch(oldFileName,diffFileName,outNewFileName,cacheMemory,_threadNum,true); diff --git a/builds/xcode_iOS_hpatchz/hpatch_objc/hpatch_objc.h b/builds/xcode_iOS_hpatchz/hpatch_objc/hpatch_objc.h index 06eb83f6..ab46ccb5 100644 --- a/builds/xcode_iOS_hpatchz/hpatch_objc/hpatch_objc.h +++ b/builds/xcode_iOS_hpatchz/hpatch_objc/hpatch_objc.h @@ -20,7 +20,7 @@ // if need supported oldFileName or outNewFileName is directory, build .so with DIR=1 can opened; // threadNum: 1..5, default 1; >1 opened multi-thread patching; // now support single compressed diffData(created by hdiffz -SD) & window diffData(created by hdiffz -WD, recommended) - // isChecksumNewData: default true; checsum newData when patching VCDIFF and window diffData; + // isChecksumNewData: default true; auto checksum newData when patching VCDIFF and window diffData; + (int)patchWithOld:(NSString *)oldFileName withDiff:(NSString *)diffFileName diff --git a/dirDiffPatch/dir_patch/dir_patch.c b/dirDiffPatch/dir_patch/dir_patch.c index f800871f..5638a11b 100644 --- a/dirDiffPatch/dir_patch/dir_patch.c +++ b/dirDiffPatch/dir_patch/dir_patch.c @@ -52,14 +52,14 @@ static const char* kVersionType="HDIFF19"; hpatch_BOOL getDirDiffInfoByFile(TDirDiffInfo* out_info,const char* diffFileName, - hpatch_StreamPos_t diffDataOffert,hpatch_StreamPos_t diffDataSize){ + hpatch_StreamPos_t diffDataOffset,hpatch_StreamPos_t diffDataSize){ hpatch_BOOL result=hpatch_TRUE; hpatch_TFileStreamInput diffData; hpatch_TFileStreamInput_init(&diffData); checki(hpatch_TFileStreamInput_open(&diffData,diffFileName),"getDirDiffInfoByFile() file open"); - if (diffDataOffert>0){ - checki(hpatch_TFileStreamInput_setOffset(&diffData,diffDataOffert), + if (diffDataOffset>0){ + checki(hpatch_TFileStreamInput_setOffset(&diffData,diffDataOffset), "getDirDiffInfoByFile() file setOffset"); check(diffData.base.streamSize>=diffDataSize); diffData.base.streamSize=diffDataSize; diff --git a/dirDiffPatch/dir_patch/dir_patch.h b/dirDiffPatch/dir_patch/dir_patch.h index 53893af8..9ea381d6 100644 --- a/dirDiffPatch/dir_patch/dir_patch.h +++ b/dirDiffPatch/dir_patch/dir_patch.h @@ -72,7 +72,7 @@ typedef struct TDirDiffInfo{ hpatch_BOOL getDirDiffInfo(TDirDiffInfo* out_info,const hpatch_TStreamInput* diffFile); hpatch_BOOL getDirDiffInfoByFile(TDirDiffInfo* out_info,const char* diffFileName, - hpatch_StreamPos_t diffDataOffert,hpatch_StreamPos_t diffDataSize); + hpatch_StreamPos_t diffDataOffset,hpatch_StreamPos_t diffDataSize); static hpatch_inline hpatch_BOOL getIsDirDiffFile(const char* diffFileName){ TDirDiffInfo dirDiffInfo; diff --git a/dirDiffPatch/dir_patch/dir_patch_types.h b/dirDiffPatch/dir_patch/dir_patch_types.h index df6e6f55..aafe93dd 100644 --- a/dirDiffPatch/dir_patch/dir_patch_types.h +++ b/dirDiffPatch/dir_patch/dir_patch_types.h @@ -52,11 +52,11 @@ extern "C" { #endif #ifdef _WIN32 -static const char kPatch_dirSeparator = '\\'; +#define kPatch_dirSeparator '\\' #else -static const char kPatch_dirSeparator = '/'; +#define kPatch_dirSeparator '/' #endif -static const char kPatch_dirSeparator_saved = '/'; +#define kPatch_dirSeparator_saved '/' static hpatch_inline //align upper hpatch_StreamPos_t toAlignRangeSize(hpatch_StreamPos_t rangeSize,size_t kAlignSize) diff --git a/hdiffz.cpp b/hdiffz.cpp index bab18d42..e3696238 100644 --- a/hdiffz.cpp +++ b/hdiffz.cpp @@ -146,13 +146,14 @@ static void printHelpInfo(){ static void printUsage(){ printVersion(); printf("\n"); - printf("diff usage: hdiffz [options] oldPath newPath outDiffFile\n" - "test usage: hdiffz -t oldPath newPath testDiffFile\n" - "resave usage: hdiffz [-c-...] diffFile outDiffFile\n" - "print info: hdiffz -info diffFile\n" + printf("diff usage: hdiffz [options] oldPath newPath outDiffFile\n" + "compress usage: hdiffz [-c-...] \"\" newPath outDiffFile\n" + "test usage: hdiffz -t oldPath newPath testDiffFile\n" + "resave usage: hdiffz [-c-...] diffFile outDiffFile\n" + "print info: hdiffz -info diffFile\n" #if (_IS_NEED_DIR_DIFF_PATCH) - "get manifest: hdiffz [-g#...] [-C-checksumType] inputPath -M#outManifestTxtFile\n" - "manifest diff: hdiffz [options] -M-old#oldManifestFile -M-new#newManifestFile\n" + "get manifest: hdiffz [-g#...] [-C-checksumType] inputPath -M#outManifestTxtFile\n" + "manifest diff: hdiffz [options] -M-old#oldManifestFile -M-new#newManifestFile\n" " oldPath newPath outDiffFile\n" " oldPath newPath inputPath can be file or directory(folder),\n" #endif @@ -193,9 +194,9 @@ static void printUsage(){ " recommended oldWinSize/128<=segSize<=oldWinSize/4;\n" " -WD[-stepSize] (need v5.0 patcher)\n" " create window diffData(HDIFFW26), optimize read old data when patch;\n" - " recommended as the primary diff format; when patch, and support step by step\n" - " patching when step by step downloading! and supports multi-thread patching!\n" - " requires diff by window mode, auto enable -w if not set;\n" + " recommended as the primary diff format; supports step-by-step patching\n" + " during step-by-step downloading, and supports multi-thread patching!\n" + " requires diff by window mode, auto enable -w-2m if not set;\n" #ifdef _CompressPlugin_zstd " default compress by zstd, can set -c-no for no compress;\n" #else @@ -395,7 +396,7 @@ static void printUsage(){ " #.DS_Store#desktop.ini#*thumbs*.db#.git*#.svn/#cache_*/00*11/*.tmp\n" " # means separator between names; (if char # in name, need write #: )\n" " * means can match any chars in name; (if char * in name, need write *: );\n" - " / at the end of name means must match directory;\n" + " / at the end of name means match the directory (including its contents);\n" " -g-old#ignorePath[#ignorePath#...]\n" " set iGnore path list in oldPath when Directory Diff;\n" " if oldFile can be changed, need add it in old ignore list;\n" @@ -417,7 +418,7 @@ static void printUsage(){ " -neq\n" " open check: if newPath & oldPath's all datas are equal, then return error; \n" " DEFAULT not check equal.\n" - " -d Diff only, do't run patch check, DEFAULT run patch check.\n" + " -d Diff only, don't run patch check, DEFAULT run patch check.\n" " -t Test only, run patch check, patch(oldPath,testDiffFile)==newPath ? \n" " -f Force overwrite, ignore write path already exists;\n" " DEFAULT (no -f) not overwrite and then return error;\n" @@ -856,7 +857,7 @@ static int _checkSetCompress(hdiff_TCompress** out_compressPlugin, #define _kNULL_SIZE (~(size_t)0) #define _THREAD_NUMBER_NULL _kNULL_SIZE -#define _THREAD_NUMBER_DEFUALT kDefaultCompressThreadNumber +#define _THREAD_NUMBER_DEFAULT kDefaultCompressThreadNumber #define _THREAD_NUMBER_MAX (1<<8) int hdiff_cmd_line(int argc, const char * argv[]){ @@ -1126,8 +1127,8 @@ int hdiff_cmd_line(int argc, const char * argv[]){ _options_check((op[2]!='\0'), "-n?"); #if (_IS_NEED_DIR_DIFF_PATCH) if (op[2]=='-'){ - _options_check((kMaxOpenFileNumber == _kNULL_SIZE), "-n-") - const char* pnum = op + 3; + _options_check((kMaxOpenFileNumber == _kNULL_SIZE), "-n-"); + const char* pnum = op + 3; _options_check(kmg_to_size(pnum, strlen(pnum), &kMaxOpenFileNumber), "-n-?"); _options_check((kMaxOpenFileNumber != _kNULL_SIZE), "-n-?"); }else @@ -1272,7 +1273,7 @@ int hdiff_cmd_line(int argc, const char * argv[]){ if (diffSets.isDiffInMem&&(diffSets.matchBlockSize==_kNULL_SIZE)) diffSets.matchBlockSize=kDefaultFastMatchBlockSize; if (diffSets.threadNum==_THREAD_NUMBER_NULL) - diffSets.threadNum=_THREAD_NUMBER_DEFUALT; + diffSets.threadNum=_THREAD_NUMBER_DEFAULT; else if (diffSets.threadNum>_THREAD_NUMBER_MAX) diffSets.threadNum=_THREAD_NUMBER_MAX; else if (diffSets.threadNum<1) diff --git a/hpatchz.c b/hpatchz.c index 3ae059c0..ca9b76cf 100644 --- a/hpatchz.c +++ b/hpatchz.c @@ -183,6 +183,7 @@ static void printUsage(){ printVersion(); printf("\n"); printf("patch usage: hpatchz [options] oldPath diffFile outNewPath\n" + "uncompress usage: hpatchz [options] \"\" diffFile outNewPath\n" "print info: hpatchz -info diffFile\n" #if (_IS_NEED_SFX) "create SFX: hpatchz [-X-exe#selfExecuteFile] diffFile -X#outSelfExtractArchive\n" @@ -234,26 +235,19 @@ static void printUsage(){ #if (_IS_USED_MULTITHREAD) " -p-parallelThreadNumber\n" " if parallelThreadNumber>1 then open multi-thread Parallel mode;\n" - " now only support single compressed diffData(created by hdiffz -SD-stepSize);\n" + " now support window diffData(created by hdiffz -WD) and single compressed diffData(created by hdiffz -SD);\n" " can set 1..5, DEFAULT -p-1!\n" #endif #if ((_IS_NEED_DIR_DIFF_PATCH)||(_IS_NEED_VCDIFF)||(_IS_NEED_WINDOW_DIFF)) " -C-checksumSets\n" - " set Checksum data for window patch & directory patch & VCDIFF patch, DEFAULT -C-new" - #if (_IS_NEED_DIR_DIFF_PATCH) - "-copy" - #endif - ";\n checksumSets support (can choose multiple):\n" + " set Checksum data for window patch & directory patch & VCDIFF patch, DEFAULT -C-new-copy;\n" + " checksumSets support (can choose multiple):\n" " -C-no no checksum;\n" " -C-new checksum new files edited from old reference files;\n" " -C-diff checksum diffFile; (VCDIFF unsupport)\n" " -C-old checksum old reference files; (VCDIFF unsupport)\n" - #if (_IS_NEED_DIR_DIFF_PATCH) " -C-copy checksum new files copy from old same files, for directory patch;\n" " -C-all same as: -C-new-copy-diff-old;\n" - #else - " -C-all same as: -C-new-diff-old;\n" - #endif #endif #if (_IS_NEED_DIR_DIFF_PATCH) " -n-maxOpenFileNumber\n" @@ -359,17 +353,17 @@ typedef enum THPatchResult { #endif int hpatch(const char* oldFileName,const char* diffFileName,const char* outNewFileName, - hpatch_BOOL isLoadOldAll,size_t patchCacheSize,hpatch_StreamPos_t diffDataOffert, + hpatch_BOOL isLoadOldAll,size_t patchCacheSize,hpatch_StreamPos_t diffDataOffset, hpatch_StreamPos_t diffDataSize,TPatchChecksumSet* checksumSet,size_t threadNum); #if (_IS_NEED_DIR_DIFF_PATCH) int hpatch_dir(const char* oldPath,const char* diffFileName,const char* outNewPath, hpatch_BOOL isLoadOldAll,size_t patchCacheSize,size_t kMaxOpenFileNumber, TPatchChecksumSet* checksumSet,IHPatchDirListener* hlistener, - hpatch_StreamPos_t diffDataOffert,hpatch_StreamPos_t diffDataSize,size_t threadNum); + hpatch_StreamPos_t diffDataOffset,hpatch_StreamPos_t diffDataSize,size_t threadNum); #endif #if (_IS_NEED_SFX) int createSfx(const char* selfExecuteFileName,const char* diffFileName,const char* out_sfxFileName); -hpatch_BOOL getDiffDataOffertInSfx(hpatch_StreamPos_t* out_diffDataOffert,hpatch_StreamPos_t* out_diffDataSize); +hpatch_BOOL getDiffDataOffertInSfx(hpatch_StreamPos_t* out_diffDataOffset,hpatch_StreamPos_t* out_diffDataSize); #endif #if (_IS_NEED_MAIN) @@ -443,7 +437,7 @@ static hpatch_BOOL _toChecksumSet(const char* psets,TPatchChecksumSet* checksumS #define _kNULL_SIZE (~(size_t)0) #define _THREAD_NUMBER_NULL _kNULL_SIZE -#define _THREAD_NUMBER_DEFUALT 1 +#define _THREAD_NUMBER_DEFAULT 1 #define _THREAD_NUMBER_MAX 5 #if (_IS_NEED_CMDLINE) @@ -603,16 +597,18 @@ int hpatch_cmd_line(int argc, const char * argv[]){ if (isRunSFX==_kNULL_VALUE) isRunSFX=hpatch_FALSE; if (threadNum==_THREAD_NUMBER_NULL) - threadNum=_THREAD_NUMBER_DEFUALT; + threadNum=_THREAD_NUMBER_DEFAULT; + if (threadNum>_THREAD_NUMBER_MAX) + threadNum=_THREAD_NUMBER_MAX; #if (_IS_NEED_MAIN && _IS_USED_MULTITHREAD) if (threadNum>1) _parallel_import_c_on_error=_on_mt_error; #endif #if (_IS_NEED_SFX) if ((argc<=1)&&(!isRunSFX)){ - hpatch_StreamPos_t _diffDataOffert=0; + hpatch_StreamPos_t _diffDataOffset=0; hpatch_StreamPos_t _diffDataSize=0; - if (getDiffDataOffertInSfx(&_diffDataOffert,&_diffDataSize)){//autoExtractSFX + if (getDiffDataOffertInSfx(&_diffDataOffset,&_diffDataSize)){//autoExtractSFX isForceOverwrite=hpatch_TRUE; isRunSFX=hpatch_TRUE; } @@ -688,12 +684,12 @@ int hpatch_cmd_line(int argc, const char * argv[]){ hpatch_BOOL isOutDir; #endif hpatch_BOOL isSamePath; - hpatch_StreamPos_t diffDataOffert=0; + hpatch_StreamPos_t diffDataOffset=0; hpatch_StreamPos_t diffDataSize=0; #if (_IS_NEED_SFX) if (isRunSFX){ printf("run as SFX mode!\n"); - _return_check(getDiffDataOffertInSfx(&diffDataOffert,&diffDataSize), + _return_check(getDiffDataOffertInSfx(&diffDataOffset,&diffDataSize), HPATCH_RUN_SFX_NOTSFX_ERROR,"not found diff data in selfExecuteFile"); diffFileName=argv[0];//selfExecuteFileName if (arg_values_size==0){//autoExtractSFX @@ -725,7 +721,7 @@ int hpatch_cmd_line(int argc, const char * argv[]){ HPATCH_PATHTYPE_ERROR,"outNewPath already exists, overwrite"); } #if (_IS_NEED_DIR_DIFF_PATCH) - _return_check(getDirDiffInfoByFile(&dirDiffInfo,diffFileName,diffDataOffert,diffDataSize), + _return_check(getDirDiffInfoByFile(&dirDiffInfo,diffFileName,diffDataOffset,diffDataSize), HPATCH_OPENREAD_ERROR,"input diffFile open read"); isOutDir=(dirDiffInfo.isDirDiff)&&(dirDiffInfo.newPathIsDir); #if (_IS_NEED_SFX) @@ -740,12 +736,12 @@ int hpatch_cmd_line(int argc, const char * argv[]){ #if (_IS_NEED_DIR_DIFF_PATCH) if (dirDiffInfo.isDirDiff){ return hpatch_dir(oldPath,diffFileName,outNewPath,isLoadOldAll,patchCacheSize,kMaxOpenFileNumber, - &checksumSet,&defaultPatchDirlistener,diffDataOffert,diffDataSize,threadNum); + &checksumSet,&defaultPatchDirlistener,diffDataOffset,diffDataSize,threadNum); }else #endif { return hpatch(oldPath,diffFileName,outNewPath,isLoadOldAll,patchCacheSize, - diffDataOffert,diffDataSize,&checksumSet,threadNum); + diffDataOffset,diffDataSize,&checksumSet,threadNum); } }else #if (_IS_NEED_DIR_DIFF_PATCH) @@ -769,12 +765,12 @@ int hpatch_cmd_line(int argc, const char * argv[]){ if (dirDiffInfo.isDirDiff){ result=hpatch_dir(oldPath,diffFileName,newTempName,isLoadOldAll,patchCacheSize, kMaxOpenFileNumber,&checksumSet,&defaultPatchDirlistener, - diffDataOffert,diffDataSize,threadNum); + diffDataOffset,diffDataSize,threadNum); }else #endif { result=hpatch(oldPath,diffFileName,newTempName,isLoadOldAll,patchCacheSize, - diffDataOffert,diffDataSize,&checksumSet,threadNum); + diffDataOffset,diffDataSize,&checksumSet,threadNum); } if (result==HPATCH_SUCCESS){ _return_check(hpatch_removeFile(oldPath), @@ -801,7 +797,7 @@ int hpatch_cmd_line(int argc, const char * argv[]){ HPATCH_TEMPPATH_ERROR,"getTempPathName(outNewPath)"); printf("NOTE: all in outNewPath temp directory will be move to oldDirectory after patch!\n"); result=hpatch_dir(oldPath,diffFileName,newTempDir,isLoadOldAll,patchCacheSize,kMaxOpenFileNumber, - &checksumSet,&tempDirPatchListener,diffDataOffert,diffDataSize,threadNum); + &checksumSet,&tempDirPatchListener,diffDataOffset,diffDataSize,threadNum); if (result==HPATCH_SUCCESS){ printf("all in outNewPath temp directory moved to oldDirectory!\n"); }else if(!hpatch_isPathNotExist(newTempDir)){ @@ -1359,7 +1355,7 @@ static TByte* allocPatchMemCache(hpatch_StreamPos_t kMinCacheSize,hpatch_StreamP #endif //_IS_NEED_PRINT_PROGRESS int hpatch(const char* oldFileName,const char* diffFileName,const char* outNewFileName, - hpatch_BOOL isLoadOldAll,size_t patchCacheSize,hpatch_StreamPos_t diffDataOffert, + hpatch_BOOL isLoadOldAll,size_t patchCacheSize,hpatch_StreamPos_t diffDataOffset, hpatch_StreamPos_t diffDataSize,TPatchChecksumSet* checksumSet,size_t threadNum){ int result=HPATCH_SUCCESS; int _isInClear=hpatch_FALSE; @@ -1394,8 +1390,8 @@ int hpatch(const char* oldFileName,const char* diffFileName,const char* outNewFi check(hpatch_TFileStreamInput_open(&diffData,diffFileName), HPATCH_OPENREAD_ERROR,"open diffFile for read"); #if (_IS_NEED_SFX) - if (diffDataOffert>0){ //run sfx - check(hpatch_TFileStreamInput_setOffset(&diffData,diffDataOffert), + if (diffDataOffset>0){ //run sfx + check(hpatch_TFileStreamInput_setOffset(&diffData,diffDataOffset), HPATCH_RUN_SFX_DIFFOFFSERT_ERROR,"readed sfx diffFile offset"); check(diffData.base.streamSize>=diffDataSize, HPATCH_RUN_SFX_DIFFOFFSERT_ERROR,"readed sfx diffFile size"); @@ -1544,7 +1540,7 @@ int hpatch(const char* oldFileName,const char* diffFileName,const char* outNewFi int hpatch_dir(const char* oldPath,const char* diffFileName,const char* outNewPath, hpatch_BOOL isLoadOldAll,size_t patchCacheSize,size_t kMaxOpenFileNumber, TPatchChecksumSet* checksumSet,IHPatchDirListener* hlistener, - hpatch_StreamPos_t diffDataOffert,hpatch_StreamPos_t diffDataSize,size_t threadNum){ + hpatch_StreamPos_t diffDataOffset,hpatch_StreamPos_t diffDataSize,size_t threadNum){ int result=HPATCH_SUCCESS; int _isInClear=hpatch_FALSE; double time0=clock_s(); @@ -1574,8 +1570,8 @@ int hpatch_dir(const char* oldPath,const char* diffFileName,const char* outNewPa } check(hpatch_TFileStreamInput_open(&diffData,diffFileName),HPATCH_OPENREAD_ERROR,"open diffFile for read"); #if (_IS_NEED_SFX) - if (diffDataOffert>0){ //run sfx - check(hpatch_TFileStreamInput_setOffset(&diffData,diffDataOffert), + if (diffDataOffset>0){ //run sfx + check(hpatch_TFileStreamInput_setOffset(&diffData,diffDataOffset), HPATCH_RUN_SFX_DIFFOFFSERT_ERROR,"readed sfx diffFile offset"); check(diffData.base.streamSize>=diffDataSize, HPATCH_RUN_SFX_DIFFOFFSERT_ERROR,"readed sfx diffFile size"); @@ -1719,7 +1715,7 @@ TByte _sfx_guid_node[_sfx_guid_node_size]={ 0x4a,0x5d, 0xa9,0xd5, 0x73,0x03,0xa8,0x2f,0xd0,0x8e, - 0xff,0xff,0xff,0xff, // saved diffDataOffert , selfExecute fileSize < 4GB + 0xff,0xff,0xff,0xff, // saved diffDataOffset , selfExecute fileSize < 4GB 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; // diffDataSize static TByte* _search(TByte* src,TByte* src_end,const TByte* sub,const TByte* sub_end){ @@ -1759,7 +1755,7 @@ static int createSfx_notCheckDiffFile_byStream(const hpatch_TStreamInput* selfE TByte* pmem=0; hpatch_StreamPos_t writePos=0; hpatch_BOOL isFoundGuid=hpatch_FALSE; - const hpatch_StreamPos_t diffDataOffert=selfExecute->streamSize; + const hpatch_StreamPos_t diffDataOffset=selfExecute->streamSize; const hpatch_StreamPos_t diffDataSize=diffData->streamSize; {//mem pmem=(TByte*)malloc(_sfx_guid_node_size+hpatch_kFileIOBufBetterSize); @@ -1791,7 +1787,7 @@ static int createSfx_notCheckDiffFile_byStream(const hpatch_TStreamInput* selfE for (i=0; i>(8*i)); + pos[di]=(TByte)(diffDataOffset>>(8*i)); } for (i=0; istreamSize; @@ -1905,7 +1901,7 @@ int createSfx(const char* selfExecuteFileName,const char* diffFileName,const cha return result; } -hpatch_BOOL getDiffDataOffertInSfx(hpatch_StreamPos_t* out_diffDataOffert,hpatch_StreamPos_t* out_diffDataSize){ +hpatch_BOOL getDiffDataOffertInSfx(hpatch_StreamPos_t* out_diffDataOffset,hpatch_StreamPos_t* out_diffDataSize){ hpatch_uint32_t diffOff=0; hpatch_uint64_t diffSize=0; size_t i; @@ -1922,7 +1918,7 @@ hpatch_BOOL getDiffDataOffertInSfx(hpatch_StreamPos_t* out_diffDataOffert,hpatch } if (diffSize==(~(hpatch_uint64_t)0)) return hpatch_FALSE; - if (out_diffDataOffert) *out_diffDataOffert=diffOff; + if (out_diffDataOffset) *out_diffDataOffset=diffOff; if (out_diffDataSize) *out_diffDataSize=diffSize; return hpatch_TRUE; } diff --git a/libHDiffPatch/HDiff/diff.h b/libHDiffPatch/HDiff/diff.h index 58a35506..627e025d 100644 --- a/libHDiffPatch/HDiff/diff.h +++ b/libHDiffPatch/HDiff/diff.h @@ -38,9 +38,9 @@ static const int kMinSingleMatchScore_default = 4; // out_diff is uncompressed, you can use create_compressed_diff() // or create_single_compressed_diff() create compressed diff data // kMinSingleMatchScore: default 4, bin: 0--4 text: 4--9 -// isUseBigCacheMatch: big cache max used O(oldSize) memory, match speed faster, but build big cache slow +// isUseBigCacheMatch: big cache uses up to O(oldSize) memory, match speed is faster, but building the big cache is slow // NOTE: create_diff() + patch() or patch_stream() or patch_stream_with_cache() is DEPRECATED, -// recommend change to use create_single_compressed_diff() + patch_single_stream() or patch_single_compressed_diff() +// recommend changing to use create_single_compressed_diff() + patch_single_stream() or patch_single_compressed_diff() void create_diff(const unsigned char* newData,const unsigned char* newData_end, const unsigned char* oldData,const unsigned char* oldData_end, std::vector& out_diff, @@ -60,9 +60,9 @@ bool check_diff(const hpatch_TStreamInput* newData, //create a compressed diff data between oldData and newData // out_diff compressed by compressPlugin -// recommended always use create_single_compressed_diff() replace create_compressed_diff() +// recommended to always use create_single_compressed_diff() to replace create_compressed_diff() // kMinSingleMatchScore: default 4, bin: 0--4 text: 4--9 -// isUseBigCacheMatch: big cache max used O(oldSize) memory, match speed faster, but build big cache slow +// isUseBigCacheMatch: big cache uses up to O(oldSize) memory, match speed is faster, but building the big cache is slow void create_compressed_diff(const unsigned char* newData,const unsigned char* newData_end, const unsigned char* oldData,const unsigned char* oldData_end, std::vector& out_diff, @@ -77,12 +77,12 @@ void create_compressed_diff(const unsigned char* newData,const unsigned char* ne bool isUseBigCacheMatch=false,size_t threadNum=1); //create a compressed diff data by stream: -// can control memory requires and run speed by different kMatchBlockSize value, +// can control memory requirements and run speed via different kMatchBlockSize values, // but out_diff size is larger than create_compressed_diff() -// recommended used in limited environment or support large file -// recommended always use create_single_compressed_diff_stream() replace create_compressed_diff_stream() +// recommended for use in memory-limited environments or for large files +// recommended to always use create_single_compressed_diff_stream() to replace create_compressed_diff_stream() // kMatchBlockSize: recommended (1<<4)--(1<<14) -// if increase kMatchBlockSize then run faster and require less memory, but out_diff size increase +// increasing kMatchBlockSize runs faster and uses less memory, but increases out_diff size // NOTICE: out_diff->write()'s writeToPos may be back to update headData! // throw std::runtime_error when I/O error,etc. static const size_t kMatchBlockSize_default = (1<<6); @@ -105,7 +105,7 @@ static const size_t kDefaultSegRatioInWindowOldSize = 64; // default segSize=kOl //create a compressed diff data by window mode: // optimize the access speed of old data when patch // kOldWindowSize: max window bytes on old data; -// kSegSize: initial data granularity in a window matching, if set 0 mean used default; +// kSegSize: initial data granularity in a window matching, if set to 0, the default is used; // throw std::runtime_error when I/O error or kSegSize too large,etc. void create_compressed_diff_window(const hpatch_TStreamInput* newData,const hpatch_TStreamInput* oldData, const hpatch_TStreamOutput* out_diff, @@ -143,7 +143,7 @@ static const size_t kDefaultPatchStepMemSize =1024*256; //create a diff data between oldData and newData, the diffData saved as single compressed stream // kMinSingleMatchScore: default 4, bin: 0--4 text: 4--9 // patchStepMemSize>=hpatch_kStreamCacheSize, default 256k, recommended 64k,2m etc... -// isUseBigCacheMatch: big cache max used O(oldSize) memory, match speed faster, but build big cache slow +// isUseBigCacheMatch: big cache uses up to O(oldSize) memory, match speed is faster, but building the big cache is slow void create_single_compressed_diff(const unsigned char* newData,const unsigned char* newData_end, const unsigned char* oldData,const unsigned char* oldData_end, std::vector& out_diff,const hdiff_TCompress* compressPlugin=0, @@ -157,11 +157,11 @@ void create_single_compressed_diff(const unsigned char* newData,const unsigned c int kMinSingleMatchScore=kMinSingleMatchScore_default, bool isUseBigCacheMatch=false,size_t threadNum=1); //create single compressed diff data by stream: -// can control memory requires and run speed by different kMatchBlockSize value, +// can control memory requirements and run speed via different kMatchBlockSize values, // but out_diff size is larger than create_single_compressed_diff() -// recommended used in limited environment or support large file +// recommended for use in memory-limited environments or for large files // kMatchBlockSize: recommended (1<<4)--(1<<14) -// if increase kMatchBlockSize then run faster and require less memory, but out_diff size increase +// increasing kMatchBlockSize runs faster and uses less memory, but increases out_diff size // NOTICE: out_diff->write()'s writeToPos may be back to update headData! // throw std::runtime_error when I/O error,etc. void create_single_compressed_diff_stream(const hpatch_TStreamInput* newData, @@ -175,7 +175,7 @@ void create_single_compressed_diff_stream(const hpatch_TStreamInput* newData, //create single compressed diff data by window mode: // optimize the access speed of old data when patch // kOldWindowSize: max window bytes on old data; -// kSegSize: initial data granularity during window matching, if set 0 mean used default; +// kSegSize: initial data granularity during window matching, if set to 0, the default is used; // throw std::runtime_error when I/O error or kSegSize too large,etc. void create_single_compressed_diff_window(const hpatch_TStreamInput* newData,const hpatch_TStreamInput* oldData, const hpatch_TStreamOutput* out_diff, @@ -265,9 +265,9 @@ void create_single_compressed_diff_block(unsigned char* newData,unsigned char* n // if (kMatchBlockSize==0) diff by sstring, else diff by stream(for large file) // kOldWindowSize: max window bytes on old data; // requires kOldWindowSize + patchStepMemSize + (I/O cache memory) when patch; -// kSegSize: initial data granularity in a window matching, if set 0 mean used default; +// kSegSize: initial data granularity in a window matching, if set to 0, the default is used; // recommended kOldWindowSize/128<=kSegSize<=kOldWindowSize/4; -// kBigCoverSize: skip big cover when rematching in window, for optimize diff speed; +// kBigCoverSize: skip big covers when rematching in a window, for optimizing diff speed; // NOTICE: out_diff->write()'s writeToPos may be back to update headData! // throw std::runtime_error when I/O error or kSegSize too large,etc. void create_window_diff(const hpatch_TStreamInput* newData,const hpatch_TStreamInput* oldData, @@ -296,7 +296,7 @@ hpatch_StreamPos_t resave_window_diff(const hpatch_TStreamInput* in_diff, //same as create?compressed_diff_stream(), but not serialize diffData, only got covers -// now isExtendCover always false,so not need pass isExtendCover +// now isExtendCover is always false, so it does not need to be passed void get_match_covers_by_stream(const hpatch_TStreamInput* newData,const hpatch_TStreamInput* oldData, std::vector& out_covers,size_t kMatchBlockSize=kMatchBlockSize_default, const hdiff_TMTSets_s* mtsets=0); @@ -356,7 +356,7 @@ void get_match_covers_in_a_window(const hpatch_TStreamInput* newData,const hpatc //covers type TInputCovers, can pass std::vector -// if (!isExtendCover), not read oldStream's data, only used oldStream->streamSize +// if (!isExtendCover), does not read oldStream's data, only uses oldStream->streamSize void serialize_compressed_diff(const hpatch_TStreamInput* newData,const hpatch_TStreamInput* oldData, const TInputCovers& covers,const hpatch_TStreamOutput* out_diff, const hdiff_TCompress* compressPlugin,bool isExtendCover); diff --git a/libHDiffPatch/HPatch/patch.h b/libHDiffPatch/HPatch/patch.h index 2fb14e2c..825d5368 100644 --- a/libHDiffPatch/HPatch/patch.h +++ b/libHDiffPatch/HPatch/patch.h @@ -98,8 +98,8 @@ hpatch_inline static hpatch_BOOL //patch with decompress plugin // used (hpatch_kStreamCacheSize*6 stack memory) + (decompress buffer*4) // compressedDiff create by create_compressed_diff() or create_compressed_diff_stream() -// decompressPlugin can null when no compressed data in compressedDiff -// if use patch_decompress_with_cache(), can passing larger memory cache to optimize speed +// decompressPlugin can be null when there is no compressed data in compressedDiff +// if using patch_decompress_with_cache(), a larger memory cache can be passed to optimize speed hpatch_BOOL patch_decompress(const hpatch_TStreamOutput* out_newData, //sequential write const hpatch_TStreamInput* oldData, //random read const hpatch_TStreamInput* compressedDiff, //random read @@ -162,7 +162,7 @@ hpatch_BOOL hpatch_coverList_close(hpatch_TCoverList* coverList) { // every byte in singleCompressedDiff will only be read once in order // singleCompressedDiff create by create_single_compressed_diff() or create_single_compressed_diff_stream() or create_hdiff_by_sign() // you can download&patch diffData at the same time, without saving it to disk -// same as call getSingleCompressedDiffInfo() + listener->onDiffInfo() + patch_single_compressed_diff() +// same as calling getSingleCompressedDiffInfo() + listener->onDiffInfo() + patch_single_compressed_diff() static hpatch_force_inline hpatch_BOOL patch_single_stream(sspatch_listener_t* listener, //call back when got diffInfo const hpatch_TStreamOutput* out_newData, //sequential write @@ -212,8 +212,8 @@ hpatch_BOOL getSingleCompressedDiffInfo_mem(hpatch_singleCompressedDiffInfo* out // note: (I/O cache memory) >= hpatch_kStreamCacheSize*3 // temp_cache_end-temp_cache == stepMemSize + (I/O cache memory) // singleCompressedDiff create by create_single_compressed_diff() or create_single_compressed_diff_stream() or create_hdiff_by_sign() -// decompressPlugin can null when no compressed data in singleCompressedDiff -// same as call compressed_stream_as_uncompressed() + patch_single_stream_diff() +// decompressPlugin can be null when there is no compressed data in singleCompressedDiff +// same as calling compressed_stream_as_uncompressed() + patch_single_stream_diff() static hpatch_force_inline hpatch_BOOL patch_single_compressed_diff(const hpatch_TStreamOutput* out_newData, //sequential write const hpatch_TStreamInput* oldData, //random read diff --git a/libHDiffPatch/HPatch/patch_types.h b/libHDiffPatch/HPatch/patch_types.h index d2dc4996..25cf53ac 100644 --- a/libHDiffPatch/HPatch/patch_types.h +++ b/libHDiffPatch/HPatch/patch_types.h @@ -186,7 +186,7 @@ static hpatch_force_inline hpatch_StreamPos_t _hpatch_pos_max(hpatch_StreamPos_t //default once I/O (read/write) byte size #ifndef hpatch_kStreamCacheSize - # define hpatch_kStreamCacheSize (1024*4) + # define hpatch_kStreamCacheSize 4096 #endif #ifndef hpatch_kFileIOBufBetterSize # define hpatch_kFileIOBufBetterSize (1024*64) @@ -207,7 +207,7 @@ static hpatch_force_inline hpatch_StreamPos_t _hpatch_pos_max(hpatch_StreamPos_t typedef struct hpatch_compressedDiffInfo{ hpatch_StreamPos_t newDataSize; hpatch_StreamPos_t oldDataSize; - hpatch_uint compressedCount;//need open hpatch_decompressHandle number + hpatch_uint compressedCount;//number of decompress handles that must be opened simultaneously char compressType[hpatch_kMaxPluginTypeLength+1]; //ascii cstring } hpatch_compressedDiffInfo; @@ -220,7 +220,7 @@ static hpatch_force_inline hpatch_StreamPos_t _hpatch_pos_max(hpatch_StreamPos_t hpatch_dec_close_error, } hpatch_dec_error_t; typedef struct hpatch_TDecompress{ - hpatch_BOOL (*is_can_open)(const char* compresseType); + hpatch_BOOL (*is_can_open)(const char* compressType); //error return 0. hpatch_decompressHandle (*open)(struct hpatch_TDecompress* decompressPlugin, hpatch_StreamPos_t dataSize, @@ -238,7 +238,7 @@ static hpatch_force_inline hpatch_StreamPos_t _hpatch_pos_max(hpatch_StreamPos_t const struct hpatch_TStreamInput* codeStream, hpatch_StreamPos_t code_begin, hpatch_StreamPos_t code_end); - volatile hpatch_dec_error_t decError; //if you used decError value, once patch must used it's own hpatch_TDecompress + volatile hpatch_dec_error_t decError; //if decError is read, each patch session must use its own hpatch_TDecompress instance } hpatch_TDecompress; #define _hpatch_update_decError(decompressPlugin,errorCode) \ do { if ((decompressPlugin)->decError==hpatch_dec_ok) \ @@ -338,7 +338,7 @@ static hpatch_force_inline hpatch_StreamPos_t _hpatch_pos_max(hpatch_StreamPos_t typedef struct sspatch_coversListener_t{ void* import; - void (*onStepCoversReset)(struct sspatch_coversListener_t* listener,hpatch_StreamPos_t leaveCoverCount);//can NULL, data(in covers_cache) will invalid; if leaveCoverCount==0, step finish + void (*onStepCoversReset)(struct sspatch_coversListener_t* listener,hpatch_StreamPos_t leaveCoverCount);//can be NULL; data in covers_cache will become invalid; if leaveCoverCount==0, the step is finished void (*onStepCovers)(struct sspatch_coversListener_t* listener, const unsigned char* covers_cache,const unsigned char* covers_cacheEnd);//if covers_cache==covers_cacheEnd==0, step finish } sspatch_coversListener_t; @@ -382,7 +382,8 @@ static hpatch_force_inline hpatch_StreamPos_t _hpatch_pos_max(hpatch_StreamPos_t hpatch_StreamPos_t compressedSize; //0 uncompressed, >0 compressed hpatch_StreamPos_t otherInfoPos; hpatch_StreamPos_t otherInfoEndPos; - hpatch_StreamPos_t windowDataPos; //window data begin pos; old,new,diff's checksum begin pos=windowDataPos-3*checksumByteSize + hpatch_StreamPos_t windowDataPos; //window data begin pos(compressed data begin pos); + //the checksum section for old/new/diff data begin pos = windowDataPos-3*checksumByteSize; hpatch_StreamPos_t _headFixedInfoPos; char compressType[hpatch_kMaxPluginTypeLength+1]; char checksumType[hpatch_kMaxPluginTypeLength+1]; From 0db8045964b9a685f002ddb5f90b146d6b793fdd Mon Sep 17 00:00:00 2001 From: sisong Date: Wed, 1 Jul 2026 13:59:19 +0800 Subject: [PATCH 7/7] fix CI build; --- Makefile | 25 +++++++++++-------- .../xcode/unitTest.xcodeproj/project.pbxproj | 16 ++++++++++++ test/unit_test.cpp | 14 +++++++++++ 3 files changed, 44 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 213a0936..276c8594 100644 --- a/Makefile +++ b/Makefile @@ -290,6 +290,19 @@ else CXXFLAGS += -fvisibility-inlines-hidden endif +ifeq ($(BSD),0) + DEF_FLAGS += -D_IS_NEED_BSDIFF=0 +else + DEF_FLAGS += -D_IS_NEED_BSDIFF=1 +endif +ifeq ($(VCD),0) + DEF_FLAGS += -D_IS_NEED_VCDIFF=0 +else + DEF_FLAGS += -D_IS_NEED_VCDIFF=1 +endif + +UTEST_FLAGS := $(DEF_FLAGS) + ifeq ($(BZIP2),0) else DEF_FLAGS += -D_CompressPlugin_bz2 @@ -335,16 +348,6 @@ else DEF_FLAGS += -D_ChecksumPlugin_xxh3 -D_ChecksumPlugin_xxh128 -I$(XXH_PATH) endif endif -ifeq ($(BSD),0) - DEF_FLAGS += -D_IS_NEED_BSDIFF=0 -else - DEF_FLAGS += -D_IS_NEED_BSDIFF=1 -endif -ifeq ($(VCD),0) - DEF_FLAGS += -D_IS_NEED_VCDIFF=0 -else - DEF_FLAGS += -D_IS_NEED_VCDIFF=1 -endif ifeq ($(LZMA),0) else DEF_FLAGS += -D_CompressPlugin_lzma -D_CompressPlugin_lzma2 @@ -446,7 +449,7 @@ hpatchz: $(HPATCH_OBJ) hdiffz: libhdiffpatch.a $(CXX) hdiffz.cpp libhdiffpatch.a $(CXXFLAGS) $(DIFF_LINK) -o hdiffz unit_test: libhdiffpatch.a - $(CXX) ./test/unit_test.cpp libhdiffpatch.a $(DIFF_LINK) -o unit_test + $(CXX) ./test/unit_test.cpp libhdiffpatch.a $(UTEST_FLAGS) $(DIFF_LINK) -o unit_test ifeq ($(OS),Windows_NT) # mingw? RM := del /Q /F diff --git a/builds/xcode/unitTest.xcodeproj/project.pbxproj b/builds/xcode/unitTest.xcodeproj/project.pbxproj index f7d89299..dc504dcc 100644 --- a/builds/xcode/unitTest.xcodeproj/project.pbxproj +++ b/builds/xcode/unitTest.xcodeproj/project.pbxproj @@ -21,6 +21,10 @@ 0D99CCBC2FD6CF0E005CC92A /* window_matcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0D99CCB92FD6CF0E005CC92A /* window_matcher.cpp */; }; 0D99CCBD2FD6CF0E005CC92A /* covers_range.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0D99CCBA2FD6CF0E005CC92A /* covers_range.cpp */; }; 0D99CCC42FE9004E005CC92A /* _hcache_window_old_mt.c in Sources */ = {isa = PBXBuildFile; fileRef = 0D99CCBF2FE8FD4D005CC92A /* _hcache_window_old_mt.c */; }; + 0D99CCF02FF4CE4B005CC92A /* bsdiff_wrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0D99CCEE2FF4CE4B005CC92A /* bsdiff_wrapper.cpp */; }; + 0D99CCF12FF4CE4B005CC92A /* bspatch_wrapper.c in Sources */ = {isa = PBXBuildFile; fileRef = 0D99CCEF2FF4CE4B005CC92A /* bspatch_wrapper.c */; }; + 0D99CCF42FF4CE5C005CC92A /* vcdiff_wrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0D99CCF22FF4CE5C005CC92A /* vcdiff_wrapper.cpp */; }; + 0D99CCF52FF4CE5C005CC92A /* vcpatch_wrapper.c in Sources */ = {isa = PBXBuildFile; fileRef = 0D99CCF32FF4CE5C005CC92A /* vcpatch_wrapper.c */; }; 0DA686642E536CB4002A6651 /* _hpatch_mt.c in Sources */ = {isa = PBXBuildFile; fileRef = 0DA686352E536964002A6651 /* _hpatch_mt.c */; }; 0DA686652E536CB4002A6651 /* hpatch_mt.c in Sources */ = {isa = PBXBuildFile; fileRef = 0DA686372E536964002A6651 /* hpatch_mt.c */; }; 0DA686662E536CB4002A6651 /* _houtput_mt.c in Sources */ = {isa = PBXBuildFile; fileRef = 0DA686382E536964002A6651 /* _houtput_mt.c */; }; @@ -92,6 +96,10 @@ 0D99CCBA2FD6CF0E005CC92A /* covers_range.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = covers_range.cpp; sourceTree = ""; }; 0D99CCBE2FE8FD3E005CC92A /* _hcache_window_old_mt.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _hcache_window_old_mt.h; sourceTree = ""; }; 0D99CCBF2FE8FD4D005CC92A /* _hcache_window_old_mt.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = _hcache_window_old_mt.c; sourceTree = ""; }; + 0D99CCEE2FF4CE4B005CC92A /* bsdiff_wrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bsdiff_wrapper.cpp; path = ../../bsdiff_wrapper/bsdiff_wrapper.cpp; sourceTree = ""; }; + 0D99CCEF2FF4CE4B005CC92A /* bspatch_wrapper.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bspatch_wrapper.c; path = ../../bsdiff_wrapper/bspatch_wrapper.c; sourceTree = ""; }; + 0D99CCF22FF4CE5C005CC92A /* vcdiff_wrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = vcdiff_wrapper.cpp; path = ../../vcdiff_wrapper/vcdiff_wrapper.cpp; sourceTree = ""; }; + 0D99CCF32FF4CE5C005CC92A /* vcpatch_wrapper.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vcpatch_wrapper.c; path = ../../vcdiff_wrapper/vcpatch_wrapper.c; sourceTree = ""; }; 0DA686352E536964002A6651 /* _hpatch_mt.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = _hpatch_mt.c; sourceTree = ""; }; 0DA686362E536964002A6651 /* _hinput_mt.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _hinput_mt.h; sourceTree = ""; }; 0DA686372E536964002A6651 /* hpatch_mt.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = hpatch_mt.c; sourceTree = ""; }; @@ -206,6 +214,10 @@ 0D3D964129FD3C5E00B37681 /* hdiffpatch */ = { isa = PBXGroup; children = ( + 0D99CCF22FF4CE5C005CC92A /* vcdiff_wrapper.cpp */, + 0D99CCF32FF4CE5C005CC92A /* vcpatch_wrapper.c */, + 0D99CCEE2FF4CE4B005CC92A /* bsdiff_wrapper.cpp */, + 0D99CCEF2FF4CE4B005CC92A /* bspatch_wrapper.c */, 0D3D964629FD3CC100B37681 /* dir_diff_tools.cpp */, 0D3D964229FD3C7F00B37681 /* file_for_patch.c */, ); @@ -434,9 +446,11 @@ 0D99CCC42FE9004E005CC92A /* _hcache_window_old_mt.c in Sources */, 0D99CCBD2FD6CF0E005CC92A /* covers_range.cpp in Sources */, 0DA686642E536CB4002A6651 /* _hpatch_mt.c in Sources */, + 0D99CCF52FF4CE5C005CC92A /* vcpatch_wrapper.c in Sources */, 0DA686652E536CB4002A6651 /* hpatch_mt.c in Sources */, 0DA686662E536CB4002A6651 /* _houtput_mt.c in Sources */, 0DA686672E536CB4002A6651 /* _hcache_old_mt.c in Sources */, + 0D99CCF12FF4CE4B005CC92A /* bspatch_wrapper.c in Sources */, 0DA686682E536CB4002A6651 /* _hinput_mt.c in Sources */, 0D99CC8F2E9A611E005CC92A /* match_block.cpp in Sources */, 0D3D963E29FD3C1000B37681 /* match_in_new.cpp in Sources */, @@ -447,6 +461,7 @@ 0D3D964029FD3C1000B37681 /* sync_make.cpp in Sources */, D6BD9BB017578491004886DE /* bytes_rle.cpp in Sources */, 0DD93B1428F16B010097699C /* parallel_channel.cpp in Sources */, + 0D99CCF42FF4CE5C005CC92A /* vcdiff_wrapper.cpp in Sources */, 0D3D963C29FD3C1000B37681 /* sync_info_client.cpp in Sources */, 0D3D964729FD3CC100B37681 /* dir_diff_tools.cpp in Sources */, 0DE343BB2DF807230000234B /* match_inplace.cpp in Sources */, @@ -464,6 +479,7 @@ 0D3D964329FD3C7F00B37681 /* file_for_patch.c in Sources */, 0D99CCBC2FD6CF0E005CC92A /* window_matcher.cpp in Sources */, 0D3D963A29FD3C1000B37681 /* sync_client.cpp in Sources */, + 0D99CCF02FF4CE4B005CC92A /* bsdiff_wrapper.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/test/unit_test.cpp b/test/unit_test.cpp index 698229a8..0d7e3e61 100644 --- a/test/unit_test.cpp +++ b/test/unit_test.cpp @@ -75,6 +75,12 @@ enum TDiffType{ static const hpatch_byte g_testControl[kDiffTypeCount]={ 1, 1,1, 1,1, 1,1, 1, 1, 1,1, 1,1 }; //static const hpatch_byte g_testControl[kDiffTypeCount]={ 0, 0,0, 0,0, 0,0, 0, 0, 0,0, 0,0 }; +#ifndef _IS_NEED_BSDIFF +# define _IS_NEED_BSDIFF 1 +#endif +#ifndef _IS_NEED_VCDIFF +# define _IS_NEED_VCDIFF 1 +#endif //===== select compress plugin ===== #define _CompressPlugin_no @@ -602,6 +608,7 @@ long _attackPacth(TByte* out_newData,TByte* out_newData_end, mem_as_hStreamInput(&diffStream,diffData,diffData_end); patch_window_diff(&listener,&out_newStream,&oldStream,&diffStream,0,patch_threadNum); } break; +#if (_IS_NEED_VCDIFF) case kDiffV: case kDiffVs: { struct hpatch_TStreamOutput out_newStream; struct hpatch_TStreamInput oldStream; @@ -612,6 +619,8 @@ long _attackPacth(TByte* out_newData,TByte* out_newData_end, vcpatch_with_cache(&out_newStream,&oldStream,&diffStream,decompressPlugin,hpatch_FALSE, _temp_cache.data(),_temp_cache.data()+_temp_cache.size()); } break; +#endif +#if (_IS_NEED_BSDIFF) case kDiffB: case kDiffBs: { struct hpatch_TStreamOutput out_newStream; struct hpatch_TStreamInput oldStream; @@ -622,6 +631,7 @@ long _attackPacth(TByte* out_newData,TByte* out_newData_end, bspatch_with_cache(&out_newStream,&oldStream,&diffStream,decompressPlugin, _temp_cache.data(),_temp_cache.data()+_temp_cache.size()); } break; +#endif } return 0; } @@ -850,6 +860,7 @@ long test(const TByte* newData,const TByte* newData_end, #endif } } +#if (_IS_NEED_VCDIFF) if (g_testControl[kDiffV]){//test vcdiff std::vector diffData; TVectorAsStreamOutput out_diffStream(diffData); @@ -891,6 +902,8 @@ long test(const TByte* newData,const TByte* newData_end, #endif } } +#endif //_IS_NEED_VCDIFF +#if (_IS_NEED_BSDIFF) if (g_testControl[kDiffB]){//test bsdiff std::vector diffData; TVectorAsStreamOutput out_diffStream(diffData); @@ -949,6 +962,7 @@ long test(const TByte* newData,const TByte* newData_end, #endif } } +#endif //_IS_NEED_BSDIFF printf("\n"); return result; }