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  int new_root_fd = upper_->RestoreState(-1, state->state_upper);
36  // The lower cache layer does not keep the root catalog open
37  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  int fd = upper_->Open(object);
53  if ((fd >= 0) || (fd != -ENOENT)) {
54  return fd;
55  }
56 
57  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  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  unsigned nbytes = remaining > kCopyBufferSize ? kCopyBufferSize : remaining;
82  int64_t result = lower_->Pread(fd2, &m_buffer[0], nbytes, offset);
83  // The file we are reading is supposed to be exactly `size` bytes.
84  if ((result < 0) || (result != nbytes)) {
85  lower_->Close(fd2);
86  upper_->AbortTxn(txn);
87  return fd;
88  }
89  result = upper_->Write(&m_buffer[0], nbytes, txn);
90  if (result < 0) {
91  lower_->Close(fd2);
92  upper_->AbortTxn(txn);
93  return fd;
94  }
95  offset += nbytes;
96  remaining -= nbytes;
97  }
98  lower_->Close(fd2);
99  int fd_return = upper_->OpenFromTxn(txn);
100  if (fd_return < 0) {
101  upper_->AbortTxn(txn);
102  return fd;
103  }
104  if (upper_->CommitTxn(txn) < 0) {
105  upper_->Close(fd_return);
106  return fd;
107  }
108  return fd_return;
109 }
110 
111 
113  uint64_t size,
114  void *txn) {
115  int upper_result = upper_->StartTxn(id, size, txn);
116  if (lower_readonly_ || (upper_result < 0)) {
117  return upper_result;
118  }
119 
120  void *txn2 = static_cast<char *>(txn) + upper_->SizeOfTxn();
121  int lower_result = lower_->StartTxn(id, size, txn2);
122  if (lower_result < 0) {
123  upper_->AbortTxn(txn);
124  }
125  return lower_result;
126 }
127 
128 
130  CacheManager *lower_cache) {
131  TieredCacheManager *cache_mgr = new TieredCacheManager(upper_cache,
132  lower_cache);
133  delete cache_mgr->quota_mgr_;
134  cache_mgr->quota_mgr_ = upper_cache->quota_mgr();
135 
136  return cache_mgr;
137 }
138 
139 
141  const int flags,
142  void *txn) {
143  upper_->CtrlTxn(label, flags, txn);
144  if (!lower_readonly_) {
145  void *txn2 = static_cast<char *>(txn) + upper_->SizeOfTxn();
146  lower_->CtrlTxn(label, flags, txn2);
147  }
148 }
149 
150 
151 int64_t TieredCacheManager::Write(const void *buf, uint64_t size, void *txn) {
152  int upper_result = upper_->Write(buf, size, txn);
153  if (lower_readonly_ || (upper_result < 0)) {
154  return upper_result;
155  }
156 
157  void *txn2 = static_cast<char *>(txn) + upper_->SizeOfTxn();
158  return lower_->Write(buf, size, txn2);
159 }
160 
161 
163  int upper_result = upper_->Reset(txn);
164 
165  int lower_result = upper_result;
166  if (!lower_readonly_) {
167  void *txn2 = static_cast<char *>(txn) + upper_->SizeOfTxn();
168  lower_result = lower_->Reset(txn2);
169  }
170 
171  return (upper_result < 0) ? upper_result : lower_result;
172 }
173 
174 
176  int upper_result = upper_->AbortTxn(txn);
177 
178  int lower_result = upper_result;
179  if (!lower_readonly_) {
180  void *txn2 = static_cast<char *>(txn) + upper_->SizeOfTxn();
181  lower_result = lower_->AbortTxn(txn2);
182  }
183 
184  return (upper_result < 0) ? upper_result : lower_result;
185 }
186 
187 
189  int upper_result = upper_->CommitTxn(txn);
190 
191  int lower_result = upper_result;
192  if (!lower_readonly_) {
193  void *txn2 = static_cast<char *>(txn) + upper_->SizeOfTxn();
194  lower_result = lower_->CommitTxn(txn2);
195  }
196 
197  return (upper_result < 0) ? upper_result : lower_result;
198 }
199 
200 
202  const std::string &fqrn) {
203  manifest::Breadcrumb breadcrumb = upper_->LoadBreadcrumb(fqrn);
204  if (!breadcrumb.IsValid())
205  breadcrumb = lower_->LoadBreadcrumb(fqrn);
206  return breadcrumb;
207 }
208 
209 
211  bool upper_success = upper_->StoreBreadcrumb(manifest);
212  bool lower_success = true;
213  if (!lower_readonly_)
214  lower_success = lower_->StoreBreadcrumb(manifest);
215  return upper_success && lower_success;
216 }
217 
218 
220  upper_->Spawn();
221  lower_->Spawn();
222 }
223 
224 
226  quota_mgr_ = NULL; // gets deleted by upper
227  delete upper_;
228  delete lower_;
229 }
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