CernVM-FS  2.13.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
file_chunk.cc
Go to the documentation of this file.
1 
6 #include "file_chunk.h"
7 
8 #include <cassert>
9 
10 #include "util/murmur.hxx"
11 #include "util/platform.h"
12 
13 using namespace std; // NOLINT
14 
15 static inline uint32_t hasher_uint64t(const uint64_t &value) {
16  return MurmurHash2(&value, sizeof(value), 0x07387a4f);
17 }
18 
19 
20 //------------------------------------------------------------------------------
21 
22 
23 unsigned FileChunkReflist::FindChunkIdx(const uint64_t off) {
24  assert(list && (list->size() > 0));
25  unsigned idx_low = 0;
26  unsigned idx_high = list->size() - 1;
27  unsigned chunk_idx = idx_high / 2;
28  while (idx_low < idx_high) {
29  if (static_cast<uint64_t>(list->AtPtr(chunk_idx)->offset()) > off) {
30  assert(idx_high > 0);
31  idx_high = chunk_idx - 1;
32  } else {
33  if ((chunk_idx == list->size() - 1)
34  || (static_cast<uint64_t>(list->AtPtr(chunk_idx + 1)->offset())
35  > off)) {
36  break;
37  }
38  idx_low = chunk_idx + 1;
39  }
40  chunk_idx = idx_low + (idx_high - idx_low) / 2;
41  }
42  return chunk_idx;
43 }
44 
45 
50  shash::Algorithms algo = list->AtPtr(0)->content_hash().algorithm;
51  shash::ContextPtr ctx(algo);
52  ctx.buffer = alloca(ctx.size);
53  shash::Init(ctx);
54  for (unsigned i = 0; i < list->size(); ++i) {
56  list->AtPtr(i)->content_hash().digest, shash::kDigestSizes[algo], ctx);
57  }
58  shash::Any result(algo);
59  shash::Final(ctx, &result);
60  return result;
61 }
62 
63 
64 //------------------------------------------------------------------------------
65 
66 
68  lock = reinterpret_cast<pthread_mutex_t *>(smalloc(sizeof(pthread_mutex_t)));
69  int retval = pthread_mutex_init(lock, NULL);
70  assert(retval == 0);
71 
72  for (unsigned i = 0; i < kNumHandleLocks; ++i) {
73  pthread_mutex_t *m = reinterpret_cast<pthread_mutex_t *>(
74  smalloc(sizeof(pthread_mutex_t)));
75  int retval = pthread_mutex_init(m, NULL);
76  assert(retval == 0);
77  handle_locks.PushBack(m);
78  }
79 }
80 
81 
83  handle2uniqino.Init(16, 0, hasher_uint64t);
84  handle2fd.Init(16, 0, hasher_uint64t);
85  inode2chunks.Init(16, 0, hasher_uint64t);
86  inode2references.Init(16, 0, hasher_uint64t);
87 }
88 
89 
91  next_handle = 2;
92  version = kVersion;
93  InitLocks();
94  InitHashmaps();
95 }
96 
97 
99  pthread_mutex_destroy(lock);
100  free(lock);
101  for (unsigned i = 0; i < kNumHandleLocks; ++i) {
102  pthread_mutex_destroy(handle_locks.At(i));
103  free(handle_locks.At(i));
104  }
105 }
106 
107 
109  version = kVersion;
110  InitLocks();
111  InitHashmaps();
112  CopyFrom(other);
113 }
114 
115 
117  if (&other == this)
118  return *this;
119 
120  handle2uniqino.Clear();
121  handle2fd.Clear();
122  inode2chunks.Clear();
123  inode2references.Clear();
124  CopyFrom(other);
125  return *this;
126 }
127 
128 
129 void ChunkTables::CopyFrom(const ChunkTables &other) {
130  assert(version == other.version);
131  next_handle = other.next_handle;
132  inode2references = other.inode2references;
133  inode2chunks = other.inode2chunks;
134  handle2fd = other.handle2fd;
135  handle2uniqino = other.handle2uniqino;
136 }
137 
138 
139 pthread_mutex_t *ChunkTables::Handle2Lock(const uint64_t handle) const {
140  const uint32_t hash = hasher_uint64t(handle);
141  const double bucket = static_cast<double>(hash)
142  * static_cast<double>(kNumHandleLocks)
143  / static_cast<double>((uint32_t)(-1));
144  return handle_locks.At((uint32_t)bucket % kNumHandleLocks);
145 }
146 
147 
148 //------------------------------------------------------------------------------
149 
150 
152  lock_ = reinterpret_cast<pthread_mutex_t *>(smalloc(sizeof(pthread_mutex_t)));
153  int retval = pthread_mutex_init(lock_, NULL);
154  assert(retval == 0);
155 }
156 
157 
159  for (unsigned i = 0; i < fd_table_.size(); ++i) {
160  delete fd_table_[i].chunk_reflist.list;
161  }
162  pthread_mutex_destroy(lock_);
163  free(lock_);
164 }
165 
166 
168  assert(chunks.list != NULL);
169  OpenChunks new_entry;
170  new_entry.chunk_reflist = chunks;
171  new_entry.chunk_fd = new ChunkFd();
172  unsigned i = 0;
173  Lock();
174  for (; i < fd_table_.size(); ++i) {
175  if (fd_table_[i].chunk_reflist.list == NULL) {
176  fd_table_[i] = new_entry;
177  Unlock();
178  return i;
179  }
180  }
181  fd_table_.push_back(new_entry);
182  Unlock();
183  return i;
184 }
185 
186 
188  OpenChunks result;
189  if (fd < 0)
190  return result;
191 
192  unsigned idx = static_cast<unsigned>(fd);
193  Lock();
194  if (idx < fd_table_.size())
195  result = fd_table_[idx];
196  Unlock();
197  return result;
198 }
199 
200 
202  if (fd < 0)
203  return;
204 
205  Lock();
206  unsigned idx = static_cast<unsigned>(fd);
207  if (idx >= fd_table_.size()) {
208  Unlock();
209  return;
210  }
211 
212  delete fd_table_[idx].chunk_reflist.list;
213  fd_table_[idx].chunk_reflist.list = NULL;
214  fd_table_[idx].chunk_reflist.path.Assign("", 0);
215  delete fd_table_[idx].chunk_fd;
216  fd_table_[idx].chunk_fd = NULL;
217  while (!fd_table_.empty() && (fd_table_.back().chunk_reflist.list == NULL)) {
218  fd_table_.pop_back();
219  }
220  Unlock();
221 }
struct cvmcache_context * ctx
FileChunkReflist chunk_reflist
Definition: file_chunk.h:140
void Lock()
SmallHashDynamic< uint64_t, uint64_t > handle2uniqino
Definition: file_chunk.h:113
OpenChunks Get(int fd)
Definition: file_chunk.cc:187
assert((mem||(size==0))&&"Out Of Memory")
Algorithms algorithm
Definition: hash.h:122
static uint32_t hasher_uint64t(const uint64_t &value)
Definition: file_chunk.cc:15
SmallHashDynamic< uint64_t, ChunkFd > handle2fd
Definition: file_chunk.h:114
void Init(ContextPtr context)
Definition: hash.cc:166
Algorithms
Definition: hash.h:41
pthread_mutex_t * Handle2Lock(const uint64_t handle) const
Definition: file_chunk.cc:139
unsigned FindChunkIdx(const uint64_t offset)
Definition: file_chunk.cc:23
void Final(ContextPtr context, Any *any_digest)
Definition: hash.cc:223
SmallHashDynamic< uint64_t, uint32_t > inode2references
Definition: file_chunk.h:119
ChunkTables & operator=(const ChunkTables &other)
Definition: file_chunk.cc:116
void * buffer
Definition: hash.h:489
int Add(FileChunkReflist chunks)
Definition: file_chunk.cc:167
void InitLocks()
Definition: file_chunk.cc:67
void Update(const unsigned char *buffer, const unsigned buffer_length, ContextPtr context)
Definition: hash.cc:192
uint64_t next_handle
Definition: file_chunk.h:120
shash::Any HashChunkList()
Definition: file_chunk.cc:49
void Release(int fd)
Definition: file_chunk.cc:201
void InitHashmaps()
Definition: file_chunk.cc:82
const char * kVersion
Definition: preload.cc:26
unsigned size
Definition: hash.h:490
void CopyFrom(const ChunkTables &other)
Definition: file_chunk.cc:129
const unsigned kDigestSizes[]
Definition: hash.h:69
SmallHashDynamic< uint64_t, FileChunkReflist > inode2chunks
Definition: file_chunk.h:118
FileChunkList * list
Definition: file_chunk.h:63
uint32_t MurmurHash2(const void *key, int len, uint32_t seed)
Definition: murmur.hxx:23