11 #include <gtest/gtest_prod.h>
36 #ifndef CVMFS_GLUE_BUFFER_H_
37 #define CVMFS_GLUE_BUFFER_H_
53 static inline uint64_t
ShiftMode(
unsigned mode) {
return (mode >> 12) & 017; }
69 :
inode_ex_(inode | (static_cast<uint64_t>(type) << 60))
98 return (uint32_t) *(
reinterpret_cast<const uint32_t *
>(key.
digest) + 1);
102 return MurmurHash2(&inode,
sizeof(inode), 0x07387a4f);
125 return sizeof(uint16_t) + length;
127 char *
data()
const {
return reinterpret_cast<char *
>(
length_ + 1); }
132 result.
length_ =
reinterpret_cast<uint16_t *
>(addr);
135 memcpy(result.
length_ + 1, str, length);
161 void Init(
const uint64_t minimum_size) {
166 uint64_t pow2_size = 128 * 1024;
167 while (pow2_size < minimum_size)
173 for (
unsigned i = 0; i <
bins_.
size(); ++i) {
182 if (remaining_bin_size < str_size) {
183 size_ += remaining_bin_size;
191 bin_used_ += str_size;
200 if (
size_ == 0)
return 1.0;
201 return static_cast<double>(
used_) / static_cast<double>(
size_);
210 for (
unsigned i = 0; i <
bins_.
size(); ++i) {
219 void *bin = smmap(size);
261 bool found =
map_.Lookup(md5path, &info);
264 map_.Insert(md5path, info);
271 map_.Insert(md5path, new_entry);
283 map_.Insert(md5path, new_entry);
288 bool retval =
map_.Lookup(md5path, &info);
304 bool found =
map_.Lookup(md5path, &info);
315 for (
unsigned i = 0; i <
map_.capacity(); ++i) {
316 if (
map_.keys()[i] != empty_path) {
317 (
map_.values() + i)->name =
319 map_.values()[i].name.data());
327 map_.Insert(md5path, info);
343 while (cursor->
idx <
map_.capacity()) {
344 if (
map_.keys()[cursor->
idx] == empty_key) {
348 *parent =
map_.values()[cursor->
idx].parent;
349 *name =
map_.values()[cursor->
idx].name;
385 int32_t
Add(
const struct stat &info) {
388 int32_t index =
static_cast<int>(
store_.
size());
399 return info_back.st_ino;
427 if (found)
return inode;
434 if (found)
return inode;
487 bool found =
map_.LookupEx(inode_ex, md5path);
492 map_.Insert(inode_ex, md5path);
523 bool Get(
const uint64_t inode,
const uint32_t by) {
524 uint32_t refcounter = 0;
525 const bool found =
map_.
Lookup(inode, &refcounter);
526 const bool new_inode = !found;
532 bool Put(
const uint64_t inode,
const uint32_t by) {
541 if (refcounter < by) {
543 "inode tracker refcount mismatch, inode % " PRIu64
544 ", refcounts %u / %u", inode, refcounter, by);
547 if (refcounter == by) {
556 void Replace(
const uint64_t old_inode,
const uint64_t new_inode) {
623 bool VfsPut(
const uint64_t inode,
const uint32_t by) {
632 "inode tracker ref map and path map out of sync: %" PRIu64,
684 uint64_t inode = inode_ex.
GetInode();
774 &(cursor->
csr_paths), &parent_md5, &name_ref);
799 int retval = pthread_mutex_lock(
lock_);
803 int retval = pthread_mutex_unlock(
lock_);
826 Entry(uint64_t e, uint64_t p,
const char *n)
865 void Add(
const uint64_t inode_parent,
const char *name, uint64_t timeout_s) {
867 if (timeout_s == 0)
return;
871 entries_.PushBack(
Entry(now + timeout_s, inode_parent, name));
898 int retval = pthread_mutex_lock(
lock_);
902 int retval = pthread_mutex_unlock(
lock_);
998 void Evict(uint64_t inode);
1028 const struct stat &info);
1034 void Close(uint64_t inode);
1040 bool retval =
map_.Lookup(inode, &entry);
1041 if (retval && (entry.
nopen != 0)) {
1061 const bool retval =
map_.Lookup(dirent.
inode(), &entry);
1068 if (entry.
nopen == 0)
1073 bool is_stale =
true;
1120 #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)
bool IsChunkedFile() const
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)
shash::Any checksum() const
bool VfsPut(const uint64_t inode, const uint32_t by)
uint64_t LookupInodeByMd5Path(const shash::Md5 &md5path)
unsigned char digest[digest_size_]
bool IsStale(const catalog::DirectoryEntry &dirent)
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)