11 #include <gtest/gtest_prod.h>
35 #ifndef CVMFS_GLUE_BUFFER_H_
36 #define CVMFS_GLUE_BUFFER_H_
52 static inline uint64_t
ShiftMode(
unsigned mode) {
return (mode >> 12) & 017; }
68 :
inode_ex_(inode | (static_cast<uint64_t>(type) << 60))
97 return (uint32_t) *(
reinterpret_cast<const uint32_t *
>(key.
digest) + 1);
101 return MurmurHash2(&inode,
sizeof(inode), 0x07387a4f);
124 return sizeof(uint16_t) + length;
126 char *
data()
const {
return reinterpret_cast<char *
>(
length_ + 1); }
131 result.
length_ =
reinterpret_cast<uint16_t *
>(addr);
134 memcpy(result.
length_ + 1, str, length);
160 void Init(
const uint64_t minimum_size) {
165 uint64_t pow2_size = 128 * 1024;
166 while (pow2_size < minimum_size)
172 for (
unsigned i = 0; i <
bins_.
size(); ++i) {
181 if (remaining_bin_size < str_size) {
182 size_ += remaining_bin_size;
190 bin_used_ += str_size;
199 if (
size_ == 0)
return 1.0;
200 return static_cast<double>(
used_) / static_cast<double>(
size_);
209 for (
unsigned i = 0; i <
bins_.
size(); ++i) {
218 void *bin = smmap(size);
260 bool found =
map_.Lookup(md5path, &info);
263 map_.Insert(md5path, info);
270 map_.Insert(md5path, new_entry);
282 map_.Insert(md5path, new_entry);
287 bool retval =
map_.Lookup(md5path, &info);
303 bool found =
map_.Lookup(md5path, &info);
314 for (
unsigned i = 0; i <
map_.capacity(); ++i) {
315 if (
map_.keys()[i] != empty_path) {
316 (
map_.values() + i)->name =
318 map_.values()[i].name.data());
326 map_.Insert(md5path, info);
342 while (cursor->
idx <
map_.capacity()) {
343 if (
map_.keys()[cursor->
idx] == empty_key) {
347 *parent =
map_.values()[cursor->
idx].parent;
348 *name =
map_.values()[cursor->
idx].name;
384 int32_t
Add(
const struct stat &info) {
387 int32_t index =
static_cast<int>(
store_.
size());
398 return info_back.st_ino;
426 if (found)
return inode;
433 if (found)
return inode;
486 bool found =
map_.LookupEx(inode_ex, md5path);
491 map_.Insert(inode_ex, md5path);
522 bool Get(
const uint64_t inode,
const uint32_t by) {
523 uint32_t refcounter = 0;
524 const bool found =
map_.
Lookup(inode, &refcounter);
525 const bool new_inode = !found;
531 bool Put(
const uint64_t inode,
const uint32_t by) {
540 if (refcounter < by) {
542 "inode tracker refcount mismatch, inode % " PRIu64
543 ", refcounts %u / %u", inode, refcounter, by);
546 if (refcounter == by) {
555 void Replace(
const uint64_t old_inode,
const uint64_t new_inode) {
622 bool VfsPut(
const uint64_t inode,
const uint32_t by) {
631 "inode tracker ref map and path map out of sync: %" PRIu64,
683 uint64_t inode = inode_ex.
GetInode();
773 &(cursor->
csr_paths), &parent_md5, &name_ref);
798 int retval = pthread_mutex_lock(
lock_);
802 int retval = pthread_mutex_unlock(
lock_);
825 Entry(uint64_t e, uint64_t p,
const char *n)
864 void Add(
const uint64_t inode_parent,
const char *name, uint64_t timeout_s) {
866 if (timeout_s == 0)
return;
870 entries_.PushBack(
Entry(now + timeout_s, inode_parent, name));
897 int retval = pthread_mutex_lock(
lock_);
901 int retval = pthread_mutex_unlock(
lock_);
997 void Evict(uint64_t inode);
1027 const struct stat &info);
1033 void Close(uint64_t inode);
1039 bool retval =
map_.Lookup(inode, &entry);
1040 if (retval && (entry.
nopen != 0)) {
1078 #endif // CVMFS_GLUE_BUFFER_H_
bool GetInfoIfOpen(uint64_t inode, shash::Any *hash, struct stat *info)
BigVector< void * > bins_
VfsPutRaii GetVfsPutRaii()
OpenDirectives(bool k, bool d)
InodeReferences inode_references_
InodeReferences::Cursor csr_inos
atomic_int64 num_hits_inode
static uint32_t hasher_md5(const shash::Md5 &key)
Cursor(const PathStore::Cursor &p, const InodeReferences::Cursor &i)
Item At(const size_t index) const
bool ReplaceInode(uint64_t old_inode, const InodeEx &new_inode)
struct stat Get(int32_t index) const
atomic_int64 num_misses_path
FRIEND_TEST(T_GlueBuffer, DentryTracker)
Statistics GetStatistics()
NameString GetFileName(const PathString &path)
void DoPrune(uint64_t now)
PageCacheTracker & operator=(const PageCacheTracker &other)
uint64_t GetInode() const
InodeEx(uint64_t inode, unsigned mode)
void Assign(const char *chars, const unsigned length)
PathStore::Cursor csr_paths
void CopyFrom(const DentryTracker &other)
bool FindDentry(uint64_t ino, uint64_t *parent_ino, NameString *name)
bool Put(const uint64_t inode, const uint32_t by)
static uint16_t size(const uint16_t length)
pthread_t thread_cleaner_
void Insert(const InodeEx inode_ex, const shash::Md5 &md5path)
assert((mem||(size==0))&&"Out Of Memory")
bool LookupMd5Path(InodeEx *inode_ex, shash::Md5 *md5path)
SmallHashDynamic< uint64_t, uint32_t > map_
BigVector< struct stat > store_
bool NextEntry(Cursor *cursor, uint64_t *inode_parent, NameString *name)
StringHeap * string_heap_
void EndEnumerate(Cursor *cursor)
bool VfsPut(const uint64_t inode, const uint32_t by)
uint64_t LookupInodeByMd5Path(const shash::Md5 &md5path)
unsigned char digest[digest_size_]
uint64_t LookupInodeByPath(const PathString &path)
bool operator==(const InodeEx &other) const
static uint32_t hasher_inode_ex(const InodeEx &inode_ex)
void Insert(const shash::Md5 &md5path, const PathString &path)
shash::Md5 Insert(const PathString &path, const uint64_t inode)
static uint32_t hasher_inode(const uint64_t &inode)
bool Next(Cursor *cursor, shash::Md5 *parent, StringRef *name)
uint64_t GetSizeAlloc() const
void EndEnumerate(Cursor *cursor)
SmallHashDynamic< InodeEx, shash::Md5 > map_
void CopyFrom(const InodeTracker &other)
uint64_t FindInode(const PathString &path)
InodeTracker & operator=(const InodeTracker &other)
uint32_t capacity() const
Statistics GetStatistics()
Statistics GetStatistics()
void Add(const uint64_t inode_parent, const char *name, uint64_t timeout_s)
void Replace(const uint64_t old_inode, const uint64_t new_inode)
bool NextEntry(Cursor *cursor, uint64_t *inode_parent, NameString *name)
void SetSize(const size_t new_size)
StringHeap(const uint64_t minimum_size)
InodeEx(uint64_t inode, EFileType type)
bool NextInode(Cursor *cursor, uint64_t *inode)
static StringRef Place(const uint16_t length, const char *str, void *addr)
void SpawnCleaner(unsigned interval_s)
bool Lookup(const shash::Md5 &md5path, PathString *path)
void Insert(const Key &key, const Value &value)
int32_t Add(const struct stat &info)
Entry(uint64_t e, uint64_t p, const char *n)
bool Next(Cursor *cursor, uint64_t *inode)
static const unsigned kVersion
void Append(const char *chars, const unsigned length)
string StringifyInt(const int64_t value)
void VfsGetBy(const InodeEx inode_ex, const uint32_t by, const PathString &path)
void Erase(const uint64_t inode)
Entry(int32_t n, int32_t i, const shash::Any &h)
static const unsigned kVersion
SmallHashDynamic< shash::Md5, PathInfo > map_
EFileType GetFileType() const
atomic_int64 num_references
SmallHashDynamic< shash::Md5, uint64_t > map_
bool Contains(const Key &key) const
PathStore & operator=(const PathStore &other)
OpenDirectives Open(uint64_t inode, const shash::Any &hash, const struct stat &info)
void PushBack(const Item &item)
void Evict(uint64_t inode)
bool IsCompatibleFileType(unsigned mode) const
void Close(uint64_t inode)
OpenDirectives OpenDirect()
EvictRaii(PageCacheTracker *t)
void RemoveString(const StringRef str_ref)
void Replace(size_t index, const Item &item)
void Erase(const shash::Md5 &md5path)
PathString GetParentPath(const PathString &path)
void CopyFrom(const PathStore &other)
PageCacheTracker * tracker_
uint64_t Erase(int32_t index)
bool Erase(const Key &key)
static uint64_t ShiftMode(unsigned mode)
bool LookupPath(const shash::Md5 &md5path, PathString *path)
DentryTracker & operator=(const DentryTracker &other)
void CopyFrom(const PageCacheTracker &other)
void Erase(const shash::Md5 &md5path)
BigQueue< Entry > entries_
unsigned GetLength() const
atomic_int64 num_hits_path
bool Lookup(const Key &key, Value *value) const
static void * MainCleaner(void *data)
static const unsigned kVersion
void Init(uint32_t expected_size, Key empty, uint32_t(*hasher)(const Key &key))
void Replace(const shash::Md5 &md5path, uint64_t new_inode)
int cleaning_interval_ms_
static const unsigned int kBitDirectIo
const char * GetChars() const
void Init(const uint64_t minimum_size)
void AddBin(const uint64_t size)
bool Get(const uint64_t inode, const uint32_t by)
StringRef AddString(const uint16_t length, const char *str)
SmallHashDynamic< uint64_t, Entry > map_
void VfsGet(const InodeEx inode_ex, const PathString &path)
bool FindPath(InodeEx *inode_ex, PathString *path)
uint32_t MurmurHash2(const void *key, int len, uint32_t seed)
bool operator!=(const InodeEx &other) const
VfsPutRaii(InodeTracker *t)