git-svn-id: https://profuse.googlecode.com/svn/branches/v2@205 aa027e90-d47c-11dd-86d7-074df07e0730

This commit is contained in:
ksherlock 2010-03-19 18:12:22 +00:00
parent 1ac9b03e47
commit 07f1244834
4 changed files with 173 additions and 25 deletions

View File

@ -4,12 +4,19 @@
#include <stdint.h>
#include <vector>
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
#endif

View File

@ -0,0 +1,64 @@
#ifndef __CONCRETE_BLOCK_CACHE_H__
#define __CONCRETE_BLOCK_CACHE_H__
#include <vector>
#include <BlockCache.h>
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<Entry *>_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 *);
};
}

View File

@ -0,0 +1,65 @@
#include <algorithm>
#include <cerrno>
#include <sys/types.h>
#include <sys/mman.h>
#include <unistd.h>
#include <Cache/MappedBlockCache.h>
#include <ProFUSE/Exception.h>
#include <ProFUSE/auto.h>
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;
}

30
Cache/MappedBlockCache.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef __MAPPED_BLOCK_CACHE_H__
#define __MAPPED_BLOCK_CACHE_H__
#include <BlockCache.h>
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