CernVM-FS  2.13.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
catalog_balancer_impl.h
Go to the documentation of this file.
1 
5 #ifndef CVMFS_CATALOG_BALANCER_IMPL_H_
6 #define CVMFS_CATALOG_BALANCER_IMPL_H_
7 
8 
9 #include <inttypes.h>
10 
11 #include <cassert>
12 #include <cstdlib>
13 #include <string>
14 #include <vector>
15 
16 #include "catalog_mgr.h"
18 #include "crypto/hash.h"
19 #include "directory_entry.h"
20 #include "util/logging.h"
21 
22 
23 using namespace std; // NOLINT
24 
25 namespace catalog {
26 
27 template<class CatalogMgrT>
29  string name, uid_t uid, gid_t gid) {
30  // Note that another entity needs to ensure that the object of an empty
31  // file is in the repository! It is currently done by the sync_mediator.
32  shash::Algorithms algorithm = catalog_mgr_->spooler_->GetHashAlgorithm();
33  shash::Any file_hash(algorithm);
34  void *empty_compressed;
35  uint64_t sz_empty_compressed;
36  bool retval = zlib::CompressMem2Mem(NULL, 0, &empty_compressed,
37  &sz_empty_compressed);
38  assert(retval);
39  shash::HashMem(static_cast<unsigned char *>(empty_compressed),
40  sz_empty_compressed, &file_hash);
41  free(empty_compressed);
42 
44  deb.name_ = NameString(name);
45  deb.mode_ = S_IFREG | S_IRUSR | S_IWUSR;
46  deb.checksum_ = file_hash;
47  deb.mtime_ = time(NULL);
48  deb.uid_ = uid;
49  deb.gid_ = gid;
50  return deb;
51 }
52 
53 template<class CatalogMgrT>
55  XattrList xattr;
56  DirectoryEntry parent;
57  bool retval;
58  retval = catalog_mgr_->LookupPath(PathString(path), kLookupDefault, &parent);
59  assert(retval);
60  DirectoryEntryBase cvmfscatalog = MakeEmptyDirectoryEntryBase(
61  ".cvmfscatalog", parent.uid(), parent.gid());
62  DirectoryEntryBase cvmfsautocatalog = MakeEmptyDirectoryEntryBase(
63  ".cvmfsautocatalog", parent.uid(), parent.gid());
64  string relative_path = path.substr(1);
65  catalog_mgr_->AddFile(cvmfscatalog, xattr, relative_path);
66  catalog_mgr_->AddFile(cvmfsautocatalog, xattr, relative_path);
67 }
68 
69 template<class CatalogMgrT>
71  if (catalog == NULL) {
72  // obtain a copy of the catalogs
73  vector<catalog_t *> catalogs = catalog_mgr_->GetCatalogs();
74  // we need to reverse the catalog list in order to analyze the
75  // last added ones first. This is necessary in the weird case the child
76  // catalog's underflow provokes an overflow in the father
77  reverse(catalogs.begin(), catalogs.end());
78  for (unsigned i = 0; i < catalogs.size(); ++i)
79  Balance(catalogs[i]);
80  return;
81  }
82  string catalog_path = catalog->mountpoint().ToString();
83  virtual_node_t root_node(catalog_path, catalog_mgr_);
84  root_node.ExtractChildren(catalog_mgr_);
85  // we have just recursively loaded the entire virtual tree!
86  PartitionOptimally(&root_node);
87 }
88 
89 template<class CatalogMgrT>
91  virtual_node_t *virtual_node) {
92  // postorder track of the fs-tree
93  for (unsigned i = 0; i < virtual_node->children.size(); ++i) {
94  virtual_node_t *virtual_child = &virtual_node->children[i];
95  if (virtual_child->IsDirectory() && !virtual_child->IsCatalog())
96  PartitionOptimally(virtual_child);
97  }
98  virtual_node->FixWeight();
99  while (virtual_node->weight > catalog_mgr_->balance_weight_) {
100  virtual_node_t *heaviest_node = MaxChild(virtual_node);
101  // we directly add a catalog in this node
102  // TODO(molina) apply heuristics here
103  if (heaviest_node != NULL
104  && heaviest_node->weight >= catalog_mgr_->min_weight_) {
105  // the catalog now generated _cannot_ be overflowed because the tree is
106  // being traversed in postorder, handling the lightest nodes first
107  unsigned max_weight = heaviest_node->weight;
108  AddCatalogMarker(heaviest_node->path);
109  AddCatalog(heaviest_node);
110  virtual_node->weight -= (max_weight - 1);
111  } else {
112  // there is no possibility for any this directory's children
113  // to be a catalog
115  "Couldn't create a new nested catalog"
116  " in any subdirectory of '%s' even though"
117  " currently it is overflowed",
118  virtual_node->path.c_str());
119  break;
120  }
121  }
122 }
123 
124 template<class CatalogMgrT>
127  virtual_node_t *max_child = NULL;
128  unsigned max_weight = 0;
129  if (virtual_node->IsDirectory() && !virtual_node->IsCatalog()
130  && !virtual_node->is_new_nested_catalog) {
131  for (unsigned i = 0; i < virtual_node->children.size(); ++i) {
132  virtual_node_t *child = &virtual_node->children[i];
133  if (child->IsDirectory() && !child->IsCatalog()
134  && max_weight < child->weight) {
135  max_weight = child->weight;
136  max_child = child;
137  }
138  }
139  }
140  return max_child;
141 }
142 
143 template<class CatalogMgrT>
145  assert(child_node != NULL);
146  string new_catalog_path = child_node->path.substr(1);
147  catalog_mgr_->CreateNestedCatalog(new_catalog_path);
148  child_node->weight = 1;
149  child_node->is_new_nested_catalog = true;
151  "Automatic creation of nested"
152  " catalog in '%s'",
153  child_node->path.c_str());
154 }
155 
156 template<class CatalogMgrT>
158  CatalogMgrT *catalog_mgr) {
159  DirectoryEntryList direntlist;
160  catalog_mgr->Listing(path, &direntlist);
161  for (unsigned i = 0; i < direntlist.size(); ++i) {
162  string child_path = path + "/" + direntlist[i].name().ToString();
163  children.push_back(virtual_node_t(child_path, direntlist[i], catalog_mgr));
164  weight += children[i].weight;
165  }
166 }
167 
181 template<class CatalogMgrT>
183  weight = 1;
184  if (!IsCatalog() && IsDirectory()) {
185  for (unsigned i = 0; i < children.size(); ++i) {
186  weight += children[i].weight;
187  }
188  }
189 }
190 
191 } // namespace catalog
192 
193 #endif // CVMFS_CATALOG_BALANCER_IMPL_H_
ShortString< kDefaultMaxName, 1 > NameString
Definition: shortstring.h:214
gid_t gid_
void Balance(catalog_t *catalog)
assert((mem||(size==0))&&"Out Of Memory")
bool LookupPath(const PathString &path, const LookupOptions options, DirectoryEntry *entry)
CatalogMgrT::catalog_t catalog_t
const unsigned kLookupDefault
Definition: catalog_mgr.h:43
catalog::WritableCatalogManager * catalog_mgr_
Definition: repository.h:384
char algorithm
Algorithms
Definition: hash.h:41
NameString name_
std::vector< DirectoryEntry > DirectoryEntryList
time_t mtime_
void HashMem(const unsigned char *buffer, const unsigned buffer_size, Any *any_digest)
Definition: hash.cc:255
unsigned int mode_
ShortString< kDefaultMaxPath, 0 > PathString
Definition: shortstring.h:213
const std::vector< CatalogT * > & GetCatalogs() const
Definition: catalog_mgr.h:350
uid_t uid() const
bool CompressMem2Mem(const void *buf, const int64_t size, void **out_buf, uint64_t *out_size)
Definition: compression.cc:754
gid_t gid() const
void ExtractChildren(CatalogMgrT *catalog_mgr)
shash::Any checksum_
std::vector< VirtualNode > children
void AddFile(const DirectoryEntryBase &entry, const XattrList &xattrs, const std::string &parent_directory)
void CreateNestedCatalog(const std::string &mountpoint)
uid_t uid_
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)
Definition: logging.cc:545