]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
Added clients side file access prediction
authoranwleung <anwleung@29311d96-e01e-0410-9327-a35deaab8ce9>
Sun, 25 Mar 2007 04:10:17 +0000 (04:10 +0000)
committeranwleung <anwleung@29311d96-e01e-0410-9327-a35deaab8ce9>
Sun, 25 Mar 2007 04:10:17 +0000 (04:10 +0000)
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1302 29311d96-e01e-0410-9327-a35deaab8ce9

branches/aleung/security1/ceph/client/Client.cc
branches/aleung/security1/ceph/client/Client.h
branches/aleung/security1/ceph/crypto/RecentPopularity.h [new file with mode: 0644]

index 94a7eb09ce58b8ee4200b0ade49a89afcb7fdaa9..6bdbe2c025fe75f31125d27b6f7721a76aa1a672 100644 (file)
@@ -2533,9 +2533,19 @@ int Client::open(const char *relpath, int flags, __int64_t uid, __int64_t gid)
     return -EPERM;
   }
 
+
   string abspath;
   mkabspath(relpath, abspath);
   const char *path = abspath.c_str();
+  
+  // note the successor relationship
+  predicter[uid].add_observation(abspath, successor[uid]);
+  string prediction = predicter[uid].predict_successor(abspath);
+  successor[uid] = abspath;
+  if (prediction.size() == 0)
+    cout << "Could not make confident prediction" << endl;
+  else
+    cout << "Predicted access of " << prediction << endl;
 
   dout(3) << "op: fh = client->open(\"" << path << "\", " << flags << ");" << endl;
   tout << "open" << endl;
index ccbf3d27b3583b6d83ce5f4b8507a9d353740d2b..95be526a10de9b75e955e74992df71db865fb78f 100644 (file)
@@ -51,6 +51,7 @@ using namespace CryptoLib;
 #include "crypto/Ticket.h"
 #include "crypto/CapGroup.h"
 #include "crypto/MerkleTree.h"
+#include "crypto/RecentPopularity.h"
 //#include "ClientCapCache.h"
 
 // stl
@@ -529,6 +530,10 @@ protected:
   // renew caps that are in use (leaves a re-use grace period)
   // expunge caps that are not open, are expired and have no extension
 
+  // prediction
+  map<uid_t, string > successor;
+  map<uid_t, RecentPopularity> predicter;
+
   Ticket *get_user_ticket(uid_t uid, gid_t gid);
   void put_user_ticket(Ticket *tk);
 
diff --git a/branches/aleung/security1/ceph/crypto/RecentPopularity.h b/branches/aleung/security1/ceph/crypto/RecentPopularity.h
new file mode 100644 (file)
index 0000000..8904ce2
--- /dev/null
@@ -0,0 +1,79 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software 
+ * Foundation.  See file COPYING.
+ * 
+ */
+
+#ifndef __RECENTPOPULARITY_H
+#define __RECENTPOPULARITY_H
+
+class RecentPopularity {
+  // confidence parameter (4 is a happy default)
+  int J;
+  // sequence size parameter (6 is a happy default)
+  int K;
+  map < string, deque<string> > inode_sequences;
+public:
+  RecentPopularity() : J(4), K(6) {}
+  RecentPopularity(int jay, int kay) : J(jay), K(kay) {}
+  
+  void add_observation(string X, string successor) {
+    inode_sequences[X].push_back(successor);
+    
+    if (inode_sequences[X].size() > (unsigned)K)
+      inode_sequences[X].pop_front();
+  }
+
+  string predict_successor(string X) {
+
+    // is our known sequence big enough?
+    if (inode_sequences[X].size() < (unsigned)K)
+      return string();
+
+    // can we make a prediction with confidence?
+    set<string> checked_inodes;
+    unsigned int index = 0;
+    for (deque<string>::reverse_iterator iri = inode_sequences[X].rbegin();
+        iri != inode_sequences[X].rend();
+        iri++) {
+      
+      // dont even bother if weve already searched
+      if (checked_inodes.count(*iri) == 0) {
+
+       // are there enough unchecked inodes to even keep going?
+       if (inode_sequences[X].size() - index >= (unsigned)J) {
+         int occurance = 0;
+         for (deque<string>::reverse_iterator ini = iri;
+              ini != inode_sequences[X].rend();
+              ini++) {
+           
+           // do we have a match?
+           if ((*ini) == (*iri))
+             occurance++;
+           if (occurance > J)
+             return (*iri);
+         }
+       }
+       else
+         return 0;
+       
+       // mark the inode as seen
+       checked_inodes.insert(*iri);
+      }
+
+      index++;
+    }
+
+    // we cannot make a guess with confidnce
+    return 0;
+  }
+};
+
+#endif