Skip to content
Snippets Groups Projects
Commit 8d1dd7a3 authored by Avi Kivity's avatar Avi Kivity
Browse files

fs: directory entry cache

Store directory entries in a hash table for future lookup.
parent 27c32e95
No related branches found
No related tags found
No related merge requests found
......@@ -53,7 +53,7 @@ bootfs::dir::dir(bootfs& fs, std::string path)
{
}
fileref bootfs::dir::open(std::string name)
fileref bootfs::dir::do_open(std::string name)
{
return _fs.do_open(_path + name);
}
......
......@@ -33,7 +33,7 @@ private:
class bootfs::dir : public ::dir {
public:
dir(bootfs& fs, std::string path);
virtual fileref open(std::string name);
virtual fileref do_open(std::string name);
virtual uint64_t size();
virtual void read(void* buffer, uint64_t offset, uint64_t len);
private:
......
......@@ -2,6 +2,18 @@
filesystem* rootfs;
namespace std {
template <>
struct hash<file::cache_key> {
size_t operator()(file::cache_key k) const {
return reinterpret_cast<uintptr_t>(k.first.get())
^ std::hash<std::string>()(k.second);
}
};
}
file::file()
: _refs(0)
{
......@@ -43,8 +55,21 @@ fileref filesystem::open(std::string name)
return d->open(name.substr(s, name.npos));
}
fileref dir::open(std::string name)
{
cache_key key(this, name);
auto ret = _cache.find(key);
if (ret == _cache.end()) {
auto f = do_open(name);
ret = _cache.insert(cache_type::value_type(key, f)).first;
}
return ret->second;
}
dirref dir::subdir(std::string name)
{
// trivial implementation, can be overridden
return boost::dynamic_pointer_cast<dir>(open(name));
}
file::cache_type file::_cache;
......@@ -4,6 +4,7 @@
#include <string>
#include <cstdint>
#include <boost/intrusive_ptr.hpp>
#include <unordered_map>
class file;
class dir;
......@@ -24,12 +25,23 @@ private:
unsigned _refs; // FIXME: make atomic
friend void intrusive_ptr_add_ref(file* f) { f->ref(); }
friend void intrusive_ptr_release(file* f) { f->unref(); }
friend class dir;
private:
typedef std::pair<dirref, std::string> cache_key;
// FIXME: an intrusive container
typedef std::unordered_map<cache_key, fileref> cache_type;
static cache_type _cache;
friend struct std::hash<cache_key>;
};
class dir : public file {
public:
virtual fileref open(std::string name) = 0;
fileref open(std::string name);
virtual fileref do_open(std::string name) = 0;
dirref subdir(std::string name);
private:
dirref _parent;
std::string _name;
};
class filesystem {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment