Added clients side file access prediction

git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1302 29311d96-e01e-0410-9327-a35deaab8ce9
This commit is contained in:
anwleung 2007-03-25 04:10:17 +00:00
parent 772e4e7808
commit fc112a7ee1
3 changed files with 94 additions and 0 deletions

View 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;

View 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);

View File

@ -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