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