본문 바로가기
Study/API

MSPatcha.dll MSPatchc.dll #MSPatch 업데이트 활용

by 뿡뿡대마왕 2017. 1. 3.
반응형


대용량의 파일들을 서버에서 관리해야 하는 일들이 있다.


근데 그 파일들의 사이즈는 GB는 아니지만 갯수가 MB단위로 하루에 GB이상씩 전달해야 하는 상황이다.


즉 서버에서는 하루에 엄청나게 많은 파일들과 엄청난 하드디스크 용량을 차지하는 case가 발생하게 되었다.


수집되는 데이터는 어느 정도 동일성을 갖는 데이터 이다.


이것에 대한 처리는 어떻게 하면 될가?


회의도 해보고 내머리로 짱구도 굴려봤지만..딱히 시원한 답은 없는 상황~..-_-;


하지만 선배가 어쩌면 해결이 될지 모르는 기가막힌 해결책을 제시했다. +.+


MSPatch 를 이용해보자.


난 그게 뭥가용?? 먹는건가용?


내가 글을 읽어보니 큰 그림은 대략 이렇다. 


패치시에 변경된 파일을 통으로 바꾸는게 아니라. 


두 파일간 diff하여 변경되면 것만 엎어친다. 라는 개념으로 보면 될 거 같다.


그러면 바이너리상에 변경된 부분만  old file에서 적용시켜 패치하고자 하는 파일로 생성하니 엄청난 이득이지 않는


가? ...난 여태 이런게 있다는것 조차 모르고 살았다 ;;;;


정말 나에게는 신세계같은 경험???..


MSPatch로 테스트 해본결과 


1. OLD File: 2,910,008 바이트(2.77MB)
2. New File: 2,920,248 바이트(2.78MB)
3. 생성된 deltafile: 297,520 바이트(290KB)
4. delta file 생성에 걸리는 시간(Release mode): 2277ms(2.3초정도 걸림, 생각보다 시간이 걸리네..)
5. 생성된 delta file을 압축률이 가장좋은 7z으로 압축시:  297,691 바이트   
   (오히려 파일 사이즈가 늘어남, 따라서 delta파일 자체 압축률이 상당히 높은것으로 보임.)
6.Apply delta file 에 걸리는 시간: 32ms

New File을 7z으로 압축하면 927KB였다 즉 7z압축시에는 약 3분의 1정도로 줄어들고 delta파일로 만든경우에는

9분의 1정도 줄어든다고 볼 수 있다.

원본 파일만 가지고 있다면 이를 활용하여 큰용량의 파일들도 작은 delta파일로만 관리 될 수 있을거 같은 

해결책이 될 거 같은 느낌이 든다.!

일단 사용하는 함수에 대해 나온곳은

출처: http://blog.naver.com/ships95/120051350941
 
위 출처를 좀더 보기 좋에 다른곳에서 포스팅한 곳은

http://indra17.tistory.com/entry/MS-Patch-API

또 다른 참조할 만한 사이트
http://bspfp.pe.kr/360

그리고 마지막으로 MSDN 사이트

https://msdn.microsoft.com/en-us/library/bb417345.aspx

여기에 해당 dl에 대한 설명과 referance api등에 대해 설명이 되어 있다.


TestCode:
Make_Delta_File에서 패치할 delta파일을 만들고
Apply_Delta_File함수에서 old파일에 delta파일을 적용하여 패치되어야 하는 파일로 만든다고 보면된다.
사용되어야 하는 dll은 mspatchc.dll (Create쪽) mspatcha.dll (apply쪽)으로 총 2개의 dll이 필요하다.
explicit link(명시적 링크, loadlibrary), 로 해도되고  implicit link로 사용하여도 된다.

//-- Include 할 헤더파일
#include <PatchApi.h>


/**
@brief 패치할 delta file을 생성한다.
@param [IN] szFrom : OLD file로 원본파일 경로(full path로 파일명 포함)
@param [IN] szDest : 패치할 New File로 변경되어야 하는 파일(full path로 파일명 포함)
@param [IN] szDelta : 생성될 delta file full path(파일명포함)
@param [OUT] pdwErr         : 실패시 GetLastError값 반환
@param [OUT] _pdwTick         : Delta file 생성에 걸리는 시간(NULL로 넣으면 처리하지 않음)
@return TRUE: 성공, FALSE: 실패
@note N/A
*/
BOOL XXXXXXX::Make_Delta_File(LPCTSTR szFrom, LPCTSTR szDest, LPCTSTR szDelta, DWORD* pdwErr, DWORD* pdwTick)
{
CString sLog = _T("");
PATCH_OLD_FILE_INFO_W ofi;
ofi.SizeOfThisStruct = sizeof(PATCH_OLD_FILE_INFO_W);
ofi.OldFileName = szFrom;
ofi.IgnoreRangeCount = 0;
ofi.RetainRangeCount = 0;

CFileStatus st;
if (FALSE == CFile::GetStatus(szDest, st))
{
if (pdwErr)
*pdwErr = GetLastError();
return FALSE;
}
ULONG lflags = (st.m_size >= 8 * 1024 * 1024) ? (PATCH_OPTION_USE_LZX_BEST | PATCH_OPTION_USE_LZX_LARGE) : PATCH_OPTION_USE_LZX_A;
if (PATCH_OPTION_USE_LZX_A != lflags)
{
sLog.Format(_T("File size over 8MB option changed : %s"), szDest);
//AfxMessageBox(sLog); //to-do: Log로 변경필요
}

DWORD dwStartTick = GetTickCount();
BOOL bResult = CreatePatchFileEx(1, &ofi, szDest, szDelta, lflags, NULL, NULL, NULL);
if (!bResult)
{
DWORD dwError = ::GetLastError();
if (pdwErr)
*pdwErr = dwError;
sLog.Format(_T("Error - CreatePatchFileEx(0x%x)"), dwError);
//AfxMessageBox(sLog); ///<to-do: 필요시 로그 남길것
return FALSE;
}
if (pdwTick && bResult)
*pdwTick = GetTickCount() - dwStartTick;
return TRUE;
}

/**
@brief delta file을 적용하여 패치할 파일로 만든다.
@param [IN] szFrom : OLD file로 원본파일 경로(full path로 파일명 포함)
@param [IN] szDest : New File로 생성될 Full path(파일명 포함)
@param [IN] szDelta : patch delta file
@param [OUT] pdwErr         : 실패시 GetLastError값 반환
@param [IN] _pdwTick         : apply에 걸리는 tickCount(NULL로 넣으면 처리하지 않음)
@return TRUE: 성공, FALSE: 실패
@note N/A
*/
BOOL XXXXX::Apply_Delta_File(LPCTSTR szFrom, LPCTSTR szDest, LPCTSTR szDelta, DWORD* pdwErr, DWORD* pdwTick)
{
CString sLog = _T("");
DWORD dwStartTick = GetTickCount();
BOOL bResult = ApplyPatchToFileEx(szDelta, szFrom, szDest, PATCH_OPTION_USE_LZX_A, NULL, NULL);
if (!bResult)
{
DWORD dwError = ::GetLastError();
if (pdwErr)
*pdwErr = dwError;
return FALSE;
}

if (pdwTick && bResult)
*pdwTick = GetTickCount() - dwStartTick;

return TRUE;
}


추가적으로 발취된 내용에서 아래와 같은 정보가 있다.

1. vcdiff           http://www.faqs.org/rfcs/rfc3284.html
2. xdelta          http://xdelta.org/
3. msdelta       http://msdn2.microsoft.com/en-us/library/bb267312.aspx
4. zdelta         http://cis.poly.edu/zdelta/


1. vcdiff : 델타에 관련된 논문
2. xdelta : 최신 버전은 xdelta3 로 소스까지 있으며 속도는 가장 빠른 것으로 보인다.
3. msdelta : vista 부터 적용된 업데이트 관련 델타 엔진, ms에서 사용중임
4. zdelta : zlib을 바탕으로 수정된 것으로 매우 빠르고 델타생성 크기가 적절하다!

[출처] MS Patch API...|작성자 비우꺼

ㅇㄹㅇㄹ

정보는 공유되어야 한다 쭈욱!~


반응형

댓글