]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librgw: implement small-directory name cache
authorMatt Benjamin <mbenjamin@redhat.com>
Tue, 22 Dec 2015 07:15:42 +0000 (02:15 -0500)
committerMatt Benjamin <mbenjamin@redhat.com>
Fri, 12 Feb 2016 17:07:15 +0000 (12:07 -0500)
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 <mbenjamin@redhat.com>
src/rgw/rgw_file.cc
src/rgw/rgw_file.h

index d9fd84c7d5f2ac789128933313e30aa03040d9f4..4dbb365593604176cabf1d829a257009761df8b6 100644 (file)
@@ -62,9 +62,24 @@ namespace rgw {
   {
     /* find either-of <object_name>, <object_name/>, 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:
index aaafd384c91ed5276d4b48a5a3cdc5505ea782c2..d4eb03673ddac2a6a5fed9b73103c28518432ae7 100644 (file)
@@ -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<directory>(&variant_type);
+    }
+
     size_t get_size() const { return state.size; }
 
     uint16_t get_depth() const { return depth; }