forked from WinMerge/winmerge
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCompareStats.h
148 lines (136 loc) · 3.87 KB
/
CompareStats.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/**
* @file CompareStats.h
*
* @brief Declaration of class CompareStats
*/
#pragma once
#include <atomic>
#include <vector>
#include <array>
class DIFFITEM;
/**
* @brief Class holding directory compare stats.
*
* This class is used for sharing compare stats between dir compare
* classes. CDiffContext updates statuses. GUI (compare statepane) tracks
* state changes and updates UI. If compare is fast (compared few small files)
* GUI might not be able to detect state change from IDLE back to IDLE. That's
* why there is IsCompareDone() which tells if new compare is ready.
*/
class CompareStats
{
public:
/**
* @brief Different states for compare procedure.
* These states form state-machine for directory compare. States go like:
* STATE_IDLE --> STATE_START --> STATE_COMPARE --> STATE_IDLE.
* @note GUI doesn't change state, but only backend code. GUI must track
* state changes to update itself.
*/
enum CMP_STATE
{
STATE_IDLE, /**< No compare running */
STATE_START, /**< Start folder compare */
STATE_COMPARE, /**< Comparing collected items */
};
/**
* @brief Resultcodes we store.
*/
enum RESULT
{
RESULT_LUNIQUE = 0,
RESULT_MUNIQUE,
RESULT_RUNIQUE,
RESULT_LMISSING,
RESULT_MMISSING,
RESULT_RMISSING,
RESULT_DIFF,
RESULT_SAME,
RESULT_BINSAME,
RESULT_BINDIFF,
RESULT_LDIRUNIQUE,
RESULT_MDIRUNIQUE,
RESULT_RDIRUNIQUE,
RESULT_LDIRMISSING,
RESULT_MDIRMISSING,
RESULT_RDIRMISSING,
RESULT_SKIP,
RESULT_DIRSKIP,
RESULT_DIRSAME,
RESULT_DIRDIFF,
RESULT_ERROR,
RESULT_COUNT //THIS MUST BE THE LAST ITEM
};
explicit CompareStats(int nDirs);
~CompareStats();
void SetCompareThreadCount(int nCompareThreads)
{
m_rgThreadState.clear();
m_rgThreadState.resize(nCompareThreads);
}
void BeginCompare(const DIFFITEM *di, int iCompareThread)
{
ThreadState &rThreadState = m_rgThreadState[iCompareThread];
rThreadState.m_nHitCount = 0;
rThreadState.m_pDiffItem = di;
}
void AddItem(int code);
void IncreaseTotalItems(int count = 1);
int GetCount(CompareStats::RESULT result) const;
int GetTotalItems() const;
int GetComparedItems() const { return m_nComparedItems; }
const DIFFITEM *GetCurDiffItem();
void Reset();
void SetCompareState(CompareStats::CMP_STATE state);
CompareStats::CMP_STATE GetCompareState() const;
bool IsCompareDone() const { return m_bCompareDone; }
CompareStats::RESULT GetResultFromCode(unsigned diffcode) const;
void Swap(int idx1, int idx2);
int GetCompareDirs() const { return m_nDirs; }
private:
std::array<std::atomic_int, RESULT_COUNT> m_counts; /**< Table storing result counts */
std::atomic_int m_nTotalItems; /**< Total items found to compare */
std::atomic_int m_nComparedItems; /**< Compared items so far */
CMP_STATE m_state; /**< State for compare (idle, collect, compare,..) */
bool m_bCompareDone; /**< Have we finished last compare? */
int m_nDirs; /**< number of directories to compare */
struct ThreadState
{
ThreadState() : m_nHitCount(0), m_pDiffItem(nullptr) {}
ThreadState(const ThreadState& other) : m_nHitCount(other.m_nHitCount.load()), m_pDiffItem(other.m_pDiffItem) {}
std::atomic_int m_nHitCount;
const DIFFITEM *m_pDiffItem;
};
std::vector<ThreadState> m_rgThreadState;
};
/**
* @brief Increase found items (dirs and files) count.
* @param [in] count Amount of items to add.
*/
inline void CompareStats::IncreaseTotalItems(int count)
{
m_nTotalItems += count;
}
/**
* @brief Return count by resultcode.
* @param [in] result Resultcode to return.
* @return Count of items for given resultcode.
*/
inline int CompareStats::GetCount(CompareStats::RESULT result) const
{
return m_counts[result];
}
/**
* @brief Return total count of items (so far) found.
*/
inline int CompareStats::GetTotalItems() const
{
return m_nTotalItems;
}
/**
* @brief Return current comparestate.
*/
inline CompareStats::CMP_STATE CompareStats::GetCompareState() const
{
return m_state;
}