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 
496  class VfsPutRaii {
497  public:
498  explicit VfsPutRaii(InodeTracker *t) : tracker_(t) {
499  tracker_->Lock();
500  }
502 
503  bool VfsPut(const uint64_t inode, const uint32_t by) {
504  bool removed = tracker_->inode_references_.Put(inode, by);
505  if (removed) {
506  // TODO(jblomer): pop operation (Lookup+Erase)
507  shash::Md5 md5path;
508  bool found = tracker_->inode_map_.LookupMd5Path(inode, &md5path);
509  assert(found);
510  tracker_->inode_map_.Erase(inode);
511  tracker_->path_map_.Erase(md5path);
512  atomic_inc64(&tracker_->statistics_.num_removes);
513  }
514  atomic_xadd64(&tracker_->statistics_.num_references, -int32_t(by));
515  return removed;
516  }
517 
518  private:
520  };
521 
522  // Cannot be moved to the statistics manager because it has to survive
523  // reloads. Added manually in the fuse module initialization and in talk.cc.
524  struct Statistics {
526  atomic_init64(&num_inserts);
527  atomic_init64(&num_removes);
528  atomic_init64(&num_references);
529  atomic_init64(&num_hits_inode);
530  atomic_init64(&num_hits_path);
531  atomic_init64(&num_misses_path);
532  }
533  std::string Print() {
534  return
535  "inserts: " + StringifyInt(atomic_read64(&num_inserts)) +
536  " removes: " + StringifyInt(atomic_read64(&num_removes)) +
537  " references: " + StringifyInt(atomic_read64(&num_references)) +
538  " hits(inode): " + StringifyInt(atomic_read64(&num_hits_inode)) +
539  " hits(path): " + StringifyInt(atomic_read64(&num_hits_path)) +
540  " misses(path): " + StringifyInt(atomic_read64(&num_misses_path));
541  }
548  };
550 
551  InodeTracker();
552  explicit InodeTracker(const InodeTracker &other);
553  InodeTracker &operator= (const InodeTracker &other);
554  ~InodeTracker();
555 
556  void VfsGetBy(const uint64_t inode, const uint32_t by, const PathString &path)
557  {
558  Lock();
559  bool new_inode = inode_references_.Get(inode, by);
560  shash::Md5 md5path = path_map_.Insert(path, inode);
561  inode_map_.Insert(inode, md5path);
562  Unlock();
563 
564  atomic_xadd64(&statistics_.num_references, by);
565  if (new_inode) atomic_inc64(&statistics_.num_inserts);
566  }
567 
568  void VfsGet(const uint64_t inode, const PathString &path) {
569  VfsGetBy(inode, 1, path);
570  }
571 
572  VfsPutRaii GetVfsPutRaii() { return VfsPutRaii(this); }
573 
574  bool FindPath(const uint64_t inode, PathString *path) {
575  Lock();
576  shash::Md5 md5path;
577  bool found = inode_map_.LookupMd5Path(inode, &md5path);
578  if (found) {
579  found = path_map_.LookupPath(md5path, path);
580  assert(found);
581  }
582  Unlock();
583 
584  if (found) {
585  atomic_inc64(&statistics_.num_hits_path);
586  } else {
587  atomic_inc64(&statistics_.num_misses_path);
588  }
589  return found;
590  }
591 
592  uint64_t FindInode(const PathString &path) {
593  Lock();
594  uint64_t inode = path_map_.LookupInodeByPath(path);
595  Unlock();
596  atomic_inc64(&statistics_.num_hits_inode);
597  return inode;
598  }
599 
601  Lock();
604  }
605 
606  bool NextEntry(Cursor *cursor, uint64_t *inode_parent, NameString *name) {
607  shash::Md5 parent_md5;
608  StringRef name_ref;
609  bool result = path_map_.path_store()->Next(
610  &(cursor->csr_paths), &parent_md5, &name_ref);
611  if (!result)
612  return false;
613  if (parent_md5.IsNull())
614  *inode_parent = 0;
615  else
616  *inode_parent = path_map_.LookupInodeByMd5Path(parent_md5);
617  name->Assign(name_ref.data(), name_ref.length());
618  return true;
619  }
620 
621  bool NextInode(Cursor *cursor, uint64_t *inode) {
622  return inode_references_.Next(&(cursor->csr_inos), inode);
623  }
624 
625  void EndEnumerate(Cursor *cursor) {
626  Unlock();
627  }
628 
629  private:
630  static const unsigned kVersion = 4;
631 
632  void InitLock();
633  void CopyFrom(const InodeTracker &other);
634  inline void Lock() const {
635  int retval = pthread_mutex_lock(lock_);
636  assert(retval == 0);
637  }
638  inline void Unlock() const {
639  int retval = pthread_mutex_unlock(lock_);
640  assert(retval == 0);
641  }
642 
643  unsigned version_;
644  pthread_mutex_t *lock_;
649 }; // class InodeTracker
650 
651 
656  FRIEND_TEST(T_GlueBuffer, NentryTracker);
657 
658  private:
659  struct Entry {
660  Entry() : expiry(0), inode_parent(0) {}
661  Entry(uint64_t e, uint64_t p, const char *n)
662  : expiry(e)
663  , inode_parent(p)
664  , name(n, strlen(n))
665  {}
666  uint64_t expiry;
667  uint64_t inode_parent;
669  };
670 
671  public:
672  struct Cursor {
673  explicit Cursor(Entry *h) : head(h), pos(0) {}
675  size_t pos;
676  };
677 
678  // Cannot be moved to the statistics manager because it has to survive
679  // reloads. Added manually in the fuse module initialization and in talk.cc.
680  struct Statistics {
682  uint64_t num_insert;
683  uint64_t num_remove;
684  uint64_t num_prune;
685  };
687 
688  static void *MainCleaner(void *data);
689 
690  NentryTracker();
691  explicit NentryTracker(const NentryTracker &other);
692  NentryTracker &operator= (const NentryTracker &other);
693  ~NentryTracker();
694 
698  NentryTracker *Move();
699 
700  void Add(const uint64_t inode_parent, const char *name, uint64_t timeout_s) {
701  if (!is_active_) return;
702  if (timeout_s == 0) return;
703 
704  uint64_t now = platform_monotonic_time();
705  Lock();
706  entries_.PushBack(Entry(now + timeout_s, inode_parent, name));
708  DoPrune(now);
709  Unlock();
710  }
711 
712  void Prune();
717  void Disable() { is_active_ = false; }
718  bool is_active() const { return is_active_; }
719 
720  void SpawnCleaner(unsigned interval_s);
721 
722  Cursor BeginEnumerate();
723  bool NextEntry(Cursor *cursor, uint64_t *inode_parent, NameString *name);
724  void EndEnumerate(Cursor *cursor);
725 
726  private:
727  static const unsigned kVersion = 0;
728 
729  void CopyFrom(const NentryTracker &other);
730 
731  void InitLock();
732  inline void Lock() const {
733  int retval = pthread_mutex_lock(lock_);
734  assert(retval == 0);
735  }
736  inline void Unlock() const {
737  int retval = pthread_mutex_unlock(lock_);
738  assert(retval == 0);
739  }
740 
741  void DoPrune(uint64_t now) {
742  Entry *entry;
743  while (entries_.Peek(&entry)) {
744  if (entry->expiry >= now)
745  break;
746  entries_.PopFront();
748  }
750  }
751 
752  pthread_mutex_t *lock_;
753  unsigned version_;
757 
760  pthread_t thread_cleaner_;
761 }; // class NentryTracker
762 
768  private:
769  struct Entry {
770  Entry() : nopen(0) {}
771  Entry(int32_t n, const shash::Any &h) : nopen(n), hash(h) {}
777  int32_t nopen;
783  };
784 
785  public:
791  static const unsigned int kBitDirectIo = 62;
792 
796  struct OpenDirectives {
809  bool direct_io;
810 
811  // Defaults to the old (pre v2.10) behavior: always flush the cache, never
812  // use direct I/O.
813  OpenDirectives() : keep_cache(false), direct_io(false) {}
814 
815  OpenDirectives(bool k, bool d) : keep_cache(k), direct_io(d) {}
816  };
817 
824  class EvictRaii {
825  public:
826  explicit EvictRaii(PageCacheTracker *t);
827  ~EvictRaii();
828  void Evict(uint64_t inode);
829 
830  private:
832  };
833 
834  // Cannot be moved to the statistics manager because it has to survive
835  // reloads. Added manually in the fuse module initialization and in talk.cc.
836  struct Statistics {
838  : n_insert(0)
839  , n_remove(0)
840  , n_open_direct(0)
841  , n_open_flush(0)
842  , n_open_cached(0)
843  {}
844  uint64_t n_insert;
845  uint64_t n_remove;
846  uint64_t n_open_direct;
847  uint64_t n_open_flush;
848  uint64_t n_open_cached;
849  };
851 
853  explicit PageCacheTracker(const PageCacheTracker &other);
856 
857  OpenDirectives Open(uint64_t inode, const shash::Any &hash);
862  OpenDirectives OpenDirect();
863  void Close(uint64_t inode);
864 
865  EvictRaii GetEvictRaii() { return EvictRaii(this); }
866 
867  // Used in RestoreState to prevent using the page cache tracker from a
868  // previous version after hotpatch
869  void Disable() { is_active_ = false; }
870 
871  private:
872  static const unsigned kVersion = 0;
873 
874  void InitLock();
875  void CopyFrom(const PageCacheTracker &other);
876 
877  pthread_mutex_t *lock_;
878  unsigned version_;
887 };
888 
889 
890 } // namespace glue
891 
892 #endif // CVMFS_GLUE_BUFFER_H_
BigVector< void * > bins_
Definition: glue_buffer.h:168
VfsPutRaii GetVfsPutRaii()
Definition: glue_buffer.h:572
Entry(int32_t n, const shash::Any &h)
Definition: glue_buffer.h:771
InodeReferences inode_references_
Definition: glue_buffer.h:647
bool IsNull() const
Definition: hash.h:382
InodeReferences::Cursor csr_inos
Definition: glue_buffer.h:487
void Lock() const
Definition: glue_buffer.h:634
void Unlock() const
Definition: glue_buffer.h:638
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:732
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:167
static const unsigned kVersion
Definition: glue_buffer.h:727
uint64_t inode_parent
Definition: glue_buffer.h:667
Statistics GetStatistics()
Definition: glue_buffer.h:549
void EndEnumerate(Cursor *cursor)
Definition: glue_buffer.cc:258
bool NextEntry(Cursor *cursor, uint64_t *inode_parent, NameString *name)
Definition: glue_buffer.cc:243
pthread_mutex_t * lock_
Definition: glue_buffer.h:877
pthread_mutex_t * lock_
Definition: glue_buffer.h:752
PageCacheTracker & operator=(const PageCacheTracker &other)
Definition: glue_buffer.cc:284
Definition: glue_buffer.h:769
NentryTracker * Move()
Definition: glue_buffer.cc:157
void Assign(const char *chars, const unsigned length)
Definition: shortstring.h:53
Cursor BeginEnumerate()
Definition: glue_buffer.h:600
double GetUsage() const
Definition: glue_buffer.h:138
PathStore::Cursor csr_paths
Definition: glue_buffer.h:486
void Unlock() const
Definition: glue_buffer.h:736
BigQueue< Entry > entries_
Definition: glue_buffer.h:756
PathStore path_store_
Definition: glue_buffer.h:368
NameString name
Definition: glue_buffer.h:668
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:130
StringHeap * string_heap_
Definition: glue_buffer.h:308
void EndEnumerate(Cursor *cursor)
Definition: glue_buffer.h:625
Statistics GetStatistics()
Definition: glue_buffer.h:686
bool VfsPut(const uint64_t inode, const uint32_t by)
Definition: glue_buffer.h:503
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
int32_t nopen
Definition: glue_buffer.h:777
OpenDirectives Open(uint64_t inode, const shash::Any &hash)
Definition: glue_buffer.cc:313
Definition: glue_buffer.h:659
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:147
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:718
uint16_t size() const
Definition: glue_buffer.h:62
void CopyFrom(const InodeTracker &other)
Definition: glue_buffer.cc:72
uint64_t FindInode(const PathString &path)
Definition: glue_buffer.h:592
SmallHashDynamic< uint64_t, shash::Md5 > map_
Definition: glue_buffer.h:397
InodeTracker & operator=(const InodeTracker &other)
Definition: glue_buffer.cc:94
uint32_t capacity() const
Definition: smallhash.h:279
Statistics GetStatistics()
Definition: glue_buffer.h:850
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:556
bool NextEntry(Cursor *cursor, uint64_t *inode_parent, NameString *name)
Definition: glue_buffer.h:606
StringHeap(const uint64_t minimum_size)
Definition: glue_buffer.h:96
Statistics statistics_
Definition: glue_buffer.h:648
bool NextInode(Cursor *cursor, uint64_t *inode)
Definition: glue_buffer.h:621
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:760
uint64_t expiry
Definition: glue_buffer.h:666
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:134
bool Next(Cursor *cursor, uint64_t *inode)
Definition: glue_buffer.h:449
static const unsigned kVersion
Definition: glue_buffer.h:872
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:644
uint64_t platform_monotonic_time()
static const unsigned kVersion
Definition: glue_buffer.h:630
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:661
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:31
void Add(const uint64_t inode_parent, const char *name, uint64_t timeout_s)
Definition: glue_buffer.h:700
bool FindPath(const uint64_t inode, PathString *path)
Definition: glue_buffer.h:574
void PushBack(const Item &item)
Definition: bigvector.h:60
bool IsEmpty() const
Definition: shortstring.h:110
void Clear()
Definition: smallhash.h:114
void Close(uint64_t inode)
Definition: glue_buffer.cc:390
OpenDirectives OpenDirect()
Definition: glue_buffer.cc:379
EvictRaii(PageCacheTracker *t)
Definition: glue_buffer.cc:409
void RemoveString(const StringRef str_ref)
Definition: glue_buffer.h:134
Entry()
Definition: glue_buffer.h:770
Entry()
Definition: glue_buffer.h:660
void Erase(const shash::Md5 &md5path)
Definition: glue_buffer.h:350
void CopyFrom(const PathStore &other)
Definition: glue_buffer.cc:46
EvictRaii GetEvictRaii()
Definition: glue_buffer.h:865
bool Erase(const Key &key)
Definition: smallhash.h:95
bool LookupPath(const shash::Md5 &md5path, PathString *path)
Definition: glue_buffer.h:321
void CopyFrom(const PageCacheTracker &other)
Definition: glue_buffer.cc:294
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:568
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:136
static const unsigned int kBitDirectIo
Definition: glue_buffer.h:791
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:177
Key empty_key() const
Definition: smallhash.h:133
SmallHashDynamic< uint64_t, Entry > map_
Definition: glue_buffer.h:886
Statistics statistics_
Definition: glue_buffer.h:754
shash::Any hash
Definition: glue_buffer.h:782
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:741