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