OSDN Git Service

PATCH: [ 1234390 ] Compare >2 MB files with quick contents
authorKimmo Varis <kimmov@gmail.com>
Fri, 8 Jul 2005 13:37:21 +0000 (13:37 +0000)
committerKimmo Varis <kimmov@gmail.com>
Fri, 8 Jul 2005 13:37:21 +0000 (13:37 +0000)
Src/DiffWrapper.cpp
Src/DiffWrapper.h
Src/DirScan.cpp
Src/readme.txt

index b303288..ce21eaa 100644 (file)
@@ -47,6 +47,17 @@ static char THIS_FILE[] = __FILE__;
 extern int recursive;
 extern CLogFile gLog;
 static int f_defcp = 0; // default codepage
+static const int MEG = 1024 * 1024; // Mega(byte)
+
+/**
+ * @brief Limit for compare by contents/quick contents.
+ * If compare by contents is selected (normal) then files bigger than limit
+ * are compared with compare by quick contents. That allows us to compare
+ * big binary files and overall makes comparing bigger files faster.
+ */
+static const int CMP_SIZE_LIMIT = 2 * MEG;
+
+static void GetComparePaths(CDiffContext * pCtxt, const DIFFITEM &di, CString & left, CString & right);
 
 /**
  * @brief Default constructor
@@ -1386,6 +1397,47 @@ static bool Unpack(CString & filepathTransformed,
 }
 
 /**
+ * @brief Get actual compared paths from DIFFITEM.
+ * @note If item is unique, same path is returned for both.
+ */
+void GetComparePaths(CDiffContext * pCtxt, const DIFFITEM &di, CString & left, CString & right)
+{
+       static const TCHAR backslash[] = _T("\\");
+
+       if (di.isSideLeft())
+       {
+               // Compare file to itself to detect encoding
+               left = pCtxt->GetNormalizedLeft() + backslash;
+               if (!di.sSubdir.IsEmpty())
+                       left += di.sSubdir + backslash;
+               left += di.sfilename;
+               right = left;
+       }
+       else if (di.isSideRight())
+       {
+               // Compare file to itself to detect encoding
+               right = pCtxt->GetNormalizedRight() + backslash;
+               if (!di.sSubdir.IsEmpty())
+                       right += di.sSubdir + backslash;
+               right += di.sfilename;
+               left = right;
+       }
+       else
+       {
+               left = pCtxt->GetNormalizedLeft() + backslash;
+               right = pCtxt->GetNormalizedRight() + backslash;
+               if (!di.sSubdir.IsEmpty())
+               {
+                       left += di.sSubdir + backslash;
+                       right += di.sSubdir + backslash;
+               }
+               left += di.sfilename;
+               right += di.sfilename;
+       }
+}
+
+
+/**
  * @brief Invoke appropriate plugins for prediffing
  * return false if anything fails
  * caller has to DeleteFile filepathTransformed, if it differs from filepath
@@ -1443,9 +1495,13 @@ bool DiffFileData::FilepathWithEncoding::Transform(const CString & filepath, CSt
 /**
  * @brief Prepare files (run plugins) & compare them, and return diffcode
  */
-int
-DiffFileData::prepAndCompareTwoFiles(CDiffContext * pCtxt, const CString & filepath1, const CString & filepath2) //, int * ndiffs, int * ntrivialdiffs, int unicoding[2])
+int DiffFileData::prepAndCompareTwoFiles(CDiffContext * pCtxt, const DIFFITEM &di)
 {
+       int nCompMethod = pCtxt->m_nCompMethod;
+       CString filepath1;
+       CString filepath2;
+       GetComparePaths(pCtxt, di, filepath1, filepath2);
+
        int code = DIFFCODE::FILE | DIFFCODE::CMPERR;
        // For user chosen plugins, define bAutomaticUnpacker as false and use the chosen infoHandler
        // but how can we receive the infoHandler ? DirScan actually only 
@@ -1511,13 +1567,20 @@ DiffFileData::prepAndCompareTwoFiles(CDiffContext * pCtxt, const CString & filep
                        goto exitPrepAndCompare;
        }
 
+       // If either file is larger than 2 Megs compare files by quick contents
+       // This allows us to (faster) compare big binary files
+       if (pCtxt->m_nCompMethod == CMP_CONTENT && 
+               (di.left.size > CMP_SIZE_LIMIT || di.right.size > CMP_SIZE_LIMIT))
+       {
+               nCompMethod = CMP_QUICK_CONTENT;
+       }
 
-       if (pCtxt->m_nCompMethod == CMP_CONTENT)
+       if (nCompMethod == CMP_CONTENT)
        {
                // use diffutils
                code = diffutils_compare_files(0);
        }
-       else if (pCtxt->m_nCompMethod == CMP_QUICK_CONTENT)
+       else if (nCompMethod == CMP_QUICK_CONTENT)
        {
                // use our own byte-by-byte compare
                code = byte_compare_files();
index a989e37..cc8fff0 100644 (file)
@@ -210,6 +210,7 @@ private:
 // forward declarations needed by DiffFileData
 struct file_data;
 class PrediffingInfo;
+struct DIFFITEM;
 
 /**
  * @brief C++ container for the structure (file_data) used by diffutils' diff_2_files(...)
@@ -232,7 +233,7 @@ struct DiffFileData
        int diffutils_compare_files(int depth);
        int byte_compare_files();
        void GuessEncoding(int side, CDiffContext * pCtxt);
-       int prepAndCompareTwoFiles(CDiffContext * pCtxt, const CString & filepath1, const CString & filepath2);
+       int prepAndCompareTwoFiles(CDiffContext * pCtxt, const DIFFITEM &di);
        BOOL Diff2Files(struct change ** diffs, int depth,
                int * bin_status, BOOL bMovedBlocks);
 
index 75ca758..dc1d135 100644 (file)
@@ -361,19 +361,9 @@ void UpdateDiffItem(DIFFITEM & di, BOOL & bExists, CDiffContext *pCtxt)
  */
 void CompareDiffItem(DIFFITEM di, CDiffContext * pCtxt)
 {
-       CString sLeftDir = pCtxt->GetNormalizedLeft();
-       CString sRightDir = pCtxt->GetNormalizedRight();
-       static const TCHAR backslash[] = _T("\\");
-
        // Clear possible rescan-flag
        di.diffcode &= ~DIFFCODE::NEEDSCAN;
 
-       if (!di.sSubdir.IsEmpty())
-       {
-               sLeftDir += backslash + di.sSubdir;
-               sRightDir += backslash + di.sSubdir;
-       }
-
        // 1. Test against filters
        if (di.isDirectory())
        {
@@ -400,9 +390,8 @@ void CompareDiffItem(DIFFITEM di, CDiffContext * pCtxt)
                if (pCtxt->m_nCompMethod != CMP_DATE)
                {
                        // Compare file to itself to detect encoding
-                       CString filepath = sRightDir + backslash + di.sfilename;
                        DiffFileData diffdata;
-                       diffdata.prepAndCompareTwoFiles(pCtxt, filepath, filepath);
+                       diffdata.prepAndCompareTwoFiles(pCtxt, di);
                        StoreDiffResult(di, pCtxt, &diffdata);
                }
                else
@@ -416,9 +405,8 @@ void CompareDiffItem(DIFFITEM di, CDiffContext * pCtxt)
                if (pCtxt->m_nCompMethod != CMP_DATE)
                {
                        // Compare file to itself to detect encoding
-                       CString filepath = sLeftDir + backslash + di.sfilename;
                        DiffFileData diffdata;
-                       diffdata.prepAndCompareTwoFiles(pCtxt, filepath, filepath);
+                       diffdata.prepAndCompareTwoFiles(pCtxt, di);
                        StoreDiffResult(di, pCtxt, &diffdata);
 
                }
@@ -458,13 +446,10 @@ void CompareDiffItem(DIFFITEM di, CDiffContext * pCtxt)
                        StoreDiffResult(di, pCtxt, NULL);
                        return;
                }
-               // Files to compare
-               CString filepath1 = sLeftDir + backslash + di.sfilename;
-               CString filepath2 = sRightDir + backslash + di.sfilename;
-                               // Really compare
+               // Really compare
                DiffFileData diffdata;
-               di.diffcode |= diffdata.prepAndCompareTwoFiles(pCtxt, filepath1, filepath2);
-                       // report result back to caller
+               di.diffcode |= diffdata.prepAndCompareTwoFiles(pCtxt, di);
+               // report result back to caller
                StoreDiffResult(di, pCtxt, &diffdata);
        }
                                
index 8a48491..1b6cbd7 100644 (file)
@@ -1,3 +1,7 @@
+2005-07-08 Kimmo
+ PATCH: [ 1234390 ] Compare >2 MB files with quick contents
+  Src: DiffWrapper.cpp DiffWrapper.h DirScan.cpp
+
 2005-07-07 Kimmo
  PATCH: [ 1232499 ] Language dialog box Simplified Chinese's name correction
   Submitted by xmpdhml at sourceforge.net