1 // Item.cpp 2 // 3 // Copyright (c) 2003, Ingo Weinhold (bonefish@cs.tu-berlin.de) 4 // 5 // This program is free software; you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation; either version 2 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with this program; if not, write to the Free Software 17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 // 19 // You can alternatively use *this file* under the terms of the the MIT 20 // license included in this package. 21 22 #include "Item.h" 23 #include "Block.h" 24 25 /*! 26 \class ItemHeader 27 \brief Represents the on-disk structure for an item header. 28 29 An ItemHeader is located in a leaf nodes and provides information about 30 a respective item. Aside from the location and the size of the item 31 it also contains the leftmost key of the item (used for searching) 32 and the format version of that key. 33 */ 34 35 /*! 36 \class Item 37 \brief Provides access to the on-disk item structure. 38 39 Item is the base class for DirItem, IndirectItem and StatItem. 40 It does little more than to hold a pointer to the leaf node it resides 41 on and to its ItemHeader. The Item locks the node in the block cache 42 as longs as it exists. An Item can be savely casted into one of the 43 derived types. 44 */ 45 46 // constructor 47 Item::Item() 48 : fNode(NULL), 49 fHeader(NULL) 50 { 51 } 52 53 // constructor 54 Item::Item(const Item &item) 55 : fNode(NULL), 56 fHeader(NULL) 57 { 58 SetTo(item.GetNode(), item.GetHeader()); 59 } 60 61 // constructor 62 Item::Item(LeafNode *node, const ItemHeader *header) 63 : fNode(NULL), 64 fHeader(NULL) 65 { 66 SetTo(node, header); 67 } 68 69 // destructor 70 Item::~Item() 71 { 72 Unset(); 73 } 74 75 // SetTo 76 status_t 77 Item::SetTo(LeafNode *node, const ItemHeader *header) 78 { 79 Unset(); 80 status_t error = (node && header ? B_OK : B_BAD_VALUE); 81 if (error == B_OK) { 82 fNode = node; 83 fHeader = const_cast<ItemHeader*>(header); 84 fNode->Get(); 85 // check the item 86 error = Check(); 87 if (error != B_OK) 88 Unset(); 89 } 90 return error; 91 } 92 93 // SetTo 94 status_t 95 Item::SetTo(LeafNode *node, int32 index) 96 { 97 Unset(); 98 status_t error = (node ? B_OK : B_BAD_VALUE); 99 if (error == B_OK) 100 error = SetTo(node, node->ItemHeaderAt(index)); 101 return error; 102 } 103 104 // Unset 105 void 106 Item::Unset() 107 { 108 if (fNode) { 109 fNode->Put(); 110 fNode = NULL; 111 } 112 fHeader = NULL; 113 } 114 115 // GetNode 116 LeafNode * 117 Item::GetNode() const 118 { 119 return fNode; 120 } 121 122 // GetHeader 123 ItemHeader * 124 Item::GetHeader() const 125 { 126 return fHeader; 127 } 128 129 // GetIndex 130 int32 131 Item::GetIndex() const 132 { 133 return (fHeader - fNode->GetItemHeaders()); 134 } 135 136 // GetData 137 void * 138 Item::GetData() const 139 { 140 return (uint8*)fNode->GetData() + fHeader->GetLocation(); 141 } 142 143 // GetLen 144 uint16 145 Item::GetLen() const 146 { 147 return fHeader->GetLen(); 148 } 149 150 // GetType 151 uint16 152 Item::GetType() const 153 { 154 return fHeader->GetType(); 155 } 156 157 // GetDirID 158 uint32 159 Item::GetDirID() const 160 { 161 return fHeader->GetDirID(); 162 } 163 164 // GetObjectID 165 uint32 166 Item::GetObjectID() const 167 { 168 return fHeader->GetObjectID(); 169 } 170 171 // GetOffset 172 uint64 173 Item::GetOffset() const 174 { 175 return fHeader->GetOffset(); 176 } 177 178 // GetKey 179 const Key * 180 Item::GetKey() const 181 { 182 return fHeader->GetKey(); 183 } 184 185 // GetKey 186 VKey * 187 Item::GetKey(VKey *k) const 188 { 189 return fHeader->GetKey(k); 190 } 191 192 // GetEntryCount 193 uint16 194 Item::GetEntryCount() const 195 { 196 return fHeader->GetEntryCount(); 197 } 198 199 // Check 200 status_t 201 Item::Check() const 202 { 203 // check location of the item 204 uint32 blockSize = fNode->GetBlockSize(); 205 uint32 itemSpaceOffset = fNode->GetItemSpaceOffset(); 206 uint32 location = fHeader->GetLocation(); 207 if (location < itemSpaceOffset 208 || location + fHeader->GetLen() > blockSize) { 209 FATAL(("WARNING: bad item %" B_PRId32 210 " on node %" B_PRIu64 ": it can not be located " 211 "where it claims to be: (location: %" B_PRIu32 ", len: %u, " 212 "item space offset: %" B_PRIu32 ", " 213 "block size: %" B_PRIu32 ")!\n", GetIndex(), 214 fNode->GetNumber(), location, fHeader->GetLen(), 215 itemSpaceOffset, blockSize)); 216 return B_BAD_DATA; 217 } 218 return B_OK; 219 } 220 221 // = 222 Item & 223 Item::operator=(const Item &item) 224 { 225 SetTo(item.GetNode(), item.GetHeader()); 226 return *this; 227 } 228 229