GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/catalog_counters.h
Date: 2024-04-28 02:33:07
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 <gtest/gtest_prod.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 1788 Fields()
44 1788 : regular_files(0)
45 1788 , symlinks(0)
46 1788 , specials(0)
47 1788 , directories(0)
48 1788 , nested_catalogs(0)
49 1788 , chunked_files(0)
50 1788 , file_chunks(0)
51 1788 , file_size(0)
52 1788 , chunked_file_size(0)
53 1788 , xattrs(0)
54 1788 , externals(0)
55 1788 , external_file_size(0) { }
56
57 // typname U is another TreeCountersBase (eg: add DeltaCounters to Counters)
58 template<typename U>
59 172 void Add(const U &other) {
60 172 Combine<U, 1>(other);
61 172 }
62
63 template<typename U>
64 135 void Subtract(const U &other) {
65 135 Combine<U, -1>(other);
66 135 }
67
68 template<typename U, int factor>
69 314 void Combine(const U &other) {
70 314 regular_files += factor * other.regular_files;
71 314 symlinks += factor * other.symlinks;
72 314 specials += factor * other.specials;
73 314 directories += factor * other.directories;
74 314 nested_catalogs += factor * other.nested_catalogs;
75 314 chunked_files += factor * other.chunked_files;
76 314 file_chunks += factor * other.file_chunks;
77 314 file_size += factor * other.file_size;
78 314 chunked_file_size += factor * other.chunked_file_size;
79 314 xattrs += factor * other.xattrs;
80 314 externals += factor * other.externals;
81 314 external_file_size += factor * other.external_file_size;
82 314 }
83
84 1584 void FillFieldsMap(const std::string &prefix, FieldsMap *map) const {
85
1/2
✓ Branch 2 taken 792 times.
✗ Branch 3 not taken.
1584 (*map)[prefix + "regular"] = &regular_files;
86
1/2
✓ Branch 2 taken 792 times.
✗ Branch 3 not taken.
1584 (*map)[prefix + "symlink"] = &symlinks;
87
1/2
✓ Branch 2 taken 792 times.
✗ Branch 3 not taken.
1584 (*map)[prefix + "special"] = &specials;
88
1/2
✓ Branch 2 taken 792 times.
✗ Branch 3 not taken.
1584 (*map)[prefix + "dir"] = &directories;
89
1/2
✓ Branch 2 taken 792 times.
✗ Branch 3 not taken.
1584 (*map)[prefix + "nested"] = &nested_catalogs;
90
1/2
✓ Branch 2 taken 792 times.
✗ Branch 3 not taken.
1584 (*map)[prefix + "chunked"] = &chunked_files;
91
1/2
✓ Branch 2 taken 792 times.
✗ Branch 3 not taken.
1584 (*map)[prefix + "chunks"] = &file_chunks;
92
1/2
✓ Branch 2 taken 792 times.
✗ Branch 3 not taken.
1584 (*map)[prefix + "file_size"] = &file_size;
93
1/2
✓ Branch 2 taken 792 times.
✗ Branch 3 not taken.
1584 (*map)[prefix + "chunked_size"] = &chunked_file_size;
94
1/2
✓ Branch 2 taken 792 times.
✗ Branch 3 not taken.
1584 (*map)[prefix + "xattr"] = &xattrs;
95
1/2
✓ Branch 2 taken 792 times.
✗ Branch 3 not taken.
1584 (*map)[prefix + "external"] = &externals;
96
1/2
✓ Branch 2 taken 792 times.
✗ Branch 3 not taken.
1584 (*map)[prefix + "external_file_size"] = &external_file_size;
97 1584 }
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 486 void Increment(const DirectoryEntry &dirent) { ApplyDelta(dirent, 1); }
142 129 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