diff --git a/Cache/BlockCache.h b/Cache/BlockCache.h index ce629e4..f740c32 100644 --- a/Cache/BlockCache.h +++ b/Cache/BlockCache.h @@ -4,12 +4,19 @@ #include #include +class MappedFile; +class Device::BlockDevice; + namespace Device { -class BlockDevice; -class MappedFile; +enum { + kBlockDirty = 1, + kBlockCommitNow = 2, + kBlockReuse = 3 +} BlockReleaseFlags; + class BlockCache { public: @@ -27,10 +34,11 @@ public: virtual void read(unsigned block, void *bp); virtual void *acquire(unsigned block) = 0; - virtual void release(unsigned block, bool dirty) = 0; + virtual void release(unsigned block, int flags) = 0 ; virtual void markDirty(unsigned block) = 0; - void release(unsigned block) { release(block, false); } + void release(unsigned block) { release(block, 0); } + void release(unsigned block, bool dirty) { release(block, dirty ? kBlockDirty : 0); } protected: BlockCache(BlockDevice *device); @@ -52,7 +60,7 @@ public: virtual void *acquire(unsigned block); - virtual void release(unsigned block, bool dirty); + virtual void release(unsigned block, int flags); virtual void markDirty(unsigned block); @@ -96,25 +104,6 @@ private: decrementCount(Entry *); }; -class MappedBlockCache : public BlockCache { - public: - - MappedBlockCache(BlockDevice *, void *data); - virtual ~MappedBlockCache(); - - virtual void sync() = 0; - virtual void write(unsigned block, const void *vp); - - - virtual void *acquire(unsigned block); - virtual void release(unsigned block, bool dirty); - virtual void markDirty(unsigned block); - - private: - void *_data; - -}; - } // namespace -#endif \ No newline at end of file +#endif diff --git a/Cache/ConcreteBlockCache.h b/Cache/ConcreteBlockCache.h new file mode 100644 index 0000000..2a97969 --- /dev/null +++ b/Cache/ConcreteBlockCache.h @@ -0,0 +1,64 @@ +#ifndef __CONCRETE_BLOCK_CACHE_H__ +#define __CONCRETE_BLOCK_CACHE_H__ + +#include + +#include + +namespace Device { + +class ConcreteBlockCache : public BlockCache { +public: + ConcreteBlockCache(BlockDevice *device, unsigned size = 16); + virtual ~ConcreteBlockCache(); + + virtual void sync(); + virtual void write(unsigned block, const void *vp) = 0; + + + virtual void *acquire(unsigned block); + virtual void release(unsigned block, int flags); + virtual void markDirty(unsigned block); + + +private: + struct Entry { + unsigned block; + unsigned count; + bool dirty; + + struct Entry *next; + struct Entry *prev; + struct Entry *nextHash; + + uint8_t buffer[512]; + + }; + + enum { HashTableSize = 23 }; + + std::vector_buffers; + + Entry *_hashTable[HashTableSize]; + + Entry *_first; + Entry *_last; + + + unsigned hashFunction(unsigned block); + + Entry *findEntry(unsigned block); + void removeEntry(unsigned block); + void addEntry(Entry *); + + Entry *newEntry(unsigned block); + + void pushEntry(Entry *); + + void setLast(Entry *); + + incrementCount(Entry *); + decrementCount(Entry *); +}; + +} diff --git a/Cache/MappedBlockCache.cpp b/Cache/MappedBlockCache.cpp new file mode 100644 index 0000000..d8a8da4 --- /dev/null +++ b/Cache/MappedBlockCache.cpp @@ -0,0 +1,65 @@ + +#include +#include + +#include +#include +#include + +#include +#include +#include + + + +using namespace Device; + +using ProFUSE::Exception; +using ProFUSE::POSIXException; + + +MappedBlockCache::MappedBlockCache(Device *device, void *data) : + BlockCache(device) +{ + _data = (uint8_t *)data; + _dirty = false; +} + +MappedBlockCache::~MappedBlockCache() +{ + if (_dirty) sync(); +} + + +void *MappedBlockCache::acquire(unsigned block) +{ +#undef __METHOD__ +#define __METHOD__ "MappedBlockCache::load" + + if (block >= blocks()) + throw Exception(__METHOD__ ": Invalid block."); + + + return _data + block * 512; +} + +void MappedBlockCache::unload(unsigned block, int flags) +{ +#undef __METHOD__ +#define __METHOD__ "MappedBlockCache::unload" + + if (flags & kBlockCommitNow) + { + _dirty = true; + sync(); + return; + } + + if (flags & kBlockDirty) _dirty = true; +} + +void MappedBlockCache::sync() +{ + _device->sync(); + _dirty = false; +} diff --git a/Cache/MappedBlockCache.h b/Cache/MappedBlockCache.h new file mode 100644 index 0000000..319a584 --- /dev/null +++ b/Cache/MappedBlockCache.h @@ -0,0 +1,30 @@ +#ifndef __MAPPED_BLOCK_CACHE_H__ +#define __MAPPED_BLOCK_CACHE_H__ + +#include + +namespace Device { + +class MappedBlockCache : public BlockCache { + public: + + MappedBlockCache(BlockDevice *, void *data); + virtual ~MappedBlockCache(); + + virtual void sync() = 0; + virtual void write(unsigned block, const void *vp); + + + virtual void *acquire(unsigned block); + virtual void release(unsigned block, int flags); + virtual void markDirty(unsigned block); + + private: + void *_data; + bool _dirty; + +}; + +} // namespace + +