1 |
|
|
/** |
2 |
|
|
* This file is part of the CernVM File System. |
3 |
|
|
* |
4 |
|
|
* Provides the LRU sub classes used for the file system client meta-data cache |
5 |
|
|
*/ |
6 |
|
|
|
7 |
|
|
#ifndef CVMFS_LRU_MD_H_ |
8 |
|
|
#define CVMFS_LRU_MD_H_ |
9 |
|
|
|
10 |
|
|
#define FUSE_USE_VERSION 26 |
11 |
|
|
#ifndef __STDC_FORMAT_MACROS |
12 |
|
|
#define __STDC_FORMAT_MACROS |
13 |
|
|
#endif |
14 |
|
|
|
15 |
|
|
#include <fuse/fuse_lowlevel.h> |
16 |
|
|
#include <stdint.h> |
17 |
|
|
|
18 |
|
|
#include "atomic.h" |
19 |
|
|
#include "directory_entry.h" |
20 |
|
|
#include "hash.h" |
21 |
|
|
#include "logging.h" |
22 |
|
|
#include "lru.h" |
23 |
|
|
#include "murmur.h" |
24 |
|
|
#include "shortstring.h" |
25 |
|
|
|
26 |
|
|
|
27 |
|
|
namespace lru { |
28 |
|
|
|
29 |
|
|
// Hash functions |
30 |
|
59 |
static inline uint32_t hasher_md5(const shash::Md5 &key) { |
31 |
|
|
// Don't start with the first bytes, because == is using them as well |
32 |
|
59 |
return (uint32_t) *(reinterpret_cast<const uint32_t *>(key.digest) + 1); |
33 |
|
|
} |
34 |
|
|
|
35 |
|
|
static inline uint32_t hasher_inode(const fuse_ino_t &inode) { |
36 |
|
|
return MurmurHash2(&inode, sizeof(inode), 0x07387a4f); |
37 |
|
|
} |
38 |
|
|
// uint32_t hasher_md5(const shash::Md5 &key); |
39 |
|
|
// uint32_t hasher_inode(const fuse_ino_t &inode); |
40 |
|
|
|
41 |
|
|
|
42 |
|
|
class InodeCache : public LruCache<fuse_ino_t, catalog::DirectoryEntry> |
43 |
✗✓ |
64 |
{ |
44 |
|
|
public: |
45 |
|
32 |
explicit InodeCache(unsigned int cache_size, perf::Statistics *statistics) : |
46 |
|
|
LruCache<fuse_ino_t, catalog::DirectoryEntry>( |
47 |
|
|
cache_size, fuse_ino_t(-1), hasher_inode, |
48 |
|
32 |
perf::StatisticsTemplate("inode_cache", statistics)) |
49 |
|
|
{ |
50 |
|
32 |
} |
51 |
|
|
|
52 |
|
|
bool Insert(const fuse_ino_t &inode, const catalog::DirectoryEntry &dirent) { |
53 |
|
|
LogCvmfs(kLogLru, kLogDebug, "insert inode --> dirent: %u -> '%s'", |
54 |
|
|
inode, dirent.name().c_str()); |
55 |
|
|
const bool result = |
56 |
|
|
LruCache<fuse_ino_t, catalog::DirectoryEntry>::Insert(inode, dirent); |
57 |
|
|
return result; |
58 |
|
|
} |
59 |
|
|
|
60 |
|
|
bool Lookup(const fuse_ino_t &inode, catalog::DirectoryEntry *dirent, |
61 |
|
|
bool update_lru = true) |
62 |
|
|
{ |
63 |
|
|
const bool result = |
64 |
|
|
LruCache<fuse_ino_t, catalog::DirectoryEntry>::Lookup(inode, dirent); |
65 |
|
|
LogCvmfs(kLogLru, kLogDebug, "lookup inode --> dirent: %u (%s)", |
66 |
|
|
inode, result ? "hit" : "miss"); |
67 |
|
|
return result; |
68 |
|
|
} |
69 |
|
|
|
70 |
|
|
void Drop() { |
71 |
|
|
LogCvmfs(kLogLru, kLogDebug, "dropping inode cache"); |
72 |
|
|
LruCache<fuse_ino_t, catalog::DirectoryEntry>::Drop(); |
73 |
|
|
} |
74 |
|
|
}; // InodeCache |
75 |
|
|
|
76 |
|
|
|
77 |
✗✓ |
64 |
class PathCache : public LruCache<fuse_ino_t, PathString> { |
78 |
|
|
public: |
79 |
|
32 |
explicit PathCache(unsigned int cache_size, perf::Statistics *statistics) : |
80 |
|
|
LruCache<fuse_ino_t, PathString>(cache_size, fuse_ino_t(-1), hasher_inode, |
81 |
|
32 |
perf::StatisticsTemplate("path_cache", statistics)) |
82 |
|
|
{ |
83 |
|
32 |
} |
84 |
|
|
|
85 |
|
|
bool Insert(const fuse_ino_t &inode, const PathString &path) { |
86 |
|
|
LogCvmfs(kLogLru, kLogDebug, "insert inode --> path %u -> '%s'", |
87 |
|
|
inode, path.c_str()); |
88 |
|
|
const bool result = |
89 |
|
|
LruCache<fuse_ino_t, PathString>::Insert(inode, path); |
90 |
|
|
return result; |
91 |
|
|
} |
92 |
|
|
|
93 |
|
|
bool Lookup(const fuse_ino_t &inode, PathString *path, |
94 |
|
|
bool update_lru = true) |
95 |
|
|
{ |
96 |
|
|
const bool found = |
97 |
|
|
LruCache<fuse_ino_t, PathString>::Lookup(inode, path); |
98 |
|
|
LogCvmfs(kLogLru, kLogDebug, "lookup inode --> path: %u (%s)", |
99 |
|
|
inode, found ? "hit" : "miss"); |
100 |
|
|
return found; |
101 |
|
|
} |
102 |
|
|
|
103 |
|
|
void Drop() { |
104 |
|
|
LogCvmfs(kLogLru, kLogDebug, "dropping path cache"); |
105 |
|
|
LruCache<fuse_ino_t, PathString>::Drop(); |
106 |
|
|
} |
107 |
|
|
}; // PathCache |
108 |
|
|
|
109 |
|
|
|
110 |
|
|
class Md5PathCache : |
111 |
|
|
public LruCache<shash::Md5, catalog::DirectoryEntry> |
112 |
✗✓ |
74 |
{ |
113 |
|
|
public: |
114 |
|
37 |
explicit Md5PathCache(unsigned int cache_size, perf::Statistics *statistics) : |
115 |
|
|
LruCache<shash::Md5, catalog::DirectoryEntry>( |
116 |
|
|
cache_size, shash::Md5(shash::AsciiPtr("!")), hasher_md5, |
117 |
|
37 |
perf::StatisticsTemplate("md5_path_cache", statistics)) |
118 |
|
|
{ |
119 |
|
37 |
dirent_negative_ = catalog::DirectoryEntry(catalog::kDirentNegative); |
120 |
|
|
} |
121 |
|
|
|
122 |
|
16 |
bool Insert(const shash::Md5 &hash, const catalog::DirectoryEntry &dirent) { |
123 |
|
|
LogCvmfs(kLogLru, kLogDebug, "insert md5 --> dirent: %s -> '%s'", |
124 |
|
16 |
hash.ToString().c_str(), dirent.name().c_str()); |
125 |
|
|
const bool result = |
126 |
|
16 |
LruCache<shash::Md5, catalog::DirectoryEntry>::Insert(hash, dirent); |
127 |
|
16 |
return result; |
128 |
|
|
} |
129 |
|
|
|
130 |
|
2 |
bool InsertNegative(const shash::Md5 &hash) { |
131 |
|
2 |
const bool result = Insert(hash, dirent_negative_); |
132 |
✓✗ |
2 |
if (result) |
133 |
|
2 |
perf::Inc(counters_.n_insert_negative); |
134 |
|
2 |
return result; |
135 |
|
|
} |
136 |
|
|
|
137 |
|
27 |
bool Lookup(const shash::Md5 &hash, catalog::DirectoryEntry *dirent, |
138 |
|
|
bool update_lru = true) |
139 |
|
|
{ |
140 |
|
|
const bool result = |
141 |
|
27 |
LruCache<shash::Md5, catalog::DirectoryEntry>::Lookup(hash, dirent); |
142 |
|
|
LogCvmfs(kLogLru, kLogDebug, "lookup md5 --> dirent: %s (%s)", |
143 |
✓✓ |
27 |
hash.ToString().c_str(), result ? "hit" : "miss"); |
144 |
|
27 |
return result; |
145 |
|
|
} |
146 |
|
|
|
147 |
|
|
bool Forget(const shash::Md5 &hash) { |
148 |
|
|
LogCvmfs(kLogLru, kLogDebug, "forget md5: %s", |
149 |
|
|
hash.ToString().c_str()); |
150 |
|
|
return LruCache<shash::Md5, catalog::DirectoryEntry>::Forget(hash); |
151 |
|
|
} |
152 |
|
|
|
153 |
|
|
void Drop() { |
154 |
|
|
LogCvmfs(kLogLru, kLogDebug, "dropping md5path cache"); |
155 |
|
|
LruCache<shash::Md5, catalog::DirectoryEntry>::Drop(); |
156 |
|
|
} |
157 |
|
|
|
158 |
|
|
private: |
159 |
|
|
catalog::DirectoryEntry dirent_negative_; |
160 |
|
|
}; // Md5PathCache |
161 |
|
|
|
162 |
|
|
} // namespace lru |
163 |
|
|
|
164 |
|
|
#endif // CVMFS_LRU_MD_H_ |