mirror of
https://github.com/ksherlock/profuse.git
synced 2024-05-28 22:41:39 +00:00
git-svn-id: https://profuse.googlecode.com/svn/branches/v2@205 aa027e90-d47c-11dd-86d7-074df07e0730
This commit is contained in:
parent
1ac9b03e47
commit
07f1244834
|
@ -4,12 +4,19 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
class MappedFile;
|
||||||
|
class Device::BlockDevice;
|
||||||
|
|
||||||
namespace Device {
|
namespace Device {
|
||||||
|
|
||||||
class BlockDevice;
|
|
||||||
class MappedFile;
|
|
||||||
|
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kBlockDirty = 1,
|
||||||
|
kBlockCommitNow = 2,
|
||||||
|
kBlockReuse = 3
|
||||||
|
} BlockReleaseFlags;
|
||||||
|
|
||||||
class BlockCache {
|
class BlockCache {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -27,10 +34,11 @@ public:
|
||||||
virtual void read(unsigned block, void *bp);
|
virtual void read(unsigned block, void *bp);
|
||||||
|
|
||||||
virtual void *acquire(unsigned block) = 0;
|
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;
|
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:
|
protected:
|
||||||
BlockCache(BlockDevice *device);
|
BlockCache(BlockDevice *device);
|
||||||
|
@ -52,7 +60,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
virtual void *acquire(unsigned block);
|
virtual void *acquire(unsigned block);
|
||||||
virtual void release(unsigned block, bool dirty);
|
virtual void release(unsigned block, int flags);
|
||||||
virtual void markDirty(unsigned block);
|
virtual void markDirty(unsigned block);
|
||||||
|
|
||||||
|
|
||||||
|
@ -96,25 +104,6 @@ private:
|
||||||
decrementCount(Entry *);
|
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
|
} // namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
64
Cache/ConcreteBlockCache.h
Normal file
64
Cache/ConcreteBlockCache.h
Normal 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 *);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
65
Cache/MappedBlockCache.cpp
Normal file
65
Cache/MappedBlockCache.cpp
Normal 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
30
Cache/MappedBlockCache.h
Normal 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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user