Loading include/client/cache.hpp +11 −3 Original line number Diff line number Diff line Loading @@ -42,16 +42,20 @@ namespace gkfs::cache { namespace dir { struct cache_entry { gkfs::filemap::FileType file_type; uint64_t size; time_t ctime; }; class Cache { class DentryCache { private: // <dir_id, <name, cache_entry>> std::unordered_map<uint32_t, std::unordered_map<std::string, cache_entry>> entries_; // <dir_path, dir_id> std::unordered_map<std::string, uint32_t> entry_dir_id_; std::mutex mtx_; std::hash<std::string> str_hash; Loading @@ -63,9 +67,9 @@ private: get_dir_id(const std::string& dir_path); public: Cache() = default; DentryCache() = default; virtual ~Cache() = default; virtual ~DentryCache() = default; void insert(const std::string& parent_dir, const std::string name, Loading @@ -83,6 +87,10 @@ public: void clear(); }; } // namespace dir //// <path<cnt, size>> // std::unordered_map<std::string, std::pair<size_t, size_t>> size_cache; } // namespace gkfs::cache Loading include/client/env.hpp +1 −1 Original line number Diff line number Diff line Loading @@ -60,7 +60,7 @@ static constexpr auto METRICS_IP_PORT = ADD_PREFIX("METRICS_IP_PORT"); static constexpr auto NUM_REPL = ADD_PREFIX("NUM_REPL"); static constexpr auto PROXY_PID_FILE = ADD_PREFIX("PROXY_PID_FILE"); static constexpr auto DIR_CACHE = ADD_PREFIX("ENABLE_DIR_CACHE"); static constexpr auto DISABLE_DENTRY_CACHE = ADD_PREFIX("DISABLE_DENTRY_CACHE"); } // namespace gkfs::env Loading include/client/preload_context.hpp +13 −8 Original line number Diff line number Diff line Loading @@ -56,7 +56,12 @@ class ClientMetrics; } namespace cache { class Cache; namespace dir { class DentryCache; } namespace file { class WriteSizeCache; } } namespace preload { Loading Loading @@ -94,8 +99,8 @@ private: std::shared_ptr<gkfs::filemap::OpenFileMap> ofm_; std::shared_ptr<gkfs::rpc::Distributor> distributor_; std::shared_ptr<FsConfig> fs_conf_; std::shared_ptr<gkfs::cache::Cache> cache_; bool use_cache_{false}; std::shared_ptr<gkfs::cache::dir::DentryCache> dentry_cache_; bool use_dentry_cache_{false}; std::string cwd_; std::vector<std::string> mountdir_components_; Loading Loading @@ -235,17 +240,17 @@ public: const std::shared_ptr<FsConfig>& fs_conf() const; std::shared_ptr<gkfs::cache::Cache> cache() const; std::shared_ptr<gkfs::cache::dir::DentryCache> dentry_cache() const; void cache(std::shared_ptr<gkfs::cache::Cache> cache); dentry_cache(std::shared_ptr<gkfs::cache::dir::DentryCache> dentry_cache); bool use_cache() const; use_dentry_cache() const; void use_cache(bool use_cache); use_dentry_cache(bool use_dentry_cache); void Loading include/config.hpp +13 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,19 @@ constexpr auto hostfile_path = "./gkfs_hosts.txt"; // We do not default this, ENV variable always required. constexpr auto forwarding_file_path = ""; namespace cache { // Optimization for readdir which avoids consecutive stat calls constexpr bool use_dentry_cache = true; // When enabled, the dentry cache is cleared when a directory is closed. // Disabling this may cause semantic issues. constexpr bool clear_dentry_cache_on_close = true; // When enabled, write operations no longer update the file size on each write. // Instead, the size is updated every `max_write_size_cache` writes per file. // fsync/close flushes the size to the server immediately. constexpr bool use_write_size_cache = true; constexpr auto max_write_size_cache = 100; } // namespace cache namespace client_metrics { // Default directory where client metrics are stored. Can be set via // LIBGKFS_METRICS_PATH. Filename consists of starting time, pid, and hostname Loading src/client/cache.cpp +12 −8 Original line number Diff line number Diff line Loading @@ -40,13 +40,15 @@ namespace gkfs::cache { namespace dir { uint32_t Cache::gen_dir_id(const std::string& dir_path) { DentryCache::gen_dir_id(const std::string& dir_path) { return str_hash(dir_path); } uint32_t Cache::get_dir_id(const std::string& dir_path) { DentryCache::get_dir_id(const std::string& dir_path) { // check if id already exists in map and return if(entry_dir_id_.find(dir_path) != entry_dir_id_.end()) { return entry_dir_id_[dir_path]; Loading @@ -59,7 +61,7 @@ Cache::get_dir_id(const std::string& dir_path) { void Cache::insert(const std::string& parent_dir, const std::string name, DentryCache::insert(const std::string& parent_dir, const std::string name, const cache_entry value) { std::lock_guard<std::mutex> const lock(mtx_); auto dir_id = get_dir_id(parent_dir); Loading @@ -67,7 +69,7 @@ Cache::insert(const std::string& parent_dir, const std::string name, } std::optional<cache_entry> Cache::get(const std::string& parent_dir, const std::string& name) { DentryCache::get(const std::string& parent_dir, const std::string& name) { std::lock_guard<std::mutex> const lock(mtx_); auto dir_id = get_dir_id(parent_dir); if(entries_[dir_id].find(name) != entries_[dir_id].end()) { Loading @@ -78,7 +80,7 @@ Cache::get(const std::string& parent_dir, const std::string& name) { } void Cache::clear_dir(const std::string& dir_path) { DentryCache::clear_dir(const std::string& dir_path) { std::lock_guard<std::mutex> const lock(mtx_); auto id_it = entry_dir_id_.find(dir_path); Loading @@ -93,7 +95,7 @@ Cache::clear_dir(const std::string& dir_path) { } void Cache::dump_cache_to_log(const std::string& dir_path) { DentryCache::dump_cache_to_log(const std::string& dir_path) { std::lock_guard<std::mutex> const lock(mtx_); auto id_it = entry_dir_id_.find(dir_path); if(id_it == entry_dir_id_.end()) { Loading @@ -113,10 +115,12 @@ Cache::dump_cache_to_log(const std::string& dir_path) { } void Cache::clear() { DentryCache::clear() { std::lock_guard<std::mutex> const lock(mtx_); entries_.clear(); entry_dir_id_.clear(); } } // namespace dir } // namespace gkfs::cache Loading
include/client/cache.hpp +11 −3 Original line number Diff line number Diff line Loading @@ -42,16 +42,20 @@ namespace gkfs::cache { namespace dir { struct cache_entry { gkfs::filemap::FileType file_type; uint64_t size; time_t ctime; }; class Cache { class DentryCache { private: // <dir_id, <name, cache_entry>> std::unordered_map<uint32_t, std::unordered_map<std::string, cache_entry>> entries_; // <dir_path, dir_id> std::unordered_map<std::string, uint32_t> entry_dir_id_; std::mutex mtx_; std::hash<std::string> str_hash; Loading @@ -63,9 +67,9 @@ private: get_dir_id(const std::string& dir_path); public: Cache() = default; DentryCache() = default; virtual ~Cache() = default; virtual ~DentryCache() = default; void insert(const std::string& parent_dir, const std::string name, Loading @@ -83,6 +87,10 @@ public: void clear(); }; } // namespace dir //// <path<cnt, size>> // std::unordered_map<std::string, std::pair<size_t, size_t>> size_cache; } // namespace gkfs::cache Loading
include/client/env.hpp +1 −1 Original line number Diff line number Diff line Loading @@ -60,7 +60,7 @@ static constexpr auto METRICS_IP_PORT = ADD_PREFIX("METRICS_IP_PORT"); static constexpr auto NUM_REPL = ADD_PREFIX("NUM_REPL"); static constexpr auto PROXY_PID_FILE = ADD_PREFIX("PROXY_PID_FILE"); static constexpr auto DIR_CACHE = ADD_PREFIX("ENABLE_DIR_CACHE"); static constexpr auto DISABLE_DENTRY_CACHE = ADD_PREFIX("DISABLE_DENTRY_CACHE"); } // namespace gkfs::env Loading
include/client/preload_context.hpp +13 −8 Original line number Diff line number Diff line Loading @@ -56,7 +56,12 @@ class ClientMetrics; } namespace cache { class Cache; namespace dir { class DentryCache; } namespace file { class WriteSizeCache; } } namespace preload { Loading Loading @@ -94,8 +99,8 @@ private: std::shared_ptr<gkfs::filemap::OpenFileMap> ofm_; std::shared_ptr<gkfs::rpc::Distributor> distributor_; std::shared_ptr<FsConfig> fs_conf_; std::shared_ptr<gkfs::cache::Cache> cache_; bool use_cache_{false}; std::shared_ptr<gkfs::cache::dir::DentryCache> dentry_cache_; bool use_dentry_cache_{false}; std::string cwd_; std::vector<std::string> mountdir_components_; Loading Loading @@ -235,17 +240,17 @@ public: const std::shared_ptr<FsConfig>& fs_conf() const; std::shared_ptr<gkfs::cache::Cache> cache() const; std::shared_ptr<gkfs::cache::dir::DentryCache> dentry_cache() const; void cache(std::shared_ptr<gkfs::cache::Cache> cache); dentry_cache(std::shared_ptr<gkfs::cache::dir::DentryCache> dentry_cache); bool use_cache() const; use_dentry_cache() const; void use_cache(bool use_cache); use_dentry_cache(bool use_dentry_cache); void Loading
include/config.hpp +13 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,19 @@ constexpr auto hostfile_path = "./gkfs_hosts.txt"; // We do not default this, ENV variable always required. constexpr auto forwarding_file_path = ""; namespace cache { // Optimization for readdir which avoids consecutive stat calls constexpr bool use_dentry_cache = true; // When enabled, the dentry cache is cleared when a directory is closed. // Disabling this may cause semantic issues. constexpr bool clear_dentry_cache_on_close = true; // When enabled, write operations no longer update the file size on each write. // Instead, the size is updated every `max_write_size_cache` writes per file. // fsync/close flushes the size to the server immediately. constexpr bool use_write_size_cache = true; constexpr auto max_write_size_cache = 100; } // namespace cache namespace client_metrics { // Default directory where client metrics are stored. Can be set via // LIBGKFS_METRICS_PATH. Filename consists of starting time, pid, and hostname Loading
src/client/cache.cpp +12 −8 Original line number Diff line number Diff line Loading @@ -40,13 +40,15 @@ namespace gkfs::cache { namespace dir { uint32_t Cache::gen_dir_id(const std::string& dir_path) { DentryCache::gen_dir_id(const std::string& dir_path) { return str_hash(dir_path); } uint32_t Cache::get_dir_id(const std::string& dir_path) { DentryCache::get_dir_id(const std::string& dir_path) { // check if id already exists in map and return if(entry_dir_id_.find(dir_path) != entry_dir_id_.end()) { return entry_dir_id_[dir_path]; Loading @@ -59,7 +61,7 @@ Cache::get_dir_id(const std::string& dir_path) { void Cache::insert(const std::string& parent_dir, const std::string name, DentryCache::insert(const std::string& parent_dir, const std::string name, const cache_entry value) { std::lock_guard<std::mutex> const lock(mtx_); auto dir_id = get_dir_id(parent_dir); Loading @@ -67,7 +69,7 @@ Cache::insert(const std::string& parent_dir, const std::string name, } std::optional<cache_entry> Cache::get(const std::string& parent_dir, const std::string& name) { DentryCache::get(const std::string& parent_dir, const std::string& name) { std::lock_guard<std::mutex> const lock(mtx_); auto dir_id = get_dir_id(parent_dir); if(entries_[dir_id].find(name) != entries_[dir_id].end()) { Loading @@ -78,7 +80,7 @@ Cache::get(const std::string& parent_dir, const std::string& name) { } void Cache::clear_dir(const std::string& dir_path) { DentryCache::clear_dir(const std::string& dir_path) { std::lock_guard<std::mutex> const lock(mtx_); auto id_it = entry_dir_id_.find(dir_path); Loading @@ -93,7 +95,7 @@ Cache::clear_dir(const std::string& dir_path) { } void Cache::dump_cache_to_log(const std::string& dir_path) { DentryCache::dump_cache_to_log(const std::string& dir_path) { std::lock_guard<std::mutex> const lock(mtx_); auto id_it = entry_dir_id_.find(dir_path); if(id_it == entry_dir_id_.end()) { Loading @@ -113,10 +115,12 @@ Cache::dump_cache_to_log(const std::string& dir_path) { } void Cache::clear() { DentryCache::clear() { std::lock_guard<std::mutex> const lock(mtx_); entries_.clear(); entry_dir_id_.clear(); } } // namespace dir } // namespace gkfs::cache