OW_HDBNode.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2001-2004 Vintela, Inc. All rights reserved.
00003 *
00004 * Redistribution and use in source and binary forms, with or without
00005 * modification, are permitted provided that the following conditions are met:
00006 *
00007 *  - Redistributions of source code must retain the above copyright notice,
00008 *    this list of conditions and the following disclaimer.
00009 *
00010 *  - Redistributions in binary form must reproduce the above copyright notice,
00011 *    this list of conditions and the following disclaimer in the documentation
00012 *    and/or other materials provided with the distribution.
00013 *
00014 *  - Neither the name of Vintela, Inc. nor the names of its
00015 *    contributors may be used to endorse or promote products derived from this
00016 *    software without specific prior written permission.
00017 *
00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc. OR THE CONTRIBUTORS
00022 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00028 * POSSIBILITY OF SUCH DAMAGE.
00029 *******************************************************************************/
00030 
00036 #include "OW_config.h"
00037 #include "OW_HDBNode.hpp"
00038 #include "OW_HDB.hpp"
00039 #include "OW_AutoPtr.hpp"
00040 #include <cstring>
00041 #include <cerrno>
00042 
00043 namespace OW_NAMESPACE
00044 {
00045 
00047 HDBNode::HDBNodeData::HDBNodeData() :
00048    m_blk(), m_key(), m_bfrLen(0), m_bfr(NULL), m_offset(-1L), m_version(0)
00049 {
00050    ::memset(&m_blk, 0, sizeof(m_blk));
00051 }
00053 HDBNode::HDBNodeData::HDBNodeData(const HDBNodeData& x) :
00054    IntrusiveCountableBase(x), m_blk(x.m_blk), m_key(x.m_key), m_bfrLen(x.m_bfrLen), m_bfr(NULL),
00055    m_offset(x.m_offset), m_version(0)
00056 {
00057    if (m_bfrLen > 0)
00058    {
00059       m_bfr = new unsigned char[m_bfrLen];
00060       ::memcpy(m_bfr, x.m_bfr, m_bfrLen);
00061    }
00062 }
00064 HDBNode::HDBNodeData::~HDBNodeData()
00065 {
00066    delete [] m_bfr;
00067 }
00069 HDBNode::HDBNodeData&
00070 HDBNode::HDBNodeData::operator= (const HDBNode::HDBNodeData& x)
00071 {
00072    m_blk = x.m_blk;
00073    m_key = x.m_key;
00074    m_version = x.m_version;
00075    delete [] m_bfr;
00076    m_bfr = NULL;
00077    m_bfrLen = x.m_bfrLen;
00078    if (m_bfrLen > 0)
00079    {
00080       m_bfr = new unsigned char[m_bfrLen];
00081       ::memcpy(m_bfr, x.m_bfr, m_bfrLen);
00082    }
00083    m_offset = x.m_offset;
00084    return *this;
00085 }
00087 HDBNode::HDBNode(const char* key, HDBHandle& hdl) :
00088    m_pdata(NULL)
00089 {
00090    if (!key || !hdl)
00091    {
00092       return;
00093    }
00094    IndexEntry ientry = hdl.findIndexEntry(key);
00095    if (!ientry)
00096    {
00097       return;
00098    }
00099    read(ientry.offset, hdl);
00100 }
00102 HDBNode::HDBNode(Int32 offset, HDBHandle& hdl) :
00103    m_pdata(NULL)
00104 {
00105    if (!hdl || offset <= 0)
00106    {
00107       return;
00108    }
00109    read(offset, hdl);
00110 }
00112 HDBNode::HDBNode(const String& key, int dataLen,
00113    const unsigned char* data) :
00114    m_pdata(NULL)
00115 {
00116    if (key.empty())
00117    {
00118       return;
00119    }
00120    m_pdata = new HDBNodeData;
00121    m_pdata->m_offset = -1;
00122    m_pdata->m_version = 0;
00123    m_pdata->m_key = key;
00124    if (dataLen && data != NULL)
00125    {
00126       m_pdata->m_bfr = new unsigned char[dataLen];
00127       ::memcpy(m_pdata->m_bfr, data, dataLen);
00128    }
00129    else
00130    {
00131       dataLen = 0;
00132    }
00133    m_pdata->m_bfrLen = dataLen;
00134    m_pdata->m_blk.isFree = false;
00135    m_pdata->m_blk.keyLength = m_pdata->m_key.length()+1;
00136    m_pdata->m_blk.size = 0;
00137    m_pdata->m_blk.nextSib = -1;
00138    m_pdata->m_blk.prevSib = -1;
00139    m_pdata->m_blk.parent = -1;
00140    m_pdata->m_blk.firstChild = -1;
00141    m_pdata->m_blk.lastChild = -1;
00142    m_pdata->m_blk.dataLength = m_pdata->m_key.length() + 1 + dataLen;
00143 }
00145 void
00146 HDBNode::read(Int32 offset, HDBHandle& hdl)
00147 {
00148    if (offset <= 0 || !hdl)
00149    {
00150       OW_THROW(HDBException, "Invalid offset to read node from, db is most likely corrupt.");
00151    }
00152    File file = hdl.getFile();
00153    HDBBlock fblk;
00154    // Dereference existing data
00155    setNull();
00156    
00157    HDB::readBlock(fblk, file, offset);
00158    // If previously deleted, don't do anything
00159    if (fblk.isFree)
00160    {
00161       return;
00162    }
00163    char* kbfr = new char[fblk.keyLength];
00164    if (file.read(kbfr, fblk.keyLength) != size_t(fblk.keyLength))
00165    {
00166       delete [] kbfr;
00167       OW_THROW_ERRNO_MSG(HDBException, "Failed to read key for node");
00168    }
00169    // Let String take ownership of the allocated memory. It will
00170    // delete it later
00171    String key(String::E_TAKE_OWNERSHIP, kbfr, fblk.keyLength - 1);
00172    unsigned char* bfr = NULL;
00173    int dataLen = fblk.dataLength - fblk.keyLength;
00174    if (dataLen > 0)
00175    {
00176       bfr = new unsigned char[dataLen];
00177       if (file.read(bfr, dataLen) != size_t(dataLen))
00178       {
00179          delete [] bfr;
00180          OW_THROW_ERRNO_MSG(HDBException, "Failed to data for node");
00181       }
00182    }
00183    m_pdata = new HDBNodeData;
00184    m_pdata->m_offset = offset;
00185    m_pdata->m_bfr = bfr;
00186    m_pdata->m_bfrLen = dataLen;
00187    m_pdata->m_blk = fblk;
00188    m_pdata->m_key = key;
00189    m_pdata->m_version = hdl.getHDB()->getVersion();
00190 }
00192 bool
00193 HDBNode::reload(HDBHandle& hdl)
00194 {
00195    // If this is a null node, don't attempt to re-load
00196    if (!m_pdata)
00197    {
00198       return false;
00199    }
00200    // If this node has never been written, don't attempt to re-load
00201    if (m_pdata->m_offset <= 0)
00202    {
00203       return true;
00204    }
00205    // If no writes were done to the database before the last
00206    // read, don't re-load
00207    if (hdl.getHDB()->getVersion() == m_pdata->m_version)
00208    {
00209       return true;
00210    }
00211    File file = hdl.getFile();
00212    HDBBlock fblk;
00213    Int32 offset = m_pdata->m_offset;
00214    try
00215    {
00216       HDB::readBlock(fblk, file, offset);
00217    }
00218    catch (const HDBException&)
00219    {
00220       setNull();
00221       return false;
00222    }
00223    // If previously deleted, don't do anything
00224    if (fblk.isFree)
00225    {
00226       setNull();
00227       return false;
00228    }
00229    AutoPtrVec<char> kbfr(new char[fblk.keyLength]);
00230    if (file.read(kbfr.get(), fblk.keyLength) != size_t(fblk.keyLength))
00231    {
00232       return false;
00233    }
00234    if (!m_pdata->m_key.equals(kbfr.get()))
00235    {
00236       // If the key has changed, assume this node was deleted and the
00237       // space is now occupied by a different node.
00238       setNull();
00239       return false;
00240    }
00241    int dataLen = fblk.dataLength - fblk.keyLength;
00242    if (fblk.dataLength != m_pdata->m_blk.dataLength)
00243    {
00244       // Length of data for node has changed, so delete the old
00245       // data buffer
00246       delete [] m_pdata->m_bfr;
00247       m_pdata->m_bfr = NULL;
00248    }
00249    
00250    // If there is data for the node, then allocate the buffer for it
00251    // and read the data
00252    if (dataLen > 0)
00253    {
00254       if (m_pdata->m_bfr == NULL)
00255       {
00256          m_pdata->m_bfr = new unsigned char[dataLen];
00257       }
00258       if (file.read(m_pdata->m_bfr, dataLen) != size_t(dataLen))
00259       {
00260          setNull();     // this will delete m_pdata->m_bfr;
00261          return false;
00262       }
00263    }
00264    m_pdata->m_bfrLen = dataLen;
00265    m_pdata->m_blk = fblk;
00266    m_pdata->m_version = hdl.getHDB()->getVersion();
00267    return true;
00268 }
00270 bool
00271 HDBNode::turnFlagsOn(HDBHandle& hdl, UInt32 flags)
00272 {
00273    if (!m_pdata)
00274    {
00275       return false;
00276    }
00277    bool cc = false;
00278    flags |= m_pdata->m_blk.flags;
00279    if (flags != m_pdata->m_blk.flags)
00280    {
00281       m_pdata->m_blk.flags = flags;
00282       if (m_pdata->m_offset > 0)
00283       {
00284          write(hdl);
00285       }
00286       cc = true;
00287    }
00288    return cc;
00289 }
00291 bool
00292 HDBNode::turnFlagsOff(HDBHandle& hdl, UInt32 flags)
00293 {
00294    if (!m_pdata)
00295    {
00296       return false;
00297    }
00298    bool cc = false;
00299    flags = m_pdata->m_blk.flags & (~flags);
00300    if (flags != m_pdata->m_blk.flags)
00301    {
00302       m_pdata->m_blk.flags = flags;
00303       if (m_pdata->m_offset > 0)
00304       {
00305          write(hdl);
00306       }
00307       cc = true;
00308    }
00309    return cc;
00310 }
00312 bool
00313 HDBNode::updateData(HDBHandle& hdl, int dataLen, const unsigned char* data)
00314 {
00315    bool cc = false;
00316    if (m_pdata)
00317    {
00318       // If this node was read from file, make sure we are dealing with
00319       // an up to date version.
00320       if (m_pdata->m_offset > 0)
00321       {
00322          if (!reload(hdl))
00323          {
00324             // Node is no longer on file
00325             return false;
00326          }
00327       }
00328       cc = true;
00329       // If the data len has changed - we'll be using a different buffer
00330       if (dataLen != m_pdata->m_bfrLen)
00331       {
00332          delete [] m_pdata->m_bfr;
00333          m_pdata->m_bfr = NULL;
00334          m_pdata->m_bfrLen = 0;
00335       }
00336       if (dataLen > 0 && data != NULL)
00337       {
00338          if (m_pdata->m_bfr == NULL)
00339          {
00340             m_pdata->m_bfr = new unsigned char[dataLen];
00341          }
00342          m_pdata->m_bfrLen = dataLen;
00343          ::memcpy(m_pdata->m_bfr, data, dataLen);
00344       }
00345       // If this node is already on file, then write changes to file
00346       if (m_pdata->m_offset > 0)
00347       {
00348          write(hdl);
00349       }
00350    }
00351    return cc;
00352 }
00354 Int32
00355 HDBNode::write(HDBHandle& hdl, EWriteHeaderFlag onlyHeader)
00356 {
00357    if (!m_pdata)
00358    {
00359       OW_THROW(HDBException, "Internal error: Cannot write null node");
00360    }
00361    bool newRecord = false;
00362    m_pdata->m_blk.keyLength = m_pdata->m_key.length() + 1;
00363    m_pdata->m_blk.dataLength = m_pdata->m_bfrLen + m_pdata->m_key.length() + 1;
00364    File file = hdl.getFile();
00365    HDB* phdb = hdl.getHDB();
00366    int totalSize = m_pdata->m_blk.dataLength + sizeof(m_pdata->m_blk);
00367    m_pdata->m_blk.isFree = false;
00368    if (m_pdata->m_offset <= 0)   // Is this a new node?
00369    {
00370       newRecord = true;
00371       m_pdata->m_blk.size = totalSize;
00372       m_pdata->m_offset = phdb->findBlock(file, totalSize);
00373       if (m_pdata->m_blk.parent <= 0)
00374       {
00375          phdb->addRootNode(file, m_pdata->m_blk, m_pdata->m_offset);
00376       }
00377       else
00378       {
00379          HDB::writeBlock(m_pdata->m_blk, file, m_pdata->m_offset);
00380       }
00381       // Add this entry to the index
00382       if (!hdl.addIndexEntry(m_pdata->m_key.c_str(), m_pdata->m_offset))
00383       {
00384          OW_THROW(HDBException, "Failed to write index entry");
00385       }
00386    }
00387    else
00388    {
00389       // If the size required to hold this node has increased,
00390       // then delete the old block and add a new one.
00391       if (totalSize > int(m_pdata->m_blk.size))
00392       {
00393          HDBBlock node = m_pdata->m_blk;
00394          phdb->addBlockToFreeList(file, node, m_pdata->m_offset); // delete old
00395          m_pdata->m_blk.size = totalSize;
00396          updateOffsets(hdl, phdb->findBlock(file, totalSize));
00397       }
00398       HDB::writeBlock(m_pdata->m_blk, file, m_pdata->m_offset);
00399    }
00400    if (onlyHeader == false || newRecord == true)
00401    {
00402       // Now write key and data for node
00403       if (file.write(m_pdata->m_key.c_str(), m_pdata->m_key.length()+1)
00404          != m_pdata->m_key.length()+1)
00405       {
00406          OW_THROW_ERRNO_MSG(HDBException, "Failed to write node key");
00407       }
00408       if (file.write(m_pdata->m_bfr, m_pdata->m_bfrLen)
00409          != size_t(m_pdata->m_bfrLen))
00410       {
00411          OW_THROW_ERRNO_MSG(HDBException, "Failed to write node data");
00412       }
00413    }
00414    m_pdata->m_version = hdl.registerWrite();
00415    return m_pdata->m_offset;
00416 }
00418 void
00419 HDBNode::updateOffsets(HDBHandle& hdl, Int32 offset)
00420 {
00421    if (offset <= 0L || !m_pdata || !hdl)
00422    {
00423       return;
00424    }
00425    HDB* pdb = hdl.getHDB();
00426    File file = hdl.getFile();
00427    HDBBlock fblk;
00428    if (m_pdata->m_blk.prevSib > 0)
00429    {
00430       HDB::readBlock(fblk, file, m_pdata->m_blk.prevSib);
00431       fblk.nextSib = offset;
00432       HDB::writeBlock(fblk, file, m_pdata->m_blk.prevSib);
00433    }
00434    if (m_pdata->m_blk.nextSib > 0)
00435    {
00436       HDB::readBlock(fblk, file, m_pdata->m_blk.nextSib);
00437       fblk.prevSib = offset;
00438       HDB::writeBlock(fblk, file, m_pdata->m_blk.nextSib);
00439    }
00440    if (m_pdata->m_blk.parent > 0)
00441    {
00442       HDB::readBlock(fblk, file, m_pdata->m_blk.parent);
00443       bool doUpdate = false;
00444       if (fblk.firstChild == m_pdata->m_offset)
00445       {
00446          fblk.firstChild = offset;
00447          doUpdate = true;
00448       }
00449       if (fblk.lastChild == m_pdata->m_offset)
00450       {
00451          fblk.lastChild = offset;
00452          doUpdate = true;
00453       }
00454       if (doUpdate)
00455       {
00456          HDB::writeBlock(fblk, file, m_pdata->m_blk.parent);
00457       }
00458    }
00459    else  // No parent. Must be a root node
00460    {
00461       if (pdb->getFirstRootOffSet() == m_pdata->m_offset)
00462       {
00463          pdb->setFirstRootOffSet(file, offset);
00464       }
00465       if (pdb->getLastRootOffset() == m_pdata->m_offset)
00466       {
00467          pdb->setLastRootOffset(file, offset);
00468       }
00469    }
00470    // Now update the parent offset on all children
00471    Int32 coffset = m_pdata->m_blk.firstChild;
00472    while (coffset > 0)
00473    {
00474       HDB::readBlock(fblk, file, coffset);
00475       fblk.parent = offset;
00476       HDB::writeBlock(fblk, file, coffset);
00477       coffset = fblk.nextSib;
00478    }
00479    // Update the index entry associated with this node
00480    hdl.updateIndexEntry(m_pdata->m_key.c_str(), offset);
00481    m_pdata->m_offset = offset;
00482 }
00484 void
00485 HDBNode::addChild(HDBHandle& hdl, HDBNode& arg)
00486 {
00487    if (!arg)
00488    {
00489       return;
00490    }
00491    // If this node has never been written, then write it before
00492    // we create a child. If we don't do this, we don't have
00493    // a parent offset to put in the child node
00494    if (m_pdata->m_offset <= 0)
00495    {
00496       write(hdl);
00497    }
00498    // If this node has already been written to the file, and it is the
00499    // child of another parent, throw and exception.
00500    // If it is already a child of this node, then just write it out
00501    // and return.
00502    if (arg.m_pdata->m_offset > 0)
00503    {
00504       // If this node is already the parent, then just
00505       // write the child node and return
00506       if (arg.m_pdata->m_blk.parent == m_pdata->m_offset)
00507       {
00508          arg.write(hdl);
00509          return;
00510       }
00511       OW_THROW(HDBException, "Child node already has a parent. db may be corrupt");
00512    }
00513    arg.m_pdata->m_blk.prevSib = m_pdata->m_blk.lastChild;
00514    arg.m_pdata->m_blk.nextSib = -1;
00515    arg.m_pdata->m_blk.parent = m_pdata->m_offset;
00516    Int32 newNodeOffset = arg.write(hdl);
00517    File file = hdl.getFile();
00518    // If this node already had children, then update the last node in the
00519    // child list to point to the new node.
00520    if (m_pdata->m_blk.lastChild > 0)
00521    {
00522       HDBBlock node;
00523       HDB::readBlock(node, file, m_pdata->m_blk.lastChild);
00524       // Update next sibling pointer on node
00525       node.nextSib = newNodeOffset; 
00526       // Write prev sibling node
00527       HDB::writeBlock(node, file, m_pdata->m_blk.lastChild);
00528    }
00529    m_pdata->m_blk.lastChild = arg.m_pdata->m_offset;
00530    if (m_pdata->m_blk.firstChild <= 0)
00531    {
00532       m_pdata->m_blk.firstChild = m_pdata->m_blk.lastChild;
00533    }
00534    write(hdl);
00535 }
00537 bool
00538 HDBNode::remove(HDBHandle& hdl)
00539 {
00540    // If node hasn't been written yet, don't do anything.
00541    if (m_pdata->m_offset <= 0)
00542    {
00543       return false;
00544    }
00545    File file = hdl.getFile();
00546    HDB* pdb = hdl.getHDB();
00547    HDBBlock fblk;
00548    // Remove all children
00549    Int32 coffset = m_pdata->m_blk.lastChild;
00550    Int32 toffset;
00551    while (coffset > 0)
00552    {
00553       HDB::readBlock(fblk, file, coffset);
00554       toffset = coffset;         // Save offset for deletion class
00555       coffset = fblk.prevSib;    // Save offset for next read
00556       // Remove node and all of its children. This call will modify fblk.
00557       removeBlock(hdl, fblk, toffset);
00558    }
00559    // Set pointer on next sibling if it exists
00560    if (m_pdata->m_blk.nextSib > 0)
00561    {
00562       HDB::readBlock(fblk, file, m_pdata->m_blk.nextSib);
00563       fblk.prevSib = m_pdata->m_blk.prevSib;
00564       HDB::writeBlock(fblk, file, m_pdata->m_blk.nextSib);
00565    }
00566    // Set pointer on prev sibling if it exists
00567    if (m_pdata->m_blk.prevSib > 0)
00568    {
00569       HDB::readBlock(fblk, file, m_pdata->m_blk.prevSib);
00570       fblk.nextSib = m_pdata->m_blk.nextSib;
00571       HDB::writeBlock(fblk, file, m_pdata->m_blk.prevSib);
00572    }
00573    // If it has a parent, insure parent doesn't contain it's offset
00574    if (m_pdata->m_blk.parent > 0)
00575    {
00576       // Read parent block
00577       HDB::readBlock(fblk, file, m_pdata->m_blk.parent);
00578       bool changed = false;
00579       // If this was the first child in the list, then update the
00580       // first child pointer in the parent block
00581       if (fblk.firstChild == m_pdata->m_offset)
00582       {
00583          changed = true;
00584          fblk.firstChild = m_pdata->m_blk.nextSib;
00585       }
00586       // If this was the last child in the list, then update the
00587       // last child pointer in the parent block
00588       if (fblk.lastChild == m_pdata->m_offset)
00589       {
00590          changed = true;
00591          fblk.lastChild = m_pdata->m_blk.prevSib;
00592       }
00593       // If any offsets changed in the parent block, then update the parent
00594       if (changed)
00595       {
00596          HDB::writeBlock(fblk, file, m_pdata->m_blk.parent);
00597       }
00598    }
00599    else
00600    {
00601       // Must be a root node
00602       if (pdb->getFirstRootOffSet() == m_pdata->m_offset)
00603       {
00604          pdb->setFirstRootOffSet(file, m_pdata->m_blk.nextSib);
00605       }
00606       if (pdb->getLastRootOffset() == m_pdata->m_offset)
00607       {
00608          pdb->setLastRootOffset(file, m_pdata->m_blk.prevSib);
00609       }
00610    }
00611    // Add block to free list
00612    pdb->addBlockToFreeList(file, m_pdata->m_blk, m_pdata->m_offset);
00613    // Remove the index entry for this node
00614    hdl.removeIndexEntry(m_pdata->m_key.c_str());
00615    m_pdata->m_offset = -1;
00616    m_pdata->m_blk.isFree = true;
00617    m_pdata->m_blk.parent = -1;
00618    m_pdata->m_blk.firstChild = -1;
00619    m_pdata->m_blk.lastChild = -1;
00620    m_pdata->m_blk.prevSib = -1;
00621    m_pdata->m_blk.nextSib = -1;
00622    m_pdata->m_blk.size = 0;
00623    hdl.registerWrite();
00624    return true;
00625 }
00627 // removeBlock is used to add a HDBBlock and all of it's children to the
00628 // DB's deletion list. The next sibling and previous sibling fields are
00629 // ignored. The intention is for this method to be called from the
00630 // HFileNodeImpl remove method only! This method is recursive, so all stack
00631 // optimizations are welcome.
00632 #define LMAX(a, b)   ((int(a) > int(b)) ? (a) : (b))
00633 void
00634 HDBNode::removeBlock(HDBHandle& hdl, HDBBlock& fblk, Int32 offset)
00635 {
00636    AutoPtrVec<unsigned char>
00637       pbfr(new unsigned char[LMAX(sizeof(fblk), fblk.keyLength)]);
00638    File file = hdl.getFile();
00639    Int32 coffset = fblk.lastChild;
00640    if (coffset > 0)
00641    {
00642       while (coffset > 0)
00643       {
00644          HDB::readBlock(*(reinterpret_cast<HDBBlock*>(pbfr.get())), file, coffset);
00645          // Save current offset for call to removeBlock
00646          Int32 toffset = coffset;
00647          // Get pointer to previous sibling
00648          coffset = (reinterpret_cast<HDBBlock*>(pbfr.get()))->prevSib;
00649          // Recursive call to removeBlock. *pblk.get() will be modified.
00650          removeBlock(hdl, *(reinterpret_cast<HDBBlock*>(pbfr.get())), toffset);
00651       }
00652    }
00653    // Need to read the key for this block to update the index
00654    if (file.read(pbfr.get(), fblk.keyLength, offset + sizeof(fblk))
00655       != size_t(fblk.keyLength))
00656    {
00657       OW_THROW_ERRNO_MSG(HDBException, "Failed to read node's key for removal");
00658    }
00659    // Remove this node's key from the index
00660    hdl.removeIndexEntry(reinterpret_cast<const char*>(pbfr.get()));
00661    // Add the block to the free list
00662    hdl.getHDB()->addBlockToFreeList(file, fblk, offset);
00663 }
00664 
00665 } // end namespace OW_NAMESPACE
00666 

Generated on Thu Feb 9 08:47:59 2006 for openwbem by  doxygen 1.4.6