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