#include "Item.h"
#include "Block.h"
\class ItemHeader
\brief Represents the on-disk structure for an item header.
An ItemHeader is located in a leaf nodes and provides information about
a respective item. Aside from the location and the size of the item
it also contains the leftmost key of the item (used for searching)
and the format version of that key.
*/
\class Item
\brief Provides access to the on-disk item structure.
Item is the base class for DirItem, IndirectItem and StatItem.
It does little more than to hold a pointer to the leaf node it resides
on and to its ItemHeader. The Item locks the node in the block cache
as longs as it exists. An Item can be savely casted into one of the
derived types.
*/
Item::Item()
: fNode(NULL),
fHeader(NULL)
{
}
Item::Item(const Item &item)
: fNode(NULL),
fHeader(NULL)
{
SetTo(item.GetNode(), item.GetHeader());
}
Item::Item(LeafNode *node, const ItemHeader *header)
: fNode(NULL),
fHeader(NULL)
{
SetTo(node, header);
}
Item::~Item()
{
Unset();
}
status_t
Item::SetTo(LeafNode *node, const ItemHeader *header)
{
Unset();
status_t error = (node && header ? B_OK : B_BAD_VALUE);
if (error == B_OK) {
fNode = node;
fHeader = const_cast<ItemHeader*>(header);
fNode->Get();
error = Check();
if (error != B_OK)
Unset();
}
return error;
}
status_t
Item::SetTo(LeafNode *node, int32 index)
{
Unset();
status_t error = (node ? B_OK : B_BAD_VALUE);
if (error == B_OK)
error = SetTo(node, node->ItemHeaderAt(index));
return error;
}
void
Item::Unset()
{
if (fNode) {
fNode->Put();
fNode = NULL;
}
fHeader = NULL;
}
LeafNode *
Item::GetNode() const
{
return fNode;
}
ItemHeader *
Item::GetHeader() const
{
return fHeader;
}
int32
Item::GetIndex() const
{
return (fHeader - fNode->GetItemHeaders());
}
void *
Item::GetData() const
{
return (uint8*)fNode->GetData() + fHeader->GetLocation();
}
uint16
Item::GetLen() const
{
return fHeader->GetLen();
}
uint16
Item::GetType() const
{
return fHeader->GetType();
}
uint32
Item::GetDirID() const
{
return fHeader->GetDirID();
}
uint32
Item::GetObjectID() const
{
return fHeader->GetObjectID();
}
uint64
Item::GetOffset() const
{
return fHeader->GetOffset();
}
const Key *
Item::GetKey() const
{
return fHeader->GetKey();
}
VKey *
Item::GetKey(VKey *k) const
{
return fHeader->GetKey(k);
}
uint16
Item::GetEntryCount() const
{
return fHeader->GetEntryCount();
}
status_t
Item::Check() const
{
uint32 blockSize = fNode->GetBlockSize();
uint32 itemSpaceOffset = fNode->GetItemSpaceOffset();
uint32 location = fHeader->GetLocation();
if (location < itemSpaceOffset
|| location + fHeader->GetLen() > blockSize) {
FATAL(("WARNING: bad item %" B_PRId32
" on node %" B_PRIu64 ": it can not be located "
"where it claims to be: (location: %" B_PRIu32 ", len: %u, "
"item space offset: %" B_PRIu32 ", "
"block size: %" B_PRIu32 ")!\n", GetIndex(),
fNode->GetNumber(), location, fHeader->GetLen(),
itemSpaceOffset, blockSize));
return B_BAD_DATA;
}
return B_OK;
}
Item &
Item::operator=(const Item &item)
{
SetTo(item.GetNode(), item.GetHeader());
return *this;
}