2 * @file CompareStats.cpp
4 * @brief Implementation of CompareStats class.
8 #include "CompareStats.h"
15 * @brief Constructor, initializes critical section.
17 CompareStats::CompareStats(int nDirs)
21 , m_bCompareDone(false)
28 * @brief Destructor, deletes critical section.
30 CompareStats::~CompareStats()
35 * @brief Add compared item.
36 * @param [in] code Resultcode to add.
38 void CompareStats::AddItem(int code)
42 RESULT res = GetResultFromCode(code);
43 int index = static_cast<int>(res);
47 assert(m_nComparedItems <= m_nTotalItems);
51 * @brief Return item taking most time among current items.
53 const DIFFITEM *CompareStats::GetCurDiffItem()
56 const DIFFITEM *cdi = m_rgThreadState.front().m_pDiffItem;
57 std::vector<ThreadState>::iterator it = m_rgThreadState.begin();
58 while (it != m_rgThreadState.end())
60 const DIFFITEM *di = it->m_pDiffItem;
61 if (di != nullptr && (di->diffcode.diffcode & DIFFCODE::COMPAREFLAGS) == DIFFCODE::NOCMP)
63 int nHitCount = it->m_nHitCount++;
64 if (nHitCountMax < nHitCount)
66 nHitCountMax = nHitCount;
76 * @brief Reset comparestats.
77 * Use this function to reset stats before new compare.
79 void CompareStats::Reset()
81 std::fill(std::begin(m_counts), std::end(m_counts), 0);
82 SetCompareState(STATE_IDLE);
85 m_bCompareDone = false;
89 * @brief Change compare state.
90 * @param [in] state New compare state.
92 void CompareStats::SetCompareState(CompareStats::CMP_STATE state)
94 // New compare starting so reset ready status
95 if (state == STATE_START)
96 m_bCompareDone = false;
98 if (state == STATE_IDLE && m_state == STATE_COMPARE)
99 m_bCompareDone = true;
105 * @brief Convert diffcode to compare-result.
106 * @param [in] diffcode DIFFITEM.diffcode to convert.
107 * @return Compare result.
109 CompareStats::RESULT CompareStats::GetResultFromCode(unsigned diffcode) const
111 DIFFCODE di(diffcode);
113 // Test first for skipped so we pick all skipped items as such
114 if (di.isResultFiltered())
117 return di.isDirectory() ? RESULT_DIRSKIP : RESULT_SKIP;
119 else if (di.isSideFirstOnly())
122 return di.isDirectory() ? RESULT_LDIRUNIQUE : RESULT_LUNIQUE;
124 else if (di.isSideSecondOnly())
127 if (di.isDirectory())
128 return (m_nDirs < 3) ? RESULT_RDIRUNIQUE : RESULT_MDIRUNIQUE;
130 return (m_nDirs < 3) ? RESULT_RUNIQUE : RESULT_MUNIQUE;
132 else if (di.isSideThirdOnly())
135 return di.isDirectory() ? RESULT_RDIRUNIQUE : RESULT_RUNIQUE;
137 else if (m_nDirs > 2 && !di.exists(0) && di.exists(1) && di.exists(2))
138 return di.isDirectory() ? RESULT_LDIRMISSING : RESULT_LMISSING;
139 else if (m_nDirs > 2 && di.exists(0) && !di.exists(1) && di.exists(2))
140 return di.isDirectory() ? RESULT_MDIRMISSING : RESULT_MMISSING;
141 else if (m_nDirs > 2 && di.exists(0) && di.exists(1) && !di.exists(2))
142 return di.isDirectory() ? RESULT_RDIRMISSING : RESULT_RMISSING;
143 else if (di.isResultError())
145 // could be directory error ?
148 // Now we know it was on both sides & compared!
149 else if (di.isResultSame())
152 if (di.isDirectory())
154 return RESULT_DIRSAME;
158 return di.isBin() ? RESULT_BINSAME : RESULT_SAME;
163 if (di.isDirectory())
165 return RESULT_DIRDIFF;
169 // presumably it is different
170 return di.isBin() ? RESULT_BINDIFF : RESULT_DIFF;
175 void CompareStats::Swap(int idx1, int idx2)
177 idx2 = m_nDirs < 3 ? idx2 + 1 : idx2;
178 m_counts[RESULT_LUNIQUE + idx2] = m_counts[RESULT_LUNIQUE + idx1].exchange(m_counts[RESULT_LUNIQUE + idx2]);
179 m_counts[RESULT_LMISSING + idx2] = m_counts[RESULT_LMISSING + idx1].exchange(m_counts[RESULT_LMISSING + idx2]);
180 m_counts[RESULT_LDIRUNIQUE + idx2] = m_counts[RESULT_LDIRUNIQUE + idx1].exchange(m_counts[RESULT_LDIRUNIQUE + idx2]);
181 m_counts[RESULT_LDIRMISSING + idx2] = m_counts[RESULT_LDIRMISSING + idx1].exchange(m_counts[RESULT_LDIRMISSING + idx2]);