1/*
2 * Copyright 2001-2008, Axel D��rfler, axeld@pinc-software.de.
3 * This file may be used under the terms of the MIT License.
4 */
5#ifndef CACHED_BLOCK_H
6#define CACHED_BLOCK_H
7
8//!	interface for the block cache
9
10#include <fs_cache.h>
11
12#include "Transaction.h"
13#include "Volume.h"
14
15
16class CachedBlock {
17public:
18							CachedBlock(Volume* volume);
19							CachedBlock(Volume* volume, off_t block);
20							~CachedBlock();
21
22			void			Keep();
23			void			Unset();
24
25			const uint8*	SetTo(off_t block);
26			uint8*			SetToWritable(Transaction& transaction,
27								off_t block, bool empty = false);
28			uint8*			SetToWritableWithoutTransaction(off_t block,
29								bool empty = false);
30
31			const uint8*	Block() const { return fBlock; }
32			off_t			BlockNumber() const { return fBlockNumber; }
33
34private:
35							CachedBlock(const CachedBlock &);
36							CachedBlock &operator=(const CachedBlock &);
37								// no implementation
38
39			uint8*			_SetToWritableEtc(int32 transaction, off_t block,
40								bool empty);
41
42protected:
43			Volume*			fVolume;
44			off_t			fBlockNumber;
45			uint8*			fBlock;
46};
47
48
49// inlines
50
51
52inline
53CachedBlock::CachedBlock(Volume* volume)
54	:
55	fVolume(volume),
56	fBlockNumber(0),
57	fBlock(NULL)
58{
59}
60
61
62inline
63CachedBlock::CachedBlock(Volume* volume, off_t block)
64	:
65	fVolume(volume),
66	fBlockNumber(0),
67	fBlock(NULL)
68{
69	SetTo(block);
70}
71
72
73inline
74CachedBlock::~CachedBlock()
75{
76	Unset();
77}
78
79
80inline void
81CachedBlock::Keep()
82{
83	fBlock = NULL;
84}
85
86
87inline void
88CachedBlock::Unset()
89{
90	if (fBlock != NULL) {
91		block_cache_put(fVolume->BlockCache(), fBlockNumber);
92		fBlock = NULL;
93	}
94}
95
96
97inline const uint8 *
98CachedBlock::SetTo(off_t block)
99{
100	Unset();
101	fBlockNumber = block;
102	return fBlock = (uint8 *)block_cache_get(fVolume->BlockCache(), block);
103}
104
105
106inline uint8*
107CachedBlock::SetToWritable(Transaction& transaction, off_t block, bool empty)
108{
109	return _SetToWritableEtc(transaction.ID(), block, empty);
110}
111
112
113inline uint8*
114CachedBlock::SetToWritableWithoutTransaction(off_t block, bool empty)
115{
116	return _SetToWritableEtc((int32)-1, block, empty);
117}
118
119inline uint8*
120CachedBlock::_SetToWritableEtc(int32 transaction, off_t block, bool empty)
121{
122	Unset();
123	fBlockNumber = block;
124
125	if (empty) {
126		fBlock = (uint8*)block_cache_get_empty(fVolume->BlockCache(),
127			block, transaction);
128	} else {
129		fBlock = (uint8*)block_cache_get_writable(fVolume->BlockCache(),
130			block, transaction);
131	}
132
133	return fBlock;
134}
135
136#endif	// CACHED_BLOCK_H
137