GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/catalog_counters.h
Date: 2025-10-19 02:35:28
Exec Total Coverage
Lines: 49 49 100.0%
Branches: 12 24 50.0%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5 #ifndef CVMFS_CATALOG_COUNTERS_H_
6 #define CVMFS_CATALOG_COUNTERS_H_
7
8 #include "duplex_testing.h"
9 #include <stdint.h>
10
11 #include <map>
12 #include <string>
13
14 namespace swissknife {
15 class CommandCheck;
16 }
17
18 namespace catalog {
19
20 class DirectoryEntry;
21 class CatalogDatabase;
22
23 struct LegacyMode {
24 enum Type { // TODO(rmeusel): C++11 typed enum
25 kNoLegacy,
26 kNoSpecials,
27 kNoExternals,
28 kNoXattrs,
29 kLegacy
30 };
31 };
32
33 // FieldT is either int64_t (DeltaCounters) or uint64_t (Counters)
34 template<typename FieldT>
35 class TreeCountersBase {
36 friend class swissknife::CommandCheck;
37 FRIEND_TEST(T_CatalogCounters, FieldsCombinations);
38 FRIEND_TEST(T_CatalogCounters, FieldsMap);
39
40 protected:
41 typedef std::map<std::string, const FieldT *> FieldsMap;
42 struct Fields {
43 61840 Fields()
44 61840 : regular_files(0)
45 61840 , symlinks(0)
46 61840 , specials(0)
47 61840 , directories(0)
48 61840 , nested_catalogs(0)
49 61840 , chunked_files(0)
50 61840 , file_chunks(0)
51 61840 , file_size(0)
52 61840 , chunked_file_size(0)
53 61840 , xattrs(0)
54 61840 , externals(0)
55 61840 , external_file_size(0) { }
56
57 // typname U is another TreeCountersBase (eg: add DeltaCounters to Counters)
58 template<typename U>
59 6116 void Add(const U &other) {
60 6116 Combine<U, 1>(other);
61 6116 }
62
63 template<typename U>
64 4637 void Subtract(const U &other) {
65 4637 Combine<U, -1>(other);
66 4637 }
67
68 template<typename U, int factor>
69 10970 void Combine(const U &other) {
70 10970 regular_files += factor * other.regular_files;
71 10970 symlinks += factor * other.symlinks;
72 10970 specials += factor * other.specials;
73 10970 directories += factor * other.directories;
74 10970 nested_catalogs += factor * other.nested_catalogs;
75 10970 chunked_files += factor * other.chunked_files;
76 10970 file_chunks += factor * other.file_chunks;
77 10970 file_size += factor * other.file_size;
78 10970 chunked_file_size += factor * other.chunked_file_size;
79 10970 xattrs += factor * other.xattrs;
80 10970 externals += factor * other.externals;
81 10970 external_file_size += factor * other.external_file_size;
82 10970 }
83
84 54224 void FillFieldsMap(const std::string &prefix, FieldsMap *map) const {
85
1/2
✓ Branch 2 taken 27112 times.
✗ Branch 3 not taken.
54224 (*map)[prefix + "regular"] = &regular_files;
86
1/2
✓ Branch 2 taken 27112 times.
✗ Branch 3 not taken.
54224 (*map)[prefix + "symlink"] = &symlinks;
87
1/2
✓ Branch 2 taken 27112 times.
✗ Branch 3 not taken.
54224 (*map)[prefix + "special"] = &specials;
88
1/2
✓ Branch 2 taken 27112 times.
✗ Branch 3 not taken.
54224 (*map)[prefix + "dir"] = &directories;
89
1/2
✓ Branch 2 taken 27112 times.
✗ Branch 3 not taken.
54224 (*map)[prefix + "nested"] = &nested_catalogs;
90
1/2
✓ Branch 2 taken 27112 times.
✗ Branch 3 not taken.
54224 (*map)[prefix + "chunked"] = &chunked_files;
91
1/2
✓ Branch 2 taken 27112 times.
✗ Branch 3 not taken.
54224 (*map)[prefix + "chunks"] = &file_chunks;
92
1/2
✓ Branch 2 taken 27112 times.
✗ Branch 3 not taken.
54224 (*map)[prefix + "file_size"] = &file_size;
93
1/2
✓ Branch 2 taken 27112 times.
✗ Branch 3 not taken.
54224 (*map)[prefix + "chunked_size"] = &chunked_file_size;
94
1/2
✓ Branch 2 taken 27112 times.
✗ Branch 3 not taken.
54224 (*map)[prefix + "xattr"] = &xattrs;
95
1/2
✓ Branch 2 taken 27112 times.
✗ Branch 3 not taken.
54224 (*map)[prefix + "external"] = &externals;
96
1/2
✓ Branch 2 taken 27112 times.
✗ Branch 3 not taken.
54224 (*map)[prefix + "external_file_size"] = &external_file_size;
97 54224 }
98
99 FieldT regular_files;
100 FieldT symlinks;
101 FieldT specials;
102 FieldT directories;
103 FieldT nested_catalogs;
104 FieldT chunked_files;
105 FieldT file_chunks;
106 FieldT file_size;
107 FieldT chunked_file_size;
108 FieldT xattrs;
109 FieldT externals;
110 FieldT external_file_size;
111 };
112
113 public:
114 FieldT Get(const std::string &key) const;
115 bool ReadFromDatabase(const CatalogDatabase &database,
116 const LegacyMode::Type legacy = LegacyMode::kNoLegacy);
117 bool WriteToDatabase(const CatalogDatabase &database) const;
118 bool InsertIntoDatabase(const CatalogDatabase &database) const;
119
120 void SetZero();
121
122 std::map<std::string, FieldT> GetValues() const;
123 std::string GetCsvMap() const;
124
125 protected:
126 FieldsMap GetFieldsMap() const;
127
128 public:
129 Fields self;
130 Fields subtree;
131 };
132
133
134 typedef int64_t DeltaCounters_t;
135 class DeltaCounters : public TreeCountersBase<DeltaCounters_t> {
136 friend class Counters;
137
138 public:
139 void PopulateToParent(DeltaCounters *parent) const;
140 void RemoveFromSubtree(const DeltaCounters &child);
141 16678 void Increment(const DirectoryEntry &dirent) { ApplyDelta(dirent, 1); }
142 4412 void Decrement(const DirectoryEntry &dirent) { ApplyDelta(dirent, -1); }
143
144 private:
145 void ApplyDelta(const DirectoryEntry &dirent, const int delta);
146 };
147
148
149 typedef uint64_t Counters_t;
150 class Counters : public TreeCountersBase<Counters_t> {
151 public:
152 static DeltaCounters Diff(const Counters &from, const Counters &to);
153
154 void ApplyDelta(const DeltaCounters &delta);
155 void AddAsSubtree(DeltaCounters *delta) const;
156 void MergeIntoParent(DeltaCounters *parent_delta) const;
157 Counters_t GetSelfEntries() const;
158 Counters_t GetSubtreeEntries() const;
159 Counters_t GetAllEntries() const;
160 };
161
162 } // namespace catalog
163
164 #include "catalog_counters_impl.h"
165
166 #endif // CVMFS_CATALOG_COUNTERS_H_
167