CernVM-FS  2.10.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
glue_buffer.h
Go to the documentation of this file.
1 
11 #include <gtest/gtest_prod.h>
12 #include <pthread.h>
13 #include <sched.h>
14 #include <stdint.h>
15 
16 #include <cassert>
17 #include <cstring>
18 #include <map>
19 #include <string>
20 #include <vector>
21 
22 #include "atomic.h"
23 #include "bigqueue.h"
24 #include "bigvector.h"
25 #include "hash.h"
26 #include "platform.h"
27 #include "shortstring.h"
28 #include "smallhash.h"
29 #include "smalloc.h"
30 #include "util/posix.h"
31 #include "util/string.h"
32 
33 #ifndef CVMFS_GLUE_BUFFER_H_
34 #define CVMFS_GLUE_BUFFER_H_
35 
36 namespace glue {
37 
38 static inline uint32_t hasher_md5(const shash::Md5 &key) {
39  // Don't start with the first bytes, because == is using them as well
40  return (uint32_t) *(reinterpret_cast<const uint32_t *>(key.digest) + 1);
41 }
42 
43 
44 static inline uint32_t hasher_inode(const uint64_t &inode) {
45  return MurmurHash2(&inode, sizeof(inode), 0x07387a4f);
46 }
47 
48 
49 //------------------------------------------------------------------------------
50 
51 
55 class StringRef {
56  public:
58  length_ = NULL;
59  }
60 
61  uint16_t length() const { return *length_; }
62  uint16_t size() const { return sizeof(uint16_t) + *length_; }
63  static uint16_t size(const uint16_t length) {
64  return sizeof(uint16_t) + length;
65  }
66  char *data() const { return reinterpret_cast<char *>(length_ + 1); }
67  static StringRef Place(const uint16_t length, const char *str,
68  void *addr)
69  {
70  StringRef result;
71  result.length_ = reinterpret_cast<uint16_t *>(addr);
72  *result.length_ = length;
73  if (length > 0)
74  memcpy(result.length_ + 1, str, length);
75  return result;
76  }
77  private:
78  uint16_t *length_;
79 };
80 
81 
82 //------------------------------------------------------------------------------
83 
84 
90 class StringHeap : public SingleCopy {
91  public:
93  Init(128*1024); // 128kB (should be >= 64kB+2B which is largest string)
94  }
95 
96  explicit StringHeap(const uint64_t minimum_size) {
97  Init(minimum_size);
98  }
99 
100  void Init(const uint64_t minimum_size) {
101  size_ = 0;
102  used_ = 0;
103 
104  // Initial bin: 128kB or smallest power of 2 >= minimum size
105  uint64_t pow2_size = 128 * 1024;
106  while (pow2_size < minimum_size)
107  pow2_size *= 2;
108  AddBin(pow2_size);
109  }
110 
112  for (unsigned i = 0; i < bins_.size(); ++i) {
113  smunmap(bins_.At(i));
114  }
115  }
116 
117  StringRef AddString(const uint16_t length, const char *str) {
118  const uint16_t str_size = StringRef::size(length);
119  const uint64_t remaining_bin_size = bin_size_ - bin_used_;
120  // May require opening of new bin
121  if (remaining_bin_size < str_size) {
122  size_ += remaining_bin_size;
123  AddBin(2*bin_size_);
124  }
125  StringRef result =
126  StringRef::Place(length, str,
127  static_cast<char *>(bins_.At(bins_.size()-1))+bin_used_);
128  size_ += str_size;
129  used_ += str_size;
130  bin_used_ += str_size;
131  return result;
132  }
133 
134  void RemoveString(const StringRef str_ref) {
135  used_ -= str_ref.size();
136  }
137 
138  double GetUsage() const {
139  if (size_ == 0) return 1.0;
140  return static_cast<double>(used_) / static_cast<double>(size_);
141  }
142 
143  uint64_t used() const { return used_; }
144 
145  // mmap'd bytes, used for testing
146  uint64_t GetSizeAlloc() const {
147  uint64_t s = bin_size_;
148  uint64_t result = 0;
149  for (unsigned i = 0; i < bins_.size(); ++i) {
150  result += s;
151  s /= 2;
152  }
153  return result;
154  }
155 
156  private:
157  void AddBin(const uint64_t size) {
158  void *bin = smmap(size);
159  bins_.PushBack(bin);
160  bin_size_ = size;
161  bin_used_ = 0;
162  }
163 
164  uint64_t size_;
165  uint64_t used_;
166  uint64_t bin_size_;
167  uint64_t bin_used_;
169 };
170 
171 
172 //------------------------------------------------------------------------------
173 
174 
175 class PathStore {
176  public:
180  struct Cursor {
181  Cursor() : idx(0) { }
182  uint32_t idx;
183  };
184 
185 
187  map_.Init(16, shash::Md5(shash::AsciiPtr("!")), hasher_md5);
188  string_heap_ = new StringHeap();
189  }
190 
192  delete string_heap_;
193  }
194 
195  explicit PathStore(const PathStore &other);
196  PathStore &operator= (const PathStore &other);
197 
198  void Insert(const shash::Md5 &md5path, const PathString &path) {
199  PathInfo info;
200  bool found = map_.Lookup(md5path, &info);
201  if (found) {
202  info.refcnt++;
203  map_.Insert(md5path, info);
204  return;
205  }
206 
207  PathInfo new_entry;
208  if (path.IsEmpty()) {
209  new_entry.name = string_heap_->AddString(0, "");
210  map_.Insert(md5path, new_entry);
211  return;
212  }
213 
214  PathString parent_path = GetParentPath(path);
215  new_entry.parent = shash::Md5(parent_path.GetChars(),
216  parent_path.GetLength());
217  Insert(new_entry.parent, parent_path);
218 
219  const uint16_t name_length = path.GetLength() - parent_path.GetLength() - 1;
220  const char *name_str = path.GetChars() + parent_path.GetLength() + 1;
221  new_entry.name = string_heap_->AddString(name_length, name_str);
222  map_.Insert(md5path, new_entry);
223  }
224 
225  bool Lookup(const shash::Md5 &md5path, PathString *path) {
226  PathInfo info;
227  bool retval = map_.Lookup(md5path, &info);
228  if (!retval)
229  return false;
230 
231  if (info.parent.IsNull())
232  return true;
233 
234  retval = Lookup(info.parent, path);
235  assert(retval);
236  path->Append("/", 1);
237  path->Append(info.name.data(), info.name.length());
238  return true;
239  }
240 
241  void Erase(const shash::Md5 &md5path) {
242  PathInfo info;
243  bool found = map_.Lookup(md5path, &info);
244  if (!found)
245  return;
246 
247  info.refcnt--;
248  if (info.refcnt == 0) {
249  map_.Erase(md5path);
251  if (string_heap_->GetUsage() < 0.75) {
252  StringHeap *new_string_heap = new StringHeap(string_heap_->used());
253  shash::Md5 empty_path = map_.empty_key();
254  for (unsigned i = 0; i < map_.capacity(); ++i) {
255  if (map_.keys()[i] != empty_path) {
256  (map_.values() + i)->name =
257  new_string_heap->AddString(map_.values()[i].name.length(),
258  map_.values()[i].name.data());
259  }
260  }
261  delete string_heap_;
262  string_heap_ = new_string_heap;
263  }
264  Erase(info.parent);
265  } else {
266  map_.Insert(md5path, info);
267  }
268  }
269 
270  void Clear() {
271  map_.Clear();
272  delete string_heap_;
273  string_heap_ = new StringHeap();
274  }
275 
277  return Cursor();
278  }
279 
280  bool Next(Cursor *cursor, shash::Md5 *parent, StringRef *name) {
281  shash::Md5 empty_key = map_.empty_key();
282  while (cursor->idx < map_.capacity()) {
283  if (map_.keys()[cursor->idx] == empty_key) {
284  cursor->idx++;
285  continue;
286  }
287  *parent = map_.values()[cursor->idx].parent;
288  *name = map_.values()[cursor->idx].name;
289  cursor->idx++;
290  return true;
291  }
292  return false;
293  }
294 
295  private:
296  struct PathInfo {
298  refcnt = 1;
299  }
301  uint32_t refcnt;
303  };
304 
305  void CopyFrom(const PathStore &other);
306 
309 };
310 
311 
312 //------------------------------------------------------------------------------
313 
314 
315 class PathMap {
316  public:
319  }
320 
321  bool LookupPath(const shash::Md5 &md5path, PathString *path) {
322  bool found = path_store_.Lookup(md5path, path);
323  return found;
324  }
325 
326  uint64_t LookupInodeByPath(const PathString &path) {
327  uint64_t inode;
328  bool found = map_.Lookup(shash::Md5(path.GetChars(), path.GetLength()),
329  &inode);
330  if (found) return inode;
331  return 0;
332  }
333 
334  uint64_t LookupInodeByMd5Path(const shash::Md5 &md5path) {
335  uint64_t inode;
336  bool found = map_.Lookup(md5path, &inode);
337  if (found) return inode;
338  return 0;
339  }
340 
341  shash::Md5 Insert(const PathString &path, const uint64_t inode) {
342  shash::Md5 md5path(path.GetChars(), path.GetLength());
343  if (!map_.Contains(md5path)) {
344  path_store_.Insert(md5path, path);
345  map_.Insert(md5path, inode);
346  }
347  return md5path;
348  }
349 
350  void Erase(const shash::Md5 &md5path) {
351  bool found = map_.Contains(md5path);
352  if (found) {
353  path_store_.Erase(md5path);
354  map_.Erase(md5path);
355  }
356  }
357 
358  void Clear() {
359  map_.Clear();
360  path_store_.Clear();
361  }
362 
363  // For enumerating
365 
366  private:
369 };
370 
371 
372 //------------------------------------------------------------------------------
373 
374 
375 class InodeMap {
376  public:
378  map_.Init(16, 0, hasher_inode);
379  }
380 
381  bool LookupMd5Path(const uint64_t inode, shash::Md5 *md5path) {
382  bool found = map_.Lookup(inode, md5path);
383  return found;
384  }
385 
386  void Insert(const uint64_t inode, const shash::Md5 &md5path) {
387  map_.Insert(inode, md5path);
388  }
389 
390  void Erase(const uint64_t inode) {
391  map_.Erase(inode);
392  }
393 
394  void Clear() { map_.Clear(); }
395 
396  private:
398 };
399 
400 
401 //------------------------------------------------------------------------------
402 
403 
405  public:
409  struct Cursor {
410  Cursor() : idx(0) { }
411  uint32_t idx;
412  };
413 
415  map_.Init(16, 0, hasher_inode);
416  }
417 
418  bool Get(const uint64_t inode, const uint32_t by) {
419  uint32_t refcounter = 0;
420  const bool found = map_.Lookup(inode, &refcounter);
421  const bool new_inode = !found;
422  refcounter += by; // This is 0 if the inode is not found
423  map_.Insert(inode, refcounter);
424  return new_inode;
425  }
426 
427  bool Put(const uint64_t inode, const uint32_t by) {
428  uint32_t refcounter;
429  bool found = map_.Lookup(inode, &refcounter);
430  assert(found);
431  assert(refcounter >= by);
432  if (refcounter == by) {
433  map_.Erase(inode);
434  return true;
435  }
436  refcounter -= by;
437  map_.Insert(inode, refcounter);
438  return false;
439  }
440 
441  void Clear() {
442  map_.Clear();
443  }
444 
446  return Cursor();
447  }
448 
449  bool Next(Cursor *cursor, uint64_t *inode) {
450  uint64_t empty_key = map_.empty_key();
451  while (cursor->idx < map_.capacity()) {
452  if (map_.keys()[cursor->idx] == empty_key) {
453  cursor->idx++;
454  continue;
455  }
456  *inode = map_.keys()[cursor->idx];
457  cursor->idx++;
458  return true;
459  }
460  return false;
461  }
462 
463  private:
465 };
466 
467 
468 //------------------------------------------------------------------------------
469 
470 
475  public:
479  struct Cursor {
480  explicit Cursor(
481  const PathStore::Cursor &p,
482  const InodeReferences::Cursor &i)
483  : csr_paths(p)
484  , csr_inos(i)
485  { }
488  };
489 
490  // Cannot be moved to the statistics manager because it has to survive
491  // reloads. Added manually in the fuse module initialization and in talk.cc.
492  struct Statistics {
494  atomic_init64(&num_inserts);
495  atomic_init64(&num_removes);
496  atomic_init64(&num_references);
497  atomic_init64(&num_hits_inode);
498  atomic_init64(&num_hits_path);
499  atomic_init64(&num_misses_path);
500  }
501  std::string Print() {
502  return
503  "inserts: " + StringifyInt(atomic_read64(&num_inserts)) +
504  " removes: " + StringifyInt(atomic_read64(&num_removes)) +
505  " references: " + StringifyInt(atomic_read64(&num_references)) +
506  " hits(inode): " + StringifyInt(atomic_read64(&num_hits_inode)) +
507  " hits(path): " + StringifyInt(atomic_read64(&num_hits_path)) +
508  " misses(path): " + StringifyInt(atomic_read64(&num_misses_path));
509  }
516  };
518 
519  InodeTracker();
520  explicit InodeTracker(const InodeTracker &other);
521  InodeTracker &operator= (const InodeTracker &other);
522  ~InodeTracker();
523 
524  void VfsGetBy(const uint64_t inode, const uint32_t by, const PathString &path)
525  {
526  Lock();
527  bool new_inode = inode_references_.Get(inode, by);
528  shash::Md5 md5path = path_map_.Insert(path, inode);
529  inode_map_.Insert(inode, md5path);
530  Unlock();
531 
532  atomic_xadd64(&statistics_.num_references, by);
533  if (new_inode) atomic_inc64(&statistics_.num_inserts);
534  }
535 
536  void VfsGet(const uint64_t inode, const PathString &path) {
537  VfsGetBy(inode, 1, path);
538  }
539 
540  void VfsPut(const uint64_t inode, const uint32_t by) {
541  Lock();
542  bool removed = inode_references_.Put(inode, by);
543  if (removed) {
544  // TODO(jblomer): pop operation (Lookup+Erase)
545  shash::Md5 md5path;
546  bool found = inode_map_.LookupMd5Path(inode, &md5path);
547  assert(found);
548  inode_map_.Erase(inode);
549  path_map_.Erase(md5path);
550  atomic_inc64(&statistics_.num_removes);
551  }
552  Unlock();
553  atomic_xadd64(&statistics_.num_references, -int32_t(by));
554  }
555 
556  bool FindPath(const uint64_t inode, PathString *path) {
557  Lock();
558  shash::Md5 md5path;
559  bool found = inode_map_.LookupMd5Path(inode, &md5path);
560  if (found) {
561  found = path_map_.LookupPath(md5path, path);
562  assert(found);
563  }
564  Unlock();
565 
566  if (found) {
567  atomic_inc64(&statistics_.num_hits_path);
568  } else {
569  atomic_inc64(&statistics_.num_misses_path);
570  }
571  return found;
572  }
573 
574  uint64_t FindInode(const PathString &path) {
575  Lock();
576  uint64_t inode = path_map_.LookupInodeByPath(path);
577  Unlock();
578  atomic_inc64(&statistics_.num_hits_inode);
579  return inode;
580  }
581 
583  Lock();
586  }
587 
588  bool NextEntry(Cursor *cursor, uint64_t *inode_parent, NameString *name) {
589  shash::Md5 parent_md5;
590  StringRef name_ref;
591  bool result = path_map_.path_store()->Next(
592  &(cursor->csr_paths), &parent_md5, &name_ref);
593  if (!result)
594  return false;
595  if (parent_md5.IsNull())
596  *inode_parent = 0;
597  else
598  *inode_parent = path_map_.LookupInodeByMd5Path(parent_md5);
599  name->Assign(name_ref.data(), name_ref.length());
600  return true;
601  }
602 
603  bool NextInode(Cursor *cursor, uint64_t *inode) {
604  return inode_references_.Next(&(cursor->csr_inos), inode);
605  }
606 
607  void EndEnumerate(Cursor *cursor) {
608  Unlock();
609  }
610 
611  private:
612  static const unsigned kVersion = 4;
613 
614  void InitLock();
615  void CopyFrom(const InodeTracker &other);
616  inline void Lock() const {
617  int retval = pthread_mutex_lock(lock_);
618  assert(retval == 0);
619  }
620  inline void Unlock() const {
621  int retval = pthread_mutex_unlock(lock_);
622  assert(retval == 0);
623  }
624 
625  unsigned version_;
626  pthread_mutex_t *lock_;
631 }; // class InodeTracker
632 
633 
638  FRIEND_TEST(T_GlueBuffer, NentryTracker);
639 
640  private:
641  struct Entry {
642  Entry() : expiry(0), inode_parent(0) {}
643  Entry(uint64_t e, uint64_t p, const char *n)
644  : expiry(e)
645  , inode_parent(p)
646  , name(n, strlen(n))
647  {}
648  uint64_t expiry;
649  uint64_t inode_parent;
651  };
652 
653  public:
654  struct Cursor {
655  explicit Cursor(Entry *h) : head(h), pos(0) {}
657  size_t pos;
658  };
659 
660  // Cannot be moved to the statistics manager because it has to survive
661  // reloads. Added manually in the fuse module initialization and in talk.cc.
662  struct Statistics {
664  uint64_t num_insert;
665  uint64_t num_remove;
666  uint64_t num_prune;
667  };
669 
670  static void *MainCleaner(void *data);
671 
672  NentryTracker();
673  explicit NentryTracker(const NentryTracker &other);
674  NentryTracker &operator= (const NentryTracker &other);
675  ~NentryTracker();
676 
680  NentryTracker *Move();
681 
682  void Add(const uint64_t inode_parent, const char *name, uint64_t timeout_s) {
683  if (!is_active_) return;
684  if (timeout_s == 0) return;
685 
686  uint64_t now = platform_monotonic_time();
687  Lock();
688  entries_.PushBack(Entry(now + timeout_s, inode_parent, name));
690  DoPrune(now);
691  Unlock();
692  }
693 
694  void Prune();
699  void Disable() { is_active_ = false; }
700  bool is_active() const { return is_active_; }
701 
702  void SpawnCleaner(unsigned interval_s);
703 
704  Cursor BeginEnumerate();
705  bool NextEntry(Cursor *cursor, uint64_t *inode_parent, NameString *name);
706  void EndEnumerate(Cursor *cursor);
707 
708  private:
709  static const unsigned kVersion = 0;
710 
711  void CopyFrom(const NentryTracker &other);
712 
713  void InitLock();
714  inline void Lock() const {
715  int retval = pthread_mutex_lock(lock_);
716  assert(retval == 0);
717  }
718  inline void Unlock() const {
719  int retval = pthread_mutex_unlock(lock_);
720  assert(retval == 0);
721  }
722 
723  void DoPrune(uint64_t now) {
724  Entry *entry;
725  while (entries_.Peek(&entry)) {
726  if (entry->expiry >= now)
727  break;
728  entries_.PopFront();
730  }
732  }
733 
734  pthread_mutex_t *lock_;
735  unsigned version_;
739 
742  pthread_t thread_cleaner_;
743 }; // class NentryTracker
744 
745 
746 } // namespace glue
747 
748 #endif // CVMFS_GLUE_BUFFER_H_
BigVector< void * > bins_
Definition: glue_buffer.h:168
InodeReferences inode_references_
Definition: glue_buffer.h:629
bool IsNull() const
Definition: hash.h:382
InodeReferences::Cursor csr_inos
Definition: glue_buffer.h:487
void Lock() const
Definition: glue_buffer.h:616
void Unlock() const
Definition: glue_buffer.h:620
int64_t atomic_int64
Definition: atomic.h:18
static uint32_t hasher_md5(const shash::Md5 &key)
Definition: glue_buffer.h:38
void Lock() const
Definition: glue_buffer.h:714
Cursor(const PathStore::Cursor &p, const InodeReferences::Cursor &i)
Definition: glue_buffer.h:480
Item At(const size_t index) const
Definition: bigvector.h:50
void SpawnCleaner(unsigned interval_s)
Definition: glue_buffer.cc:166
static const unsigned kVersion
Definition: glue_buffer.h:709
uint64_t inode_parent
Definition: glue_buffer.h:649
Statistics GetStatistics()
Definition: glue_buffer.h:517
void EndEnumerate(Cursor *cursor)
Definition: glue_buffer.cc:257
bool NextEntry(Cursor *cursor, uint64_t *inode_parent, NameString *name)
Definition: glue_buffer.cc:242
pthread_mutex_t * lock_
Definition: glue_buffer.h:734
NentryTracker * Move()
Definition: glue_buffer.cc:156
void Assign(const char *chars, const unsigned length)
Definition: shortstring.h:53
Cursor BeginEnumerate()
Definition: glue_buffer.h:582
double GetUsage() const
Definition: glue_buffer.h:138
PathStore::Cursor csr_paths
Definition: glue_buffer.h:486
void Unlock() const
Definition: glue_buffer.h:718
BigQueue< Entry > entries_
Definition: glue_buffer.h:738
PathStore path_store_
Definition: glue_buffer.h:368
NameString name
Definition: glue_buffer.h:650
bool Put(const uint64_t inode, const uint32_t by)
Definition: glue_buffer.h:427
static uint16_t size(const uint16_t length)
Definition: glue_buffer.h:63
FRIEND_TEST(T_GlueBuffer, NentryTracker)
assert((mem||(size==0))&&"Out Of Memory")
SmallHashDynamic< uint64_t, uint32_t > map_
Definition: glue_buffer.h:464
std::string GetParentPath(const std::string &path)
Definition: posix.cc:131
StringHeap * string_heap_
Definition: glue_buffer.h:308
void EndEnumerate(Cursor *cursor)
Definition: glue_buffer.h:607
Statistics GetStatistics()
Definition: glue_buffer.h:668
uint64_t bin_used_
Definition: glue_buffer.h:167
char * data() const
Definition: glue_buffer.h:66
uint64_t LookupInodeByMd5Path(const shash::Md5 &md5path)
Definition: glue_buffer.h:334
unsigned char digest[digest_size_]
Definition: hash.h:123
PathStore * path_store()
Definition: glue_buffer.h:364
uint16_t * length_
Definition: glue_buffer.h:78
uint64_t LookupInodeByPath(const PathString &path)
Definition: glue_buffer.h:326
Definition: glue_buffer.h:641
void Insert(const shash::Md5 &md5path, const PathString &path)
Definition: glue_buffer.h:198
shash::Md5 Insert(const PathString &path, const uint64_t inode)
Definition: glue_buffer.h:341
static uint32_t hasher_inode(const uint64_t &inode)
Definition: glue_buffer.h:44
void CopyFrom(const NentryTracker &other)
Definition: glue_buffer.cc:146
bool Next(Cursor *cursor, shash::Md5 *parent, StringRef *name)
Definition: glue_buffer.h:280
uint64_t GetSizeAlloc() const
Definition: glue_buffer.h:146
bool LookupMd5Path(const uint64_t inode, shash::Md5 *md5path)
Definition: glue_buffer.h:381
bool is_active() const
Definition: glue_buffer.h:700
uint16_t size() const
Definition: glue_buffer.h:62
void CopyFrom(const InodeTracker &other)
Definition: glue_buffer.cc:71
uint64_t FindInode(const PathString &path)
Definition: glue_buffer.h:574
SmallHashDynamic< uint64_t, shash::Md5 > map_
Definition: glue_buffer.h:397
InodeTracker & operator=(const InodeTracker &other)
Definition: glue_buffer.cc:93
uint32_t capacity() const
Definition: smallhash.h:278
uint64_t bin_size_
Definition: glue_buffer.h:166
void VfsGetBy(const uint64_t inode, const uint32_t by, const PathString &path)
Definition: glue_buffer.h:524
void VfsPut(const uint64_t inode, const uint32_t by)
Definition: glue_buffer.h:540
bool NextEntry(Cursor *cursor, uint64_t *inode_parent, NameString *name)
Definition: glue_buffer.h:588
StringHeap(const uint64_t minimum_size)
Definition: glue_buffer.h:96
Statistics statistics_
Definition: glue_buffer.h:630
bool NextInode(Cursor *cursor, uint64_t *inode)
Definition: glue_buffer.h:603
static StringRef Place(const uint16_t length, const char *str, void *addr)
Definition: glue_buffer.h:67
uint16_t length() const
Definition: glue_buffer.h:61
pthread_t thread_cleaner_
Definition: glue_buffer.h:742
uint64_t expiry
Definition: glue_buffer.h:648
bool Lookup(const shash::Md5 &md5path, PathString *path)
Definition: glue_buffer.h:225
void Insert(const Key &key, const Value &value)
Definition: smallhash.h:89
Key * keys() const
Definition: smallhash.h:133
bool Next(Cursor *cursor, uint64_t *inode)
Definition: glue_buffer.h:449
void Append(const char *chars, const unsigned length)
Definition: shortstring.h:70
string StringifyInt(const int64_t value)
Definition: string.cc:78
pthread_mutex_t * lock_
Definition: glue_buffer.h:626
uint64_t platform_monotonic_time()
static const unsigned kVersion
Definition: glue_buffer.h:612
SmallHashDynamic< shash::Md5, PathInfo > map_
Definition: glue_buffer.h:307
uint64_t used() const
Definition: glue_buffer.h:143
void Erase(const uint64_t inode)
Definition: glue_buffer.h:390
Entry(uint64_t e, uint64_t p, const char *n)
Definition: glue_buffer.h:643
SmallHashDynamic< shash::Md5, uint64_t > map_
Definition: glue_buffer.h:367
bool Contains(const Key &key) const
Definition: smallhash.h:82
PathStore & operator=(const PathStore &other)
Definition: glue_buffer.cc:30
void Add(const uint64_t inode_parent, const char *name, uint64_t timeout_s)
Definition: glue_buffer.h:682
bool FindPath(const uint64_t inode, PathString *path)
Definition: glue_buffer.h:556
void PushBack(const Item &item)
Definition: bigvector.h:60
bool IsEmpty() const
Definition: shortstring.h:110
void Clear()
Definition: smallhash.h:113
void RemoveString(const StringRef str_ref)
Definition: glue_buffer.h:134
Entry()
Definition: glue_buffer.h:642
void Erase(const shash::Md5 &md5path)
Definition: glue_buffer.h:350
void CopyFrom(const PathStore &other)
Definition: glue_buffer.cc:45
bool LookupPath(const shash::Md5 &md5path, PathString *path)
Definition: glue_buffer.h:321
void Erase(const shash::Md5 &md5path)
Definition: glue_buffer.h:241
void Insert(const uint64_t inode, const shash::Md5 &md5path)
Definition: glue_buffer.h:386
void VfsGet(const uint64_t inode, const PathString &path)
Definition: glue_buffer.h:536
unsigned GetLength() const
Definition: shortstring.h:104
bool Lookup(const Key &key, Value *value) const
Definition: smallhash.h:73
void Init(uint32_t expected_size, Key empty, uint32_t(*hasher)(const Key &key))
Definition: smallhash.h:60
NentryTracker & operator=(const NentryTracker &other)
Definition: glue_buffer.cc:135
const char * GetChars() const
Definition: shortstring.h:96
void Init(const uint64_t minimum_size)
Definition: glue_buffer.h:100
void AddBin(const uint64_t size)
Definition: glue_buffer.h:157
bool Get(const uint64_t inode, const uint32_t by)
Definition: glue_buffer.h:418
StringRef AddString(const uint16_t length, const char *str)
Definition: glue_buffer.h:117
static void size_t size
Definition: smalloc.h:47
static void * MainCleaner(void *data)
Definition: glue_buffer.cc:176
Key empty_key() const
Definition: smallhash.h:132
void Erase(const Key &key)
Definition: smallhash.h:95
Statistics statistics_
Definition: glue_buffer.h:736
Cursor BeginEnumerate()
Definition: glue_buffer.h:276
uint32_t MurmurHash2(const void *key, int len, uint32_t seed)
Definition: murmur.hxx:23
size_t size() const
Definition: bigvector.h:100
void DoPrune(uint64_t now)
Definition: glue_buffer.h:723