#ifndef CACHED_BLOCK_H
#define CACHED_BLOCK_H
#include "system_dependencies.h"
#include "Volume.h"
#include "Journal.h"
#include "Debug.h"
class CachedBlock {
public:
CachedBlock(Volume* volume);
CachedBlock(CachedBlock* cached);
~CachedBlock();
inline void Keep();
inline void Unset();
inline status_t SetTo(off_t block);
inline status_t SetTo(block_run run);
inline status_t SetToWritable(Transaction& transaction,
off_t block, bool empty = false);
inline status_t SetToWritable(Transaction& transaction,
block_run run, bool empty = false);
inline status_t MakeWritable(Transaction& transaction);
const uint8* Block() const { return fBlock; }
uint8* WritableBlock() const { return fBlock; }
off_t BlockNumber() const { return fBlockNumber; }
uint32 BlockSize() const
{ return fVolume->BlockSize(); }
uint32 BlockShift() const
{ return fVolume->BlockShift(); }
private:
CachedBlock(const CachedBlock& other);
CachedBlock& operator=(const CachedBlock& other);
protected:
Volume* fVolume;
off_t fBlockNumber;
uint8* fBlock;
};
inline
CachedBlock::CachedBlock(Volume* volume)
:
fVolume(volume),
fBlockNumber(0),
fBlock(NULL)
{
}
inline
CachedBlock::CachedBlock(CachedBlock* cached)
:
fVolume(cached->fVolume),
fBlockNumber(cached->BlockNumber()),
fBlock(cached->fBlock)
{
cached->Keep();
}
inline
CachedBlock::~CachedBlock()
{
Unset();
}
inline void
CachedBlock::Keep()
{
fBlock = NULL;
}
inline void
CachedBlock::Unset()
{
if (fBlock != NULL) {
block_cache_put(fVolume->BlockCache(), fBlockNumber);
fBlock = NULL;
}
}
inline status_t
CachedBlock::SetTo(off_t block)
{
Unset();
fBlockNumber = block;
return block_cache_get_etc(fVolume->BlockCache(), block, (const void**)&fBlock);
}
inline status_t
CachedBlock::SetTo(block_run run)
{
return SetTo(fVolume->ToBlock(run));
}
inline status_t
CachedBlock::SetToWritable(Transaction& transaction, off_t block, bool empty)
{
Unset();
fBlockNumber = block;
if (empty) {
fBlock = (uint8*)block_cache_get_empty(fVolume->BlockCache(),
block, transaction.ID());
return fBlock != NULL ? B_OK : B_NO_MEMORY;
}
return block_cache_get_writable_etc(fVolume->BlockCache(),
block, transaction.ID(), (void**)&fBlock);
}
inline status_t
CachedBlock::SetToWritable(Transaction& transaction, block_run run, bool empty)
{
return SetToWritable(transaction, fVolume->ToBlock(run), empty);
}
inline status_t
CachedBlock::MakeWritable(Transaction& transaction)
{
if (fBlock == NULL)
return B_NO_INIT;
return block_cache_make_writable(fVolume->BlockCache(), fBlockNumber,
transaction.ID());
}
#endif