From fdc782c1d15228986145213413cc1e8e12331a0e Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 25 Oct 2018 12:35:49 +0200 Subject: [PATCH] Add a very naive block cache to the DiskBackedFileSystem. This would be a lot better as an LRU. Right now it's a 32-slot hash table with random eviction. --- AK/HashMap.h | 9 ++++++++ AK/HashTable.h | 4 ++-- VirtualFileSystem/DiskBackedFileSystem.cpp | 24 +++++++++++++++++++++- VirtualFileSystem/DiskBackedFileSystem.h | 2 ++ 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/AK/HashMap.h b/AK/HashMap.h index 70f4259e05..0035732a16 100644 --- a/AK/HashMap.h +++ b/AK/HashMap.h @@ -49,9 +49,12 @@ public: bool isEmpty() const { return m_table.isEmpty(); } unsigned size() const { return m_table.size(); } unsigned capacity() const { return m_table.capacity(); } + void clear() { m_table.clear(); } + void set(const K&, const V&); void set(const K&, V&&); void remove(const K&); + void removeOneRandomly() { m_table.remove(m_table.begin()); } typedef HashTable HashTableType; typedef typename HashTableType::Iterator IteratorType; @@ -77,6 +80,12 @@ void HashMap::set(const K& key, V&& value) m_table.set(Entry{key, move(value)}); } +template +void HashMap::set(const K& key, const V& value) +{ + m_table.set(Entry{key, value}); +} + template void HashMap::remove(const K& key) { diff --git a/AK/HashTable.h b/AK/HashTable.h index 807b1e845b..df3caac0d6 100644 --- a/AK/HashTable.h +++ b/AK/HashTable.h @@ -216,7 +216,7 @@ public: remove(it); } - void remove(Iterator&); + void remove(Iterator); private: Bucket& lookup(const T&, unsigned* bucketIndex = nullptr); @@ -329,7 +329,7 @@ auto HashTable::find(const T& value) const -> ConstIterator } template -void HashTable::remove(Iterator& it) +void HashTable::remove(Iterator it) { ASSERT(!isEmpty()); m_buckets[it.m_bucketIndex].chain.remove(it.m_bucketIterator); diff --git a/VirtualFileSystem/DiskBackedFileSystem.cpp b/VirtualFileSystem/DiskBackedFileSystem.cpp index 7ff0beaf00..845e470eac 100644 --- a/VirtualFileSystem/DiskBackedFileSystem.cpp +++ b/VirtualFileSystem/DiskBackedFileSystem.cpp @@ -1,5 +1,11 @@ #include "DiskBackedFileSystem.h" +#ifdef SERENITY +#include "i386.h" +#else +typedef int InterruptDisabler; +#endif + //#define DBFS_DEBUG DiskBackedFileSystem::DiskBackedFileSystem(RetainPtr&& device) @@ -36,11 +42,26 @@ ByteBuffer DiskBackedFileSystem::readBlock(unsigned index) const #ifdef DBFS_DEBUG kprintf("DiskBackedFileSystem::readBlock %u\n", index); #endif + { + InterruptDisabler disabler; + auto it = m_blockCache.find(index); + if (it != m_blockCache.end()) { + return (*it).value; + } + } + auto buffer = ByteBuffer::createUninitialized(blockSize()); DiskOffset baseOffset = static_cast(index) * static_cast(blockSize()); auto* bufferPointer = buffer.pointer(); device().read(baseOffset, blockSize(), bufferPointer); ASSERT(buffer.size() == blockSize()); + + { + InterruptDisabler disabler; + if (m_blockCache.size() >= 32) + m_blockCache.removeOneRandomly(); + m_blockCache.set(index, buffer); + } return buffer; } @@ -74,5 +95,6 @@ void DiskBackedFileSystem::setBlockSize(unsigned blockSize) void DiskBackedFileSystem::invalidateCaches() { - // FIXME: Implement block cache. + InterruptDisabler disabler; + m_blockCache.clear(); } diff --git a/VirtualFileSystem/DiskBackedFileSystem.h b/VirtualFileSystem/DiskBackedFileSystem.h index 4b5f880a0c..e986ffa2df 100644 --- a/VirtualFileSystem/DiskBackedFileSystem.h +++ b/VirtualFileSystem/DiskBackedFileSystem.h @@ -2,6 +2,7 @@ #include "FileSystem.h" #include +#include class DiskBackedFileSystem : public FileSystem { public: @@ -27,4 +28,5 @@ protected: private: unsigned m_blockSize { 0 }; RetainPtr m_device; + mutable HashMap m_blockCache; };