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
Item()47 Item::Item()
48 : fNode(NULL),
49 fHeader(NULL)
50 {
51 }
52
53 // constructor
Item(const Item & item)54 Item::Item(const Item &item)
55 : fNode(NULL),
56 fHeader(NULL)
57 {
58 SetTo(item.GetNode(), item.GetHeader());
59 }
60
61 // constructor
Item(LeafNode * node,const ItemHeader * header)62 Item::Item(LeafNode *node, const ItemHeader *header)
63 : fNode(NULL),
64 fHeader(NULL)
65 {
66 SetTo(node, header);
67 }
68
69 // destructor
~Item()70 Item::~Item()
71 {
72 Unset();
73 }
74
75 // SetTo
76 status_t
SetTo(LeafNode * node,const ItemHeader * header)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
SetTo(LeafNode * node,int32 index)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
Unset()106 Item::Unset()
107 {
108 if (fNode) {
109 fNode->Put();
110 fNode = NULL;
111 }
112 fHeader = NULL;
113 }
114
115 // GetNode
116 LeafNode *
GetNode() const117 Item::GetNode() const
118 {
119 return fNode;
120 }
121
122 // GetHeader
123 ItemHeader *
GetHeader() const124 Item::GetHeader() const
125 {
126 return fHeader;
127 }
128
129 // GetIndex
130 int32
GetIndex() const131 Item::GetIndex() const
132 {
133 return (fHeader - fNode->GetItemHeaders());
134 }
135
136 // GetData
137 void *
GetData() const138 Item::GetData() const
139 {
140 return (uint8*)fNode->GetData() + fHeader->GetLocation();
141 }
142
143 // GetLen
144 uint16
GetLen() const145 Item::GetLen() const
146 {
147 return fHeader->GetLen();
148 }
149
150 // GetType
151 uint16
GetType() const152 Item::GetType() const
153 {
154 return fHeader->GetType();
155 }
156
157 // GetDirID
158 uint32
GetDirID() const159 Item::GetDirID() const
160 {
161 return fHeader->GetDirID();
162 }
163
164 // GetObjectID
165 uint32
GetObjectID() const166 Item::GetObjectID() const
167 {
168 return fHeader->GetObjectID();
169 }
170
171 // GetOffset
172 uint64
GetOffset() const173 Item::GetOffset() const
174 {
175 return fHeader->GetOffset();
176 }
177
178 // GetKey
179 const Key *
GetKey() const180 Item::GetKey() const
181 {
182 return fHeader->GetKey();
183 }
184
185 // GetKey
186 VKey *
GetKey(VKey * k) const187 Item::GetKey(VKey *k) const
188 {
189 return fHeader->GetKey(k);
190 }
191
192 // GetEntryCount
193 uint16
GetEntryCount() const194 Item::GetEntryCount() const
195 {
196 return fHeader->GetEntryCount();
197 }
198
199 // Check
200 status_t
Check() const201 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 &
operator =(const Item & item)223 Item::operator=(const Item &item)
224 {
225 SetTo(item.GetNode(), item.GetHeader());
226 return *this;
227 }
228
229