CernVM-FS  2.13.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
cache_tiered.cc
Go to the documentation of this file.
1 
5 #include "cache_tiered.h"
6 
7 #include <errno.h>
8 
9 #include <string>
10 #include <vector>
11 
12 #include "quota.h"
13 #include "util/platform.h"
14 #include "util/posix.h"
15 
16 
18  return "Tiered Cache\n"
19  " - upper layer: "
20  + upper_->Describe() + " - lower layer: " + lower_->Describe();
21 }
22 
23 
25  SavedState *state = reinterpret_cast<SavedState *>(data);
26  upper_->FreeState(-1, state->state_upper);
27  lower_->FreeState(-1, state->state_lower);
28  delete state;
29  return true;
30 }
31 
32 
34  SavedState *state = reinterpret_cast<SavedState *>(data);
35  const int new_root_fd = upper_->RestoreState(-1, state->state_upper);
36  // The lower cache layer does not keep the root catalog open
37  const int retval = lower_->RestoreState(-1, state->state_lower);
38  assert(retval == -1);
39  return new_root_fd;
40 }
41 
42 
44  SavedState *state = new SavedState();
45  state->state_upper = upper_->SaveState(-1);
46  state->state_lower = lower_->SaveState(-1);
47  return state;
48 }
49 
50 
52  const int fd = upper_->Open(object);
53  if ((fd >= 0) || (fd != -ENOENT)) {
54  return fd;
55  }
56 
57  const int fd2 = lower_->Open(object);
58  if (fd2 < 0) {
59  return fd;
60  } // NOTE: use error code from upper.
61 
62  // Lower cache hit; upper cache miss. Copy object into the upper cache.
63  const int64_t size = lower_->GetSize(fd2);
64  if (size < 0) {
65  lower_->Close(fd2);
66  return fd;
67  }
68 
69  void *txn = alloca(upper_->SizeOfTxn());
70  if (upper_->StartTxn(object.id, size, txn) < 0) {
71  lower_->Close(fd2);
72  return fd;
73  }
74  upper_->CtrlTxn(object.label, 0, txn);
75 
76  std::vector<char> m_buffer;
77  m_buffer.resize(kCopyBufferSize);
78  uint64_t remaining = size;
79  uint64_t offset = 0;
80  while (remaining > 0) {
81  const unsigned nbytes =
82  remaining > kCopyBufferSize ? kCopyBufferSize : remaining;
83  int64_t result = lower_->Pread(fd2, &m_buffer[0], nbytes, offset);
84  // The file we are reading is supposed to be exactly `size` bytes.
85  if ((result < 0) || (result != nbytes)) {
86  lower_->Close(fd2);
87  upper_->AbortTxn(txn);
88  return fd;
89  }
90  result = upper_->Write(&m_buffer[0], nbytes, txn);
91  if (result < 0) {
92  lower_->Close(fd2);
93  upper_->AbortTxn(txn);
94  return fd;
95  }
96  offset += nbytes;
97  remaining -= nbytes;
98  }
99  lower_->Close(fd2);
100  const int fd_return = upper_->OpenFromTxn(txn);
101  if (fd_return < 0) {
102  upper_->AbortTxn(txn);
103  return fd;
104  }
105  if (upper_->CommitTxn(txn) < 0) {
106  upper_->Close(fd_return);
107  return fd;
108  }
109  return fd_return;
110 }
111 
112 
114  uint64_t size,
115  void *txn) {
116  const int upper_result = upper_->StartTxn(id, size, txn);
117  if (lower_readonly_ || (upper_result < 0)) {
118  return upper_result;
119  }
120 
121  void *txn2 = static_cast<char *>(txn) + upper_->SizeOfTxn();
122  const int lower_result = lower_->StartTxn(id, size, txn2);
123  if (lower_result < 0) {
124  upper_->AbortTxn(txn);
125  }
126  return lower_result;
127 }
128 
129 
131  CacheManager *lower_cache) {
132  TieredCacheManager *cache_mgr = new TieredCacheManager(upper_cache,
133  lower_cache);
134  delete cache_mgr->quota_mgr_;
135  cache_mgr->quota_mgr_ = upper_cache->quota_mgr();
136 
137  return cache_mgr;
138 }
139 
140 
142  const int flags,
143  void *txn) {
144  upper_->CtrlTxn(label, flags, txn);
145  if (!lower_readonly_) {
146  void *txn2 = static_cast<char *>(txn) + upper_->SizeOfTxn();
147  lower_->CtrlTxn(label, flags, txn2);
148  }
149 }
150 
151 
152 int64_t TieredCacheManager::Write(const void *buf, uint64_t size, void *txn) {
153  const int upper_result = upper_->Write(buf, size, txn);
154  if (lower_readonly_ || (upper_result < 0)) {
155  return upper_result;
156  }
157 
158  void *txn2 = static_cast<char *>(txn) + upper_->SizeOfTxn();
159  return lower_->Write(buf, size, txn2);
160 }
161 
162 
164  const int upper_result = upper_->Reset(txn);
165 
166  int lower_result = upper_result;
167  if (!lower_readonly_) {
168  void *txn2 = static_cast<char *>(txn) + upper_->SizeOfTxn();
169  lower_result = lower_->Reset(txn2);
170  }
171 
172  return (upper_result < 0) ? upper_result : lower_result;
173 }
174 
175 
177  const int upper_result = upper_->AbortTxn(txn);
178 
179  int lower_result = upper_result;
180  if (!lower_readonly_) {
181  void *txn2 = static_cast<char *>(txn) + upper_->SizeOfTxn();
182  lower_result = lower_->AbortTxn(txn2);
183  }
184 
185  return (upper_result < 0) ? upper_result : lower_result;
186 }
187 
188 
190  const int upper_result = upper_->CommitTxn(txn);
191 
192  int lower_result = upper_result;
193  if (!lower_readonly_) {
194  void *txn2 = static_cast<char *>(txn) + upper_->SizeOfTxn();
195  lower_result = lower_->CommitTxn(txn2);
196  }
197 
198  return (upper_result < 0) ? upper_result : lower_result;
199 }
200 
201 
203  const std::string &fqrn) {
204  manifest::Breadcrumb breadcrumb = upper_->LoadBreadcrumb(fqrn);
205  if (!breadcrumb.IsValid())
206  breadcrumb = lower_->LoadBreadcrumb(fqrn);
207  return breadcrumb;
208 }
209 
210 
212  const bool upper_success = upper_->StoreBreadcrumb(manifest);
213  bool lower_success = true;
214  if (!lower_readonly_)
215  lower_success = lower_->StoreBreadcrumb(manifest);
216  return upper_success && lower_success;
217 }
218 
219 
221  upper_->Spawn();
222  lower_->Spawn();
223 }
224 
225 
227  quota_mgr_ = NULL; // gets deleted by upper
228  delete upper_;
229  delete lower_;
230 }
const manifest::Manifest * manifest() const
Definition: repository.h:125
virtual int64_t GetSize(int fd)=0
virtual int AbortTxn(void *txn)
int RestoreState(const int fd_progress, void *state)
Definition: cache.cc:182
virtual void Spawn()=0
virtual manifest::Breadcrumb LoadBreadcrumb(const std::string &)
Definition: cache.h:215
void * SaveState(const int fd_progress)
Definition: cache.cc:211
assert((mem||(size==0))&&"Out Of Memory")
virtual int AbortTxn(void *txn)=0
virtual bool StoreBreadcrumb(const manifest::Manifest &)
Definition: cache.h:218
virtual bool DoFreeState(void *data)
Definition: cache_tiered.cc:24
virtual void * DoSaveState()
Definition: cache_tiered.cc:43
virtual std::string Describe()
Definition: cache_tiered.cc:17
TieredCacheManager(CacheManager *upper_cache, CacheManager *lower_cache)
Definition: cache_tiered.h:84
virtual int Open(const LabeledObject &object)=0
virtual int Reset(void *txn)
static CacheManager * Create(CacheManager *upper_cache, CacheManager *lower_cache)
virtual int CommitTxn(void *txn)=0
virtual int Open(const LabeledObject &object)
Definition: cache_tiered.cc:51
virtual int OpenFromTxn(void *txn)=0
virtual int CommitTxn(void *txn)
virtual void CtrlTxn(const Label &label, const int flags, void *txn)
virtual int DoRestoreState(void *data)
Definition: cache_tiered.cc:33
virtual int Close(int fd)=0
virtual int64_t Write(const void *buf, uint64_t size, void *txn)
virtual int Reset(void *txn)=0
void FreeState(const int fd_progress, void *state)
Definition: cache.cc:95
CacheManager * lower_
Definition: cache_tiered.h:88
virtual void CtrlTxn(const Label &label, const int flags, void *txn)=0
CacheManager * upper_
Definition: cache_tiered.h:87
QuotaManager * quota_mgr()
Definition: cache.h:191
static const unsigned kCopyBufferSize
Definition: cache_tiered.h:75
virtual int StartTxn(const shash::Any &id, uint64_t size, void *txn)
QuotaManager * quota_mgr_
Definition: cache.h:233
virtual uint32_t SizeOfTxn()=0
bool IsValid() const
Definition: manifest.h:33
virtual manifest::Breadcrumb LoadBreadcrumb(const std::string &fqrn)
virtual ~TieredCacheManager()
virtual int StartTxn(const shash::Any &id, uint64_t size, void *txn)=0
virtual void Spawn()
static void size_t size
Definition: smalloc.h:54
virtual int64_t Pread(int fd, void *buf, uint64_t size, uint64_t offset)=0
virtual bool StoreBreadcrumb(const manifest::Manifest &manifest)
virtual std::string Describe()=0
virtual int64_t Write(const void *buf, uint64_t sz, void *txn)=0