39 "inodes (path TEXT PRIMARY KEY);";
41 kSqlAddRoot =
"INSERT INTO inodes (oid, path) VALUES (?, ?);";
55 "busy handler, attempt %d, accumulated waiting time %u", attempt,
60 const unsigned backoff_range_ms = 1 << attempt;
61 unsigned backoff_ms = handler_info->
prng.
Next(backoff_range_ms);
76 const uint64_t root_inode,
82 "total number of issued inode");
86 "inode --> path hits");
88 "path --> inode hits");
90 string db_path = db_dir +
"/inode_maps.db";
95 "Ignoring rebuild flag as this may crash other cluster nodes.");
98 int retval = sqlite3_enable_shared_cache(0);
99 assert(retval == SQLITE_OK);
101 retval = sqlite3_open_v2(
102 db_path.c_str(), &maps->
db_,
103 SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
104 if (retval != SQLITE_OK) {
112 retval = sqlite3_busy_handler(maps->
db_, BusyHandler,
114 assert(retval == SQLITE_OK);
117 retval = sqlite3_prepare_v2(maps->
db_, kSqlCreateTable, -1, &stmt, NULL);
118 if (retval != SQLITE_OK) {
120 "Failed to prepare create table statement: %s",
121 sqlite3_errmsg(maps->
db_));
124 if (sqlite3_step(stmt) != SQLITE_DONE) {
126 "Failed to create main inode table: %s",
127 sqlite3_errmsg(maps->
db_));
128 sqlite3_finalize(stmt);
131 sqlite3_finalize(stmt);
136 assert(retval == SQLITE_OK);
137 retval = sqlite3_prepare_v2(maps->
db_, kSqlGetInode, -1,
139 assert(retval == SQLITE_OK);
140 retval = sqlite3_prepare_v2(maps->
db_, kSqlAddInode, -1, &maps->
stmt_add_,
142 assert(retval == SQLITE_OK);
147 retval = sqlite3_prepare_v2(maps->
db_, kSqlAddRoot, -1, &stmt, NULL);
148 assert(retval == SQLITE_OK);
149 retval = sqlite3_bind_int64(stmt, 1, root_inode);
150 assert(retval == SQLITE_OK);
151 retval = sqlite3_bind_text(stmt, 2,
"", 0, SQLITE_TRANSIENT);
152 assert(retval == SQLITE_OK);
153 if (sqlite3_step(stmt) != SQLITE_DONE) {
155 sqlite3_errmsg(maps->
db_));
157 sqlite3_finalize(stmt);
171 sqlite_state = sqlite3_bind_text(stmt_get_inode_, 1, path.
GetChars(),
173 assert(sqlite_state == SQLITE_OK);
174 sqlite_state = sqlite3_step(stmt_get_inode_);
175 if (sqlite_state == SQLITE_DONE) {
177 sqlite3_reset(stmt_get_inode_);
180 if (sqlite_state != SQLITE_ROW) {
182 path.
c_str(), sqlite3_errmsg(db_));
183 sqlite3_reset(stmt_get_inode_);
186 inode = sqlite3_column_int64(stmt_get_inode_, 0);
187 sqlite3_reset(stmt_get_inode_);
199 sqlite_state = sqlite3_prepare_v2(db_, kSqlAddInode, -1, &stmt_add_, NULL);
200 assert(sqlite_state == SQLITE_OK);
201 sqlite_state = sqlite3_bind_text(stmt_add_, 1, path.
GetChars(),
203 if (sqlite_state != SQLITE_OK) {
206 sqlite3_reset(stmt_add_);
209 sqlite_state = sqlite3_step(stmt_add_);
210 if (sqlite_state != SQLITE_DONE) {
212 "Failed to execute SQL for IssueInode (%s): %s", path.
c_str(),
213 sqlite3_errmsg(db_));
214 sqlite3_reset(stmt_add_);
217 inode = sqlite3_last_insert_rowid(db_);
218 sqlite3_reset(stmt_add_);
219 n_db_seq_->Set(inode);
236 inode = FindInode(path);
242 inode = IssueInode(path);
246 inode = RetryGetInode(path, attempt + 1);
256 return RetryGetInode(path, 0);
270 sqlite_state = sqlite3_bind_int64(stmt_get_path_, 1, inode);
271 assert(sqlite_state == SQLITE_OK);
272 sqlite_state = sqlite3_step(stmt_get_path_);
273 if (sqlite_state == SQLITE_DONE) {
275 sqlite3_reset(stmt_get_path_);
278 if (sqlite_state != SQLITE_ROW) {
280 inode, sqlite3_errmsg(db_));
282 const char *raw_path = (
const char *)sqlite3_column_text(stmt_get_path_, 0);
283 path->
Assign(raw_path, strlen(raw_path));
284 sqlite3_reset(stmt_get_path_);
292 , stmt_get_path_(NULL)
293 , stmt_get_inode_(NULL)
298 , n_db_path_found_(NULL)
299 , n_db_inode_found_(NULL) {
300 lock_ =
reinterpret_cast<pthread_mutex_t *
>(smalloc(
sizeof(pthread_mutex_t)));
301 int retval = pthread_mutex_init(
lock_, NULL);
314 sqlite3_close_v2(
db_);
315 pthread_mutex_destroy(
lock_);
perf::Counter * n_db_added_
Counter * Register(const std::string &name, const std::string &desc)
static const char * kSqlGetPath
static NfsMapsSqlite * Create(const std::string &db_dir, const uint64_t root_inode, const bool rebuild, perf::Statistics *statistics_)
perf::Counter * n_db_seq_
void Assign(const char *chars, const unsigned length)
uint64_t FindInode(const PathString &path)
static const char * kSqlAddRoot
assert((mem||(size==0))&&"Out Of Memory")
BusyHandlerInfo busy_handler_info_
static const char * kSqlGetInode
static const unsigned kMaxWaitMs
virtual uint64_t GetInode(const PathString &path)
static int BusyHandler(void *data, int attempt)
static const char * kSqlCreateTable
static const unsigned kMaxBackoffMs
virtual bool GetPath(const uint64_t inode, PathString *path)
void Inc(class Counter *counter)
perf::Counter * n_db_inode_found_
sqlite3_stmt * stmt_get_inode_
uint64_t RetryGetInode(const PathString &path, int attempt)
uint64_t IssueInode(const PathString &path)
perf::Counter * n_db_path_found_
void SafeSleepMs(const unsigned ms)
sqlite3_stmt * stmt_get_path_
unsigned GetLength() const
const char * c_str() const
const char * GetChars() const
static const char * kSqlAddInode
uint32_t Next(const uint64_t boundary)
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)