From: Matt Benjamin Date: Tue, 22 Dec 2015 07:15:42 +0000 (-0500) Subject: librgw: implement small-directory name cache X-Git-Tag: v10.1.0~382^2~76 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=453219cb12d3de60c422fb98fce86d46ea26cbb9;p=ceph.git 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 --- 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; }