24 #include "leveldb/cache.h"
25 #include "leveldb/db.h"
26 #include "leveldb/filter_policy.h"
39 : leveldb::EnvWrapper(leveldb::Env::Default()), maps_(maps) {
45 if (maps_->spawned_) {
46 leveldb::Env::Default()->StartThread(f, a);
50 "single threaded leveldb::StartThread called");
57 if (maps_->spawned_) {
58 leveldb::Env::Default()->Schedule(
function, arg);
66 atomic_inc32(&num_bg_threads_);
68 int retval = pthread_create(&bg_thread, NULL, MainFakeThread, funcarg);
70 retval = pthread_detach(bg_thread);
76 while (atomic_read32(&num_bg_threads_) > 0)
102 const uint64_t root_inode,
108 "total number of issued inode");
112 leveldb::Status status;
113 leveldb::Options leveldb_options;
114 leveldb_options.create_if_missing =
true;
120 "rebuilding NFS maps, might result in stale entries");
121 const bool retval =
RemoveTree(leveldb_dir +
"/inode2path") &&
138 status.ToString().c_str());
146 leveldb_options.block_size = 512;
155 status.ToString().c_str());
163 if (maps->
seq_ == 0) {
176 unsigned remainder) {
178 if (residue_class < 2) {
191 leveldb::Status status;
192 const leveldb::Slice key(reinterpret_cast<const char *>(path.
digest),
196 status =
db_path2inode_->Get(leveldb::ReadOptions(), key, &result);
197 if (!status.ok() && !status.IsNotFound()) {
199 path.
ToString().c_str(), status.ToString().c_str());
202 if (status.IsNotFound()) {
207 const uint64_t *inode =
reinterpret_cast<const uint64_t *
>(result.data());
245 leveldb::Status status;
246 const leveldb::Slice key(reinterpret_cast<const char *>(&inode),
250 status =
db_inode2path_->Get(leveldb::ReadOptions(), key, &result);
251 if (status.IsNotFound()) {
253 "failed to find inode %" PRIu64
" in NFS maps, returning ESTALE",
259 "failed to read from inode2path db inode %" PRIu64
": %s", inode,
260 status.ToString().c_str());
263 path->
Assign(result.data(), result.length());
273 db_inode2path_->GetProperty(leveldb::Slice(
"leveldb.stats"), &stats);
274 stats +=
"inode --> path database:\n" + stats +
"\n";
276 db_path2inode_->GetProperty(leveldb::Slice(
"leveldb.stats"), &stats);
277 stats +=
"path --> inode database:\n" + stats +
"\n";
298 lock_ =
reinterpret_cast<pthread_mutex_t *
>(smalloc(
sizeof(pthread_mutex_t)));
299 const int retval = pthread_mutex_init(
lock_, NULL);
316 pthread_mutex_destroy(
lock_);
323 leveldb::Status status;
324 const leveldb::Slice key(reinterpret_cast<const char *>(&inode),
328 status =
db_inode2path_->Put(leveldb::WriteOptions(), key, value);
331 "failed to write inode2path entry (%" PRIu64
" --> %s): %s", inode,
332 path.
c_str(), status.ToString().c_str());
335 inode, path.
c_str());
340 const uint64_t inode) {
341 leveldb::Status status;
342 const leveldb::Slice key(reinterpret_cast<const char *>(path.
digest),
344 const leveldb::Slice value(reinterpret_cast<const char *>(&inode),
347 status =
db_path2inode_->Put(leveldb::WriteOptions(), key, value);
350 "failed to write path2inode entry (%s --> %" PRIu64
"): %s",
351 path.
ToString().c_str(), inode, status.ToString().c_str());
Counter * Register(const std::string &name, const std::string &desc)
virtual bool GetPath(const uint64_t inode, PathString *path)
virtual void SetInodeResidue(unsigned residue_class, unsigned remainder)
const leveldb::FilterPolicy * filter_inode2path_
atomic_int32 num_bg_threads_
std::string ToString(const bool with_suffix=false) const
void Assign(const char *chars, const unsigned length)
static NfsMapsLeveldb * Create(const std::string &leveldb_dir, const uint64_t root_inode, const bool rebuild, perf::Statistics *statistics)
uint64_t FindInode(const shash::Md5 &path)
virtual uint64_t GetInode(const PathString &path)
perf::Counter * n_db_added_
assert((mem||(size==0))&&"Out Of Memory")
leveldb::DB * db_path2inode_
unsigned char digest[digest_size_]
unsigned inode_residue_class_
void PutInode2Path(const uint64_t inode, const PathString &path)
ForkAwareEnv(NfsMapsLeveldb *maps)
static void * MainFakeThread(void *data)
unsigned GetDigestSize() const
virtual std::string GetStatistics()
leveldb::DB * db_inode2path_
leveldb::Cache * cache_path2inode_
unsigned inode_remainder_
void Schedule(void(*function)(void *), void *arg)
void PutPath2Inode(const shash::Md5 &path, const uint64_t inode)
virtual ~NfsMapsLeveldb()
void StartThread(void(*f)(void *), void *a)
void Inc(class Counter *counter)
bool RemoveTree(const std::string &path)
void SleepForMicroseconds(int micros)
const leveldb::FilterPolicy * filter_path2inode_
void SafeSleepMs(const unsigned ms)
unsigned GetLength() const
ForkAwareEnv * fork_aware_env_
const char * c_str() const
const char * GetChars() const
leveldb::Cache * cache_inode2path_
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)