From 453219cb12d3de60c422fb98fce86d46ea26cbb9 Mon Sep 17 00:00:00 2001 From: Matt Benjamin Date: Tue, 22 Dec 2015 02:15:42 -0500 Subject: [PATCH] librgw: implement small-directory name cache Augment the existing marker cache with cache of name->type mappings for up to 128 dirents (appx. 4x the common upper-bound of 32). The motivation here is to use the name and type information from readdir, rather than discarding it. Boosts perf. at least 60% on unit test corpus. Signed-off-by: Matt Benjamin --- src/rgw/rgw_file.cc | 17 ++++++++++++++++- src/rgw/rgw_file.h | 18 ++++++++++++++---- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/rgw/rgw_file.cc b/src/rgw/rgw_file.cc index d9fd84c7d5f2..4dbb36559360 100644 --- a/src/rgw/rgw_file.cc +++ b/src/rgw/rgw_file.cc @@ -62,9 +62,24 @@ namespace rgw { { /* find either-of , , only one of * which should exist; atomicity? */ + using std::get; + LookupFHResult fhr{nullptr, 0}; + RGWFileHandle::directory* d = parent->get_directory(); + if (! d->name_cache.empty()) { + RGWFileHandle::dirent_string name{path}; + const auto& diter = d->name_cache.find(name); + if (diter != d->name_cache.end()) { + fhr = lookup_fh(parent, path, + RGWFileHandle::FLAG_CREATE| + ((diter->second == RGW_FS_TYPE_DIRECTORY) ? + RGWFileHandle::FLAG_DIRECTORY : + RGWFileHandle::FLAG_NONE)); + if (get<0>(fhr)) + return fhr; + } + } std::string object_name{path}; - for (auto ix : { 0, 1 }) { switch (ix) { case 0: diff --git a/src/rgw/rgw_file.h b/src/rgw/rgw_file.h index aaafd384c91e..d4eb03673dda 100644 --- a/src/rgw/rgw_file.h +++ b/src/rgw/rgw_file.h @@ -203,8 +203,8 @@ namespace rgw { private: RGWFileHandle(RGWLibFS* _fs, uint32_t fs_inst) - : fs(_fs), bucket(nullptr), parent(nullptr), depth(0), - flags(FLAG_ROOT) + : fs(_fs), bucket(nullptr), parent(nullptr), variant_type{directory()}, + depth(0), flags(FLAG_ROOT) { /* root */ fh.fh_type = RGW_FS_TYPE_DIRECTORY; @@ -231,12 +231,18 @@ namespace rgw { if (parent->is_root()) { fh.fh_type = RGW_FS_TYPE_DIRECTORY; + variant_type = directory(); flags |= FLAG_BUCKET; } else { bucket = (parent->flags & FLAG_BUCKET) ? parent : parent->bucket; - fh.fh_type = (flags & FLAG_DIRECTORY) ? RGW_FS_TYPE_DIRECTORY - : RGW_FS_TYPE_FILE; + if (flags & FLAG_DIRECTORY) { + fh.fh_type = RGW_FS_TYPE_DIRECTORY; + variant_type = directory(); + } else { + fh.fh_type = RGW_FS_TYPE_FILE; + variant_type = file(); + } } depth = parent->depth + 1; @@ -252,6 +258,10 @@ namespace rgw { return fhk; } + directory* get_directory() { + return get(&variant_type); + } + size_t get_size() const { return state.size; } uint16_t get_depth() const { return depth; } -- 2.47.3