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)
24 , m_nIdleCompareThreadCount(0)
29 * @brief Destructor, deletes critical section.
31 CompareStats::~CompareStats() = default;
34 * @brief Add compared item.
35 * @param [in] code Resultcode to add.
37 void CompareStats::AddItem(int code)
41 RESULT res = GetResultFromCode(code);
42 int index = static_cast<int>(res);
46 assert(m_nComparedItems <= m_nTotalItems);
50 * @brief Return item taking most time among current items.
52 const DIFFITEM *CompareStats::GetCurDiffItem()
55 const DIFFITEM *cdi = m_rgThreadState.front().m_pDiffItem;
56 std::vector<ThreadState>::iterator it = m_rgThreadState.begin();
57 while (it != m_rgThreadState.end())
59 const DIFFITEM *di = it->m_pDiffItem;
60 if (di != nullptr && (di->diffcode.diffcode & DIFFCODE::COMPAREFLAGS) == DIFFCODE::NOCMP)
62 int nHitCount = it->m_nHitCount++;
63 if (nHitCountMax < nHitCount)
65 nHitCountMax = nHitCount;
75 * @brief Reset comparestats.
76 * Use this function to reset stats before new compare.
78 void CompareStats::Reset()
80 std::fill(std::begin(m_counts), std::end(m_counts), 0);
81 SetCompareState(STATE_IDLE);
84 m_bCompareDone = false;
88 * @brief Change compare state.
89 * @param [in] state New compare state.
91 void CompareStats::SetCompareState(CompareStats::CMP_STATE state)
93 // New compare starting so reset ready status
94 if (state == STATE_START)
95 m_bCompareDone = false;
97 if (state == STATE_IDLE && m_state == STATE_COMPARE)
98 m_bCompareDone = true;
104 * @brief Convert diffcode to compare-result.
105 * @param [in] diffcode DIFFITEM.diffcode to convert.
106 * @return Compare result.
108 CompareStats::RESULT CompareStats::GetResultFromCode(unsigned diffcode) const
110 DIFFCODE di(diffcode);
112 bool is_dir = di.isDirectory();
113 // Test first for skipped so we pick all skipped items as such
114 if (di.isResultFiltered())
117 return is_dir ? RESULT_DIRSKIP : RESULT_SKIP;
119 else if (di.isSideFirstOnly())
122 return is_dir ? RESULT_LDIRUNIQUE : RESULT_LUNIQUE;
124 else if (di.isSideSecondOnly())
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 is_dir ? RESULT_RDIRUNIQUE : RESULT_RUNIQUE;
137 else if (m_nDirs > 2)
139 switch (diffcode & DIFFCODE::ALL)
141 case (DIFFCODE::SECOND | DIFFCODE::THIRD) : return is_dir ? RESULT_LDIRMISSING : RESULT_LMISSING;
142 case (DIFFCODE::FIRST | DIFFCODE::THIRD) : return is_dir ? RESULT_MDIRMISSING : RESULT_MMISSING;
143 case (DIFFCODE::FIRST | DIFFCODE::SECOND): return is_dir ? RESULT_RDIRMISSING : RESULT_RMISSING;
146 if (di.isResultError())
148 // could be directory error ?
151 // Now we know it was on both sides & compared!
152 else if (di.isResultSame())
157 return RESULT_DIRSAME;
161 return di.isBin() ? RESULT_BINSAME : RESULT_SAME;
168 return RESULT_DIRDIFF;
172 // presumably it is different
173 return di.isBin() ? RESULT_BINDIFF : RESULT_DIFF;
178 void CompareStats::Swap(int idx1, int idx2)
180 idx2 = m_nDirs < 3 ? idx2 + 1 : idx2;
181 m_counts[RESULT_LUNIQUE + idx2] = m_counts[RESULT_LUNIQUE + idx1].exchange(m_counts[RESULT_LUNIQUE + idx2]);
182 m_counts[RESULT_LMISSING + idx2] = m_counts[RESULT_LMISSING + idx1].exchange(m_counts[RESULT_LMISSING + idx2]);
183 m_counts[RESULT_LDIRUNIQUE + idx2] = m_counts[RESULT_LDIRUNIQUE + idx1].exchange(m_counts[RESULT_LDIRUNIQUE + idx2]);
184 m_counts[RESULT_LDIRMISSING + idx2] = m_counts[RESULT_LDIRMISSING + idx1].exchange(m_counts[RESULT_LDIRMISSING + idx2]);