From bd068089076822b625af541726ec4e6da725475c Mon Sep 17 00:00:00 2001 From: Matt Benjamin Date: Tue, 22 Dec 2015 01:06:06 -0500 Subject: [PATCH] librgw: fill in dirent cache Signed-off-by: Matt Benjamin --- src/rgw/rgw_file.h | 49 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/src/rgw/rgw_file.h b/src/rgw/rgw_file.h index 0ab6bfa444dca..c0636caa08922 100644 --- a/src/rgw/rgw_file.h +++ b/src/rgw/rgw_file.h @@ -142,6 +142,9 @@ namespace rgw { * w/90% of file names <= 31 (Yifan Wang, CMU) */ using dirent_string = basic_sstring; + using marker_cache_t = flat_map; + using name_cache_t = flat_map; + struct state { uint64_t dev; size_t size; @@ -159,9 +162,22 @@ namespace rgw { }; struct directory { + + static constexpr uint32_t FLAG_NONE = 0x0000; + static constexpr uint32_t FLAG_CACHED = 0x0001; + static constexpr uint32_t FLAG_OVERFLOW = 0x0002; + uint32_t flags; - flat_map marker_cache; - directory() : flags(0) {} + marker_cache_t marker_cache; + name_cache_t name_cache; + + directory() : flags(FLAG_NONE) {} + + void set_overflow() { + marker_cache.clear(); + name_cache.clear(); + flags |= FLAG_OVERFLOW; + } }; boost::variant variant_type; @@ -329,12 +345,22 @@ namespace rgw { } } - void add_marker(uint64_t off, const boost::string_ref& marker) { + void add_marker(uint64_t off, const boost::string_ref& marker, + uint8_t obj_type) { using std::get; directory* d = get(&variant_type); if (d) { + unique_lock guard(mtx); d->marker_cache.insert( - flat_map::value_type(off, marker.data())); + marker_cache_t::value_type(off, marker.data())); + /* 90% of directories hold <= 32 entries (Yifan Wang, CMU), + * but go big */ + if (d->name_cache.size() < 128) { + d->name_cache.insert( + name_cache_t::value_type(marker.data(), obj_type)); + } else { + d->set_overflow(); // too many + } } } @@ -786,12 +812,11 @@ public: // do nothing } - int operator()(const boost::string_ref& name, - const boost::string_ref& marker) { + int operator()(const boost::string_ref& name, const boost::string_ref& marker) { uint64_t off = XXH64(name.data(), name.length(), fh_key::seed); *offset = off; /* update traversal cache */ - rgw_fh->add_marker(off, marker); + rgw_fh->add_marker(off, marker, RGW_FS_TYPE_DIRECTORY); rcb(name.data(), cb_arg, (*offset)++); return 0; } @@ -862,14 +887,14 @@ public: return 0; } - int operator()(const boost::string_ref name, - const boost::string_ref marker) { + int operator()(const boost::string_ref name, const boost::string_ref marker, + uint8_t type) { /* hash offset of name in parent (short name) for NFS readdir cookie */ std::string sname{name}; uint64_t off = XXH64(name.data(), name.length(), fh_key::seed); *offset = off; /* update traversal cache */ - rgw_fh->add_marker(off, marker); + rgw_fh->add_marker(off, marker, type); rcb(name.data(), cb_arg, off); return 0; } @@ -907,7 +932,7 @@ public: << dendl; /* call me maybe */ - this->operator()(sref, sref); + this->operator()(sref, sref, RGW_FS_TYPE_FILE); ++ix; } for (auto& iter : common_prefixes) { @@ -936,7 +961,7 @@ public: << " cpref=" << sref << dendl; - this->operator()(sref, sref); + this->operator()(sref, sref, RGW_FS_TYPE_DIRECTORY); ++ix; } } -- 2.39.5