]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: Add bloom filter to CDir.
authorGreg Farnum <gregf@hq.newdream.net>
Mon, 15 Nov 2010 20:59:29 +0000 (12:59 -0800)
committerGreg Farnum <gregf@hq.newdream.net>
Mon, 15 Nov 2010 21:31:25 +0000 (13:31 -0800)
You can now add items to a bloom filter and check for their existence.
This is intended to be used when trimming items out of the cache; the
filter is cleared when you mark_complete and is not transferred between
nodes. Neither does it change how you set or remove the STATE_COMPLETE flag.
You must explicitly check the bloom filter as appropriate; likewise, if
you start to fill it in you must always continue filling it in until
you delete the current instance of the filter.

Signed-off-by: Greg Farnum <gregf@hq.newdream.net>
src/mds/CDir.cc
src/mds/CDir.h

index 7203ee92407e6a85333dfd411e0775ff756771d0..dff4e09af9326f87bbeef1d1bd5cc2bd01424a72 100644 (file)
@@ -26,6 +26,7 @@
 #include "MDLog.h"
 #include "LogSegment.h"
 
+#include "include/bloom_filter.hpp"
 #include "include/Context.h"
 #include "common/Clock.h"
 
@@ -152,7 +153,7 @@ ostream& CDir::print_db_line_prefix(ostream& out)
 
 CDir::CDir(CInode *in, frag_t fg, MDCache *mdcache, bool auth) :
   dirty_rstat_inodes(member_offset(CInode, dirty_rstat_item)),
-  item_dirty(this), item_new(this)
+  item_dirty(this), item_new(this), bloom(NULL)
 {
   g_num_dir++;
   g_num_dira++;
@@ -516,6 +517,21 @@ void CDir::unlink_inode_work( CDentry *dn )
   }
 }
 
+void CDir::add_to_bloom(CDentry *dn)
+{
+  if (!bloom)
+    bloom = new bloom_filter(100, 0.05, 0);
+  /* This size and false positive probability is completely random.*/
+  bloom->insert(dn->name.c_str(), dn->name.size());
+}
+
+bool CDir::is_in_bloom(const string& name)
+{
+  if (!bloom)
+    return false;
+  return bloom->contains(name.c_str(), name.size());
+}
+
 void CDir::remove_null_dentries() {
   dout(12) << "remove_null_dentries " << *this << dendl;
 
@@ -1090,7 +1106,11 @@ void CDir::log_mark_dirty()
   mdlog->wait_for_sync(new C_Dir_Dirty(this, pv, mdlog->get_current_segment()));
 }
 
-
+void CDir::mark_complete() {
+  state_set(STATE_COMPLETE);
+  delete bloom;
+  bloom = NULL;
+}
 
 void CDir::first_get()
 {
index 5262841b01e826d6ffef5b4a00c1f346568da542..0a42e343633efb20c9be82529903463c1ab87f35 100644 (file)
@@ -38,6 +38,7 @@ class CDentry;
 class MDCache;
 class MDCluster;
 class Context;
+class bloom_filter;
 
 class ObjectOperation;
 
@@ -273,6 +274,10 @@ protected:
   friend class CDirDiscover;
   friend class CDirExport;
 
+  bloom_filter *bloom;
+  /* If you set up the bloom filter, you must keep it accurate!
+   * It's deleted when you mark_complete() and is deliberately not serialized.*/
+
  public:
   CDir(CInode *in, frag_t fg, MDCache *mdcache, bool auth);
   ~CDir() {
@@ -334,6 +339,10 @@ protected:
   void link_primary_inode( CDentry *dn, CInode *in );
   void unlink_inode( CDentry *dn );
   void try_remove_unlinked_dn(CDentry *dn);
+
+  void add_to_bloom(CDentry *dn);
+  bool is_in_bloom(const string& name);
+  bool has_bloom() { return (bloom ? true : false); }
 private:
   void link_inode_work( CDentry *dn, CInode *in );
   void unlink_inode_work( CDentry *dn );
@@ -475,7 +484,7 @@ private:
   version_t get_committed_version() { return committed_version; }
   void set_committed_version(version_t v) { committed_version = v; }
 
-  void mark_complete() { state_set(STATE_COMPLETE); }
+  void mark_complete();
 
 
   // -- reference counting --