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