OSDN Git Service

a0e84082df72fde69053e2f792046f1cb9101a17
[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         void SetCompareThreadCount(int nCompareThreads)
73         {
74                 m_rgThreadState.resize(nCompareThreads);
75         }
76         void BeginCompare(const DIFFITEM *di, int iCompareThread)
77         {
78                 ThreadState &rThreadState = m_rgThreadState[iCompareThread];
79                 rThreadState.m_nHitCount = 0;
80                 rThreadState.m_pDiffItem = di;
81         }
82         void AddItem(int code);
83         void IncreaseTotalItems(int count = 1);
84         int GetCount(CompareStats::RESULT result) const;
85         int GetTotalItems() const;
86         int GetComparedItems() const { return m_nComparedItems; }
87         const DIFFITEM *GetCurDiffItem();
88         void Reset();
89         void SetCompareState(CompareStats::CMP_STATE state);
90         CompareStats::CMP_STATE GetCompareState() const;
91         bool IsCompareDone() const { return m_bCompareDone; }
92         CompareStats::RESULT GetResultFromCode(unsigned diffcode) const;
93         void Swap(int idx1, int idx2);
94         int GetCompareDirs() const { return m_nDirs; }
95
96 private:
97         std::array<std::atomic_int, RESULT_COUNT> m_counts; /**< Table storing result counts */
98         std::atomic_int m_nTotalItems; /**< Total items found to compare */
99         std::atomic_int m_nComparedItems; /**< Compared items so far */
100         CMP_STATE m_state; /**< State for compare (idle, collect, compare,..) */
101         bool m_bCompareDone; /**< Have we finished last compare? */
102         int m_nDirs; /**< number of directories to compare */
103         struct ThreadState
104         {
105                 ThreadState() : m_nHitCount(0), m_pDiffItem(nullptr) {}
106                 ThreadState(const ThreadState& other) : m_nHitCount(other.m_nHitCount.load()), m_pDiffItem(other.m_pDiffItem) {}
107                 std::atomic_int m_nHitCount;
108                 const DIFFITEM *m_pDiffItem;
109         };
110         std::vector<ThreadState> m_rgThreadState;
111
112 };
113
114 /** 
115  * @brief Increase found items (dirs and files) count.
116  * @param [in] count Amount of items to add.
117  */
118 inline void CompareStats::IncreaseTotalItems(int count)
119 {
120         m_nTotalItems += count;
121 }
122
123 /** 
124  * @brief Return count by resultcode.
125  * @param [in] result Resultcode to return.
126  * @return Count of items for given resultcode.
127  */
128 inline int CompareStats::GetCount(CompareStats::RESULT result) const
129 {
130         return m_counts[result];
131 }
132
133 /**
134  * @brief Return total count of items (so far) found.
135  */
136 inline int CompareStats::GetTotalItems() const
137 {
138         return m_nTotalItems;
139 }
140
141 /**
142  * @brief Return current comparestate.
143  */
144 inline CompareStats::CMP_STATE CompareStats::GetCompareState() const
145 {
146         return m_state;
147 }