OSDN Git Service

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