示例#1
0
bool
HDBNode::remove(HDBHandle& hdl)
{
	// If node hasn't been written yet, don't do anything.
	if (m_pdata->m_offset <= 0)
	{
		return false;
	}
	File file = hdl.getFile();
	HDB* pdb = hdl.getHDB();
	HDBBlock fblk;
	// Remove all children
	Int32 coffset = m_pdata->m_blk.lastChild;
	Int32 toffset;
	while (coffset > 0)
	{
		HDB::readBlock(fblk, file, coffset);
		toffset = coffset;			// Save offset for deletion class
		coffset = fblk.prevSib;		// Save offset for next read
		// Remove node and all of its children. This call will modify fblk.
		removeBlock(hdl, fblk, toffset);
	}
	// Set pointer on next sibling if it exists
	if (m_pdata->m_blk.nextSib > 0)
	{
		HDB::readBlock(fblk, file, m_pdata->m_blk.nextSib);
		fblk.prevSib = m_pdata->m_blk.prevSib;
		HDB::writeBlock(fblk, file, m_pdata->m_blk.nextSib);
	}
	// Set pointer on prev sibling if it exists
	if (m_pdata->m_blk.prevSib > 0)
	{
		HDB::readBlock(fblk, file, m_pdata->m_blk.prevSib);
		fblk.nextSib = m_pdata->m_blk.nextSib;
		HDB::writeBlock(fblk, file, m_pdata->m_blk.prevSib);
	}
	// If it has a parent, insure parent doesn't contain it's offset
	if (m_pdata->m_blk.parent > 0)
	{
		// Read parent block
		HDB::readBlock(fblk, file, m_pdata->m_blk.parent);
		bool changed = false;
		// If this was the first child in the list, then update the
		// first child pointer in the parent block
		if (fblk.firstChild == m_pdata->m_offset)
		{
			changed = true;
			fblk.firstChild = m_pdata->m_blk.nextSib;
		}
		// If this was the last child in the list, then update the
		// last child pointer in the parent block
		if (fblk.lastChild == m_pdata->m_offset)
		{
			changed = true;
			fblk.lastChild = m_pdata->m_blk.prevSib;
		}
		// If any offsets changed in the parent block, then update the parent
		if (changed)
		{
			HDB::writeBlock(fblk, file, m_pdata->m_blk.parent);
		}
	}
	else
	{
		// Must be a root node
		if (pdb->getFirstRootOffSet() == m_pdata->m_offset)
		{
			pdb->setFirstRootOffSet(file, m_pdata->m_blk.nextSib);
		}
		if (pdb->getLastRootOffset() == m_pdata->m_offset)
		{
			pdb->setLastRootOffset(file, m_pdata->m_blk.prevSib);
		}
	}
	// Add block to free list
	pdb->addBlockToFreeList(file, m_pdata->m_blk, m_pdata->m_offset);
	// Remove the index entry for this node
	hdl.removeIndexEntry(m_pdata->m_key.c_str());
	m_pdata->m_offset = -1;
	m_pdata->m_blk.isFree = true;
	m_pdata->m_blk.parent = -1;
	m_pdata->m_blk.firstChild = -1;
	m_pdata->m_blk.lastChild = -1;
	m_pdata->m_blk.prevSib = -1;
	m_pdata->m_blk.nextSib = -1;
	m_pdata->m_blk.size = 0;
	hdl.registerWrite();
	return true;
}
示例#2
0
void
HDBNode::updateOffsets(HDBHandle& hdl, Int32 offset)
{
	if (offset <= 0L || !m_pdata || !hdl)
	{
		return;
	}
	HDB* pdb = hdl.getHDB();
	File file = hdl.getFile();
	HDBBlock fblk;
	if (m_pdata->m_blk.prevSib > 0)
	{
		HDB::readBlock(fblk, file, m_pdata->m_blk.prevSib);
		fblk.nextSib = offset;
		HDB::writeBlock(fblk, file, m_pdata->m_blk.prevSib);
	}
	if (m_pdata->m_blk.nextSib > 0)
	{
		HDB::readBlock(fblk, file, m_pdata->m_blk.nextSib);
		fblk.prevSib = offset;
		HDB::writeBlock(fblk, file, m_pdata->m_blk.nextSib);
	}
	if (m_pdata->m_blk.parent > 0)
	{
		HDB::readBlock(fblk, file, m_pdata->m_blk.parent);
		bool doUpdate = false;
		if (fblk.firstChild == m_pdata->m_offset)
		{
			fblk.firstChild = offset;
			doUpdate = true;
		}
		if (fblk.lastChild == m_pdata->m_offset)
		{
			fblk.lastChild = offset;
			doUpdate = true;
		}
		if (doUpdate)
		{
			HDB::writeBlock(fblk, file, m_pdata->m_blk.parent);
		}
	}
	else	// No parent. Must be a root node
	{
		if (pdb->getFirstRootOffSet() == m_pdata->m_offset)
		{
			pdb->setFirstRootOffSet(file, offset);
		}
		if (pdb->getLastRootOffset() == m_pdata->m_offset)
		{
			pdb->setLastRootOffset(file, offset);
		}
	}
	// Now update the parent offset on all children
	Int32 coffset = m_pdata->m_blk.firstChild;
	while (coffset > 0)
	{
		HDB::readBlock(fblk, file, coffset);
		fblk.parent = offset;
		HDB::writeBlock(fblk, file, coffset);
		coffset = fblk.nextSib;
	}
	// Update the index entry associated with this node
	hdl.updateIndexEntry(m_pdata->m_key.c_str(), offset);
	m_pdata->m_offset = offset;
}