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; }
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; }