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() = default;
33 * @brief Add compared item.
34 * @param [in] code Resultcode to add.
36 void CompareStats::AddItem(int code)
40 RESULT res = GetResultFromCode(code);
41 int index = static_cast<int>(res);
45 assert(m_nComparedItems <= m_nTotalItems);
49 * @brief Return item taking most time among current items.
51 const DIFFITEM *CompareStats::GetCurDiffItem()
54 const DIFFITEM *cdi = m_rgThreadState.front().m_pDiffItem;
55 std::vector<ThreadState>::iterator it = m_rgThreadState.begin();
56 while (it != m_rgThreadState.end())
58 const DIFFITEM *di = it->m_pDiffItem;
59 if (di != nullptr && (di->diffcode.diffcode & DIFFCODE::COMPAREFLAGS) == DIFFCODE::NOCMP)
61 int nHitCount = it->m_nHitCount++;
62 if (nHitCountMax < nHitCount)
64 nHitCountMax = nHitCount;
74 * @brief Reset comparestats.
75 * Use this function to reset stats before new compare.
77 void CompareStats::Reset()
79 std::fill(std::begin(m_counts), std::end(m_counts), 0);
80 SetCompareState(STATE_IDLE);
83 m_bCompareDone = false;
87 * @brief Change compare state.
88 * @param [in] state New compare state.
90 void CompareStats::SetCompareState(CompareStats::CMP_STATE state)
92 // New compare starting so reset ready status
93 if (state == STATE_START)
94 m_bCompareDone = false;
96 if (state == STATE_IDLE && m_state == STATE_COMPARE)
97 m_bCompareDone = true;
103 * @brief Convert diffcode to compare-result.
104 * @param [in] diffcode DIFFITEM.diffcode to convert.
105 * @return Compare result.
107 CompareStats::RESULT CompareStats::GetResultFromCode(unsigned diffcode) const
109 DIFFCODE di(diffcode);
111 // Test first for skipped so we pick all skipped items as such
112 if (di.isResultFiltered())
115 return di.isDirectory() ? RESULT_DIRSKIP : RESULT_SKIP;
117 else if (di.isSideFirstOnly())
120 return di.isDirectory() ? RESULT_LDIRUNIQUE : RESULT_LUNIQUE;
122 else if (di.isSideSecondOnly())
125 if (di.isDirectory())
126 return (m_nDirs < 3) ? RESULT_RDIRUNIQUE : RESULT_MDIRUNIQUE;
128 return (m_nDirs < 3) ? RESULT_RUNIQUE : RESULT_MUNIQUE;
130 else if (di.isSideThirdOnly())
133 return di.isDirectory() ? RESULT_RDIRUNIQUE : RESULT_RUNIQUE;
135 else if (m_nDirs > 2 && !di.exists(0) && di.exists(1) && di.exists(2))
136 return di.isDirectory() ? RESULT_LDIRMISSING : RESULT_LMISSING;
137 else if (m_nDirs > 2 && di.exists(0) && !di.exists(1) && di.exists(2))
138 return di.isDirectory() ? RESULT_MDIRMISSING : RESULT_MMISSING;
139 else if (m_nDirs > 2 && di.exists(0) && di.exists(1) && !di.exists(2))
140 return di.isDirectory() ? RESULT_RDIRMISSING : RESULT_RMISSING;
141 else if (di.isResultError())
143 // could be directory error ?
146 // Now we know it was on both sides & compared!
147 else if (di.isResultSame())
150 if (di.isDirectory())
152 return RESULT_DIRSAME;
156 return di.isBin() ? RESULT_BINSAME : RESULT_SAME;
161 if (di.isDirectory())
163 return RESULT_DIRDIFF;
167 // presumably it is different
168 return di.isBin() ? RESULT_BINDIFF : RESULT_DIFF;
173 void CompareStats::Swap(int idx1, int idx2)
175 idx2 = m_nDirs < 3 ? idx2 + 1 : idx2;
176 m_counts[RESULT_LUNIQUE + idx2] = m_counts[RESULT_LUNIQUE + idx1].exchange(m_counts[RESULT_LUNIQUE + idx2]);
177 m_counts[RESULT_LMISSING + idx2] = m_counts[RESULT_LMISSING + idx1].exchange(m_counts[RESULT_LMISSING + idx2]);
178 m_counts[RESULT_LDIRUNIQUE + idx2] = m_counts[RESULT_LDIRUNIQUE + idx1].exchange(m_counts[RESULT_LDIRUNIQUE + idx2]);
179 m_counts[RESULT_LDIRMISSING + idx2] = m_counts[RESULT_LDIRMISSING + idx1].exchange(m_counts[RESULT_LDIRMISSING + idx2]);