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