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 11 #include "system_dependencies.h" 12 13 #include "Volume.h" 14 #include "Journal.h" 15 #include "Debug.h" 16 17 18 // The CachedBlock class is completely implemented as inlines. 19 // It should be used when cache single blocks to make sure they 20 // will be properly released after use (and it's also very 21 // convenient to use them). 22 23 class CachedBlock { 24 public: 25 CachedBlock(Volume* volume); 26 CachedBlock(Volume* volume, off_t block); 27 CachedBlock(Volume* volume, block_run run); 28 CachedBlock(CachedBlock* cached); 29 ~CachedBlock(); 30 31 inline void Keep(); 32 inline void Unset(); 33 34 inline const uint8* SetTo(off_t block, off_t base, size_t length); 35 inline const uint8* SetTo(off_t block); 36 inline const uint8* SetTo(block_run run); 37 inline uint8* SetToWritable(Transaction& transaction, off_t block, 38 off_t base, size_t length, bool empty = false); 39 inline uint8* SetToWritable(Transaction& transaction, off_t block, 40 bool empty = false); 41 inline uint8* SetToWritable(Transaction& transaction, block_run run, 42 bool empty = false); 43 inline status_t MakeWritable(Transaction& transaction); 44 45 const uint8* Block() const { return fBlock; } 46 off_t BlockNumber() const { return fBlockNumber; } 47 uint32 BlockSize() const { return fVolume->BlockSize(); } 48 uint32 BlockShift() const { return fVolume->BlockShift(); } 49 50 private: 51 CachedBlock(const CachedBlock& other); 52 CachedBlock& operator=(const CachedBlock& other); 53 // no implementation 54 55 protected: 56 Volume *fVolume; 57 off_t fBlockNumber; 58 uint8 *fBlock; 59 }; 60 61 62 // inlines 63 64 65 inline 66 CachedBlock::CachedBlock(Volume* volume) 67 : 68 fVolume(volume), 69 fBlockNumber(0), 70 fBlock(NULL) 71 { 72 } 73 74 75 inline 76 CachedBlock::CachedBlock(Volume* volume, off_t block) 77 : 78 fVolume(volume), 79 fBlockNumber(0), 80 fBlock(NULL) 81 { 82 SetTo(block); 83 } 84 85 86 inline 87 CachedBlock::CachedBlock(Volume* volume, block_run run) 88 : 89 fVolume(volume), 90 fBlockNumber(0), 91 fBlock(NULL) 92 { 93 SetTo(volume->ToBlock(run)); 94 } 95 96 97 inline 98 CachedBlock::CachedBlock(CachedBlock* cached) 99 : 100 fVolume(cached->fVolume), 101 fBlockNumber(cached->BlockNumber()), 102 fBlock(cached->fBlock) 103 { 104 cached->Keep(); 105 } 106 107 108 inline 109 CachedBlock::~CachedBlock() 110 { 111 Unset(); 112 } 113 114 115 inline void 116 CachedBlock::Keep() 117 { 118 fBlock = NULL; 119 } 120 121 122 inline void 123 CachedBlock::Unset() 124 { 125 if (fBlock != NULL) { 126 block_cache_put(fVolume->BlockCache(), fBlockNumber); 127 fBlock = NULL; 128 } 129 } 130 131 132 inline const uint8* 133 CachedBlock::SetTo(off_t block, off_t base, size_t length) 134 { 135 Unset(); 136 fBlockNumber = block; 137 return fBlock = (uint8*)block_cache_get_etc(fVolume->BlockCache(), 138 block, base, length); 139 } 140 141 142 inline const uint8* 143 CachedBlock::SetTo(off_t block) 144 { 145 return SetTo(block, block, 1); 146 } 147 148 149 inline const uint8* 150 CachedBlock::SetTo(block_run run) 151 { 152 return SetTo(fVolume->ToBlock(run)); 153 } 154 155 156 inline uint8* 157 CachedBlock::SetToWritable(Transaction& transaction, off_t block, off_t base, 158 size_t length, bool empty) 159 { 160 Unset(); 161 fBlockNumber = block; 162 163 if (empty) { 164 fBlock = (uint8*)block_cache_get_empty(fVolume->BlockCache(), 165 block, transaction.ID()); 166 } else { 167 fBlock = (uint8*)block_cache_get_writable_etc(fVolume->BlockCache(), 168 block, base, length, transaction.ID()); 169 } 170 171 return fBlock; 172 } 173 174 175 inline uint8* 176 CachedBlock::SetToWritable(Transaction& transaction, off_t block, bool empty) 177 { 178 return SetToWritable(transaction, block, block, 1, empty); 179 } 180 181 182 inline uint8* 183 CachedBlock::SetToWritable(Transaction& transaction, block_run run, bool empty) 184 { 185 return SetToWritable(transaction, fVolume->ToBlock(run), empty); 186 } 187 188 189 inline status_t 190 CachedBlock::MakeWritable(Transaction& transaction) 191 { 192 if (fBlock == NULL) 193 return B_NO_INIT; 194 195 return block_cache_make_writable(fVolume->BlockCache(), fBlockNumber, 196 transaction.ID()); 197 } 198 199 #endif // CACHED_BLOCK_H 200