OW_HDB.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_HDB.hpp"
00038 #include "OW_AutoPtr.hpp"
00039 #include "OW_Format.hpp"
00040 #if defined(OW_HAVE_ISTREAM) && defined(OW_HAVE_OSTREAM)
00041 #include <istream>
00042 #include <ostream>
00043 #else
00044 #include <iostream>
00045 #endif
00046 #include <cstring>
00047 
00048 extern "C"
00049 {
00050 #include <errno.h>
00051 }
00052 
00053 namespace OW_NAMESPACE
00054 {
00055 
00056 static UInt32 calcCheckSum(unsigned char* src, Int32 len);
00058 HDB::HDB() :
00059    m_hdrBlock(), m_fileName(), m_version(0), m_hdlCount(0),
00060    m_opened(false), m_pindex(NULL), m_indexGuard(), m_guard()
00061 {
00062 }
00064 HDB::~HDB()
00065 {
00066    try
00067    {
00068       if (m_hdlCount > 0)
00069       {
00070          // cerr << "*** HDB::~HDB - STILL OUTSTANDING HANDLES ***" << endl;
00071       }
00072       close();
00073    }
00074    catch (...)
00075    {
00076       // don't let exceptions escape
00077    }
00078 }
00080 void
00081 HDB::close()
00082 {
00083    if (m_opened)
00084    {
00085       m_pindex->close();
00086       m_pindex = 0;
00087       m_opened = false;
00088       m_lockFile.unlock();
00089       m_lockFile.close();
00090    }
00091 }
00093 void
00094 HDB::open(const char* fileName)
00095 {
00096    MutexLock l(m_guard);
00097    if (m_opened)
00098    {
00099       return;
00100    }
00101    m_hdlCount = 0;
00102    m_version = 0;
00103    m_fileName = fileName;
00104 
00105    String lockFilename = m_fileName + ".lock";
00106    m_lockFile = FileSystem::openOrCreateFile(lockFilename);
00107    if (!m_lockFile)
00108    {
00109       OW_THROW(HDBException,
00110          Format("Unable to open or create lock: %1, errno: %2(%3)",
00111             lockFilename, errno, strerror(errno)).c_str());
00112    }
00113 
00114    // if we can't get a lock, someone else has got it open.
00115    if (m_lockFile.tryLock() == -1)
00116    {
00117       OW_THROW(HDBException,
00118          Format("Unable to lock HDB, verify it's not in use: %1, errno: %2(%3)",
00119             lockFilename, errno, strerror(errno)).c_str());
00120    }
00121 
00122    String fname = m_fileName + ".dat";
00123    createFile();
00124    checkFile();
00125    m_fileName = fname;
00126    m_opened = true;
00127 }
00129 bool
00130 HDB::createFile()
00131 {
00132    HDBHeaderBlock b = { OW_HDBSIGNATURE, HDBVERSION, -1L, -1L, -1L };
00133    m_hdrBlock = b;
00134    File f = FileSystem::createFile(m_fileName + ".dat");
00135    if (!f)
00136    {
00137       return false;
00138    }
00139    if (f.write(&m_hdrBlock, sizeof(m_hdrBlock), 0) != sizeof(m_hdrBlock))
00140    {
00141       f.close();
00142       OW_THROW(HDBException, "Failed to write header of HDB");
00143    }
00144    f.close();
00145 
00146    m_pindex = Index::createIndexObject();
00147    m_pindex->open(m_fileName.c_str());
00148    return true;
00149 }
00151 void
00152 HDB::checkFile()
00153 {
00154    File f = FileSystem::openFile(m_fileName + ".dat");
00155    if (!f)
00156    {
00157       String msg("Failed to open file: ");
00158       msg += m_fileName;
00159       OW_THROW(HDBException, msg.c_str());
00160    }
00161    if (f.read(&m_hdrBlock, sizeof(m_hdrBlock), 0) != sizeof(m_hdrBlock))
00162    {
00163       f.close();
00164       String msg("Failed to read HDB header from file: ");
00165       msg += m_fileName;
00166       OW_THROW(HDBException, msg.c_str());
00167    }
00168    f.close();
00169    if (::strncmp(m_hdrBlock.signature, OW_HDBSIGNATURE, HDBSIGLEN))
00170    {
00171       String msg("Invalid Format for HDB file: ");
00172       msg += m_fileName;
00173       OW_THROW(HDBException, msg.c_str());
00174    }
00175    if (m_hdrBlock.version < MinHDBVERSION || m_hdrBlock.version > HDBVERSION)
00176    {
00177       OW_THROW(HDBException, Format("Invalid version (%1) for file (%2). Expected (%3)", m_hdrBlock.version, m_fileName, HDBVERSION).c_str());
00178    }
00179    m_pindex = Index::createIndexObject();
00180    m_pindex->open(m_fileName.c_str());
00181 }
00183 Int32
00184 HDB::incVersion()
00185 {
00186    MutexLock l(m_guard);
00187    m_version++;
00188    return m_version;
00189 }
00191 HDBHandle
00192 HDB::getHandle()
00193 {
00194    MutexLock l(m_guard);
00195    if (!m_opened)
00196    {
00197       OW_THROW(HDBException, "Can't get handle from closed HDB");
00198    }
00199    const File& file = FileSystem::openFile(m_fileName);
00200    if (!file)
00201    {
00202       return HDBHandle();
00203    }
00204    m_hdlCount++;
00205    return HDBHandle(this, file);
00206 }
00208 void
00209 HDB::decHandleCount()
00210 {
00211    MutexLock l(m_guard);
00212    m_hdlCount--;
00213 }
00215 void
00216 HDB::setOffsets(File& file, Int32 firstRootOffset, Int32 lastRootOffset,
00217    Int32 firstFreeOffset)
00218 {
00219    MutexLock l(m_guard);
00220    m_hdrBlock.firstRoot = firstRootOffset;
00221    m_hdrBlock.lastRoot = lastRootOffset;
00222    m_hdrBlock.firstFree = firstFreeOffset;
00223    if (file.write(&m_hdrBlock, sizeof(m_hdrBlock), 0) != sizeof(m_hdrBlock))
00224    {
00225       OW_THROW(HDBException, "Failed to update offset on HDB");
00226    }
00227 }
00229 void
00230 HDB::setFirstRootOffSet(File& file, Int32 offset)
00231 {
00232    setOffsets(file, offset, m_hdrBlock.lastRoot, m_hdrBlock.firstFree);
00233 }
00235 void
00236 HDB::setLastRootOffset(File& file, Int32 offset)
00237 {
00238    setOffsets(file, m_hdrBlock.firstRoot, offset, m_hdrBlock.firstFree);
00239 }
00241 void
00242 HDB::setFirstFreeOffSet(File& file, Int32 offset)
00243 {
00244    setOffsets(file, m_hdrBlock.firstRoot, m_hdrBlock.lastRoot, offset);
00245 }
00247 // Find a block in the free list that is large enough to hold the given
00248 // size. If no block in the free list is large enough or the free list
00249 // is empty, then the offset to the end of the file is returned
00250 Int32
00251 HDB::findBlock(File& file, Int32 size)
00252 {
00253    MutexLock l(m_guard);
00254    Int32 offset = -1;
00255    HDBBlock fblk;
00256    // If the free list is not empty, then search it for a block
00257    // big enough to hold the given size
00258    if (m_hdrBlock.firstFree != -1)
00259    {
00260       Int32 coffset = m_hdrBlock.firstFree;
00261       while (true)
00262       {
00263          readBlock(fblk, file, coffset);
00264          // If the current block size is greater than or equal to the
00265          // size being requested, then we found a block in the file
00266          // we can use.
00267          if (fblk.size >= static_cast<UInt32>(size))
00268          {
00269             offset = coffset;
00270             break;
00271          }
00272          if ((coffset = fblk.nextSib) == -1L)
00273          {
00274             break;
00275          }
00276       }
00277    }
00278    // If offset is no longer -1, then we must have found a block
00279    // of adequate size.
00280    if (offset != -1)
00281    {
00282       // Remove the block from the free list
00283       removeBlockFromFreeList(file, fblk);
00284    }
00285    else
00286    {
00287       // We didn't find a block that was big enough, so let's just allocate
00288       // a chunk at the end of the file.
00289       if (file.seek(0L, SEEK_END) == -1L)
00290       {
00291          OW_THROW(HDBException, "Failed to seek to end of file");
00292       }
00293       if ((offset = file.tell()) == -1L)
00294       {
00295          OW_THROW(HDBException, "Failed to get offset in file");
00296       }
00297    }
00298    return offset;
00299 }
00301 void
00302 HDB::removeBlockFromFreeList(File& file, HDBBlock& fblk)
00303 {
00304    MutexLock l(m_guard);
00305    HDBBlock cblk;
00306    // If block has a next sibling, then set it's previous sibling pointer
00307    // to the given blocks previous pointer
00308    if (fblk.nextSib != -1)
00309    {
00310       readBlock(cblk, file, fblk.nextSib);
00311       cblk.prevSib = fblk.prevSib;
00312       writeBlock(cblk, file, fblk.nextSib);
00313    }
00314    // If block has a previous sibling, then set it's next sibling pointer
00315    // to the given blocks next pointer
00316    if (fblk.prevSib != -1)
00317    {
00318       readBlock(cblk, file, fblk.prevSib);
00319       cblk.nextSib = fblk.nextSib;
00320       writeBlock(cblk, file, fblk.prevSib);
00321    }
00322    else     // Block must be the 1st one in the free list
00323    {
00324       // If no previous sibling, assume this was the 1st in the
00325       // free list, so set the head pointer
00326       if (m_hdrBlock.firstFree != -1)
00327       {
00328          setFirstFreeOffSet(file, fblk.nextSib);
00329       }
00330    }
00331 }
00333 // Add a block to the free list.
00334 void
00335 HDB::addBlockToFreeList(File& file, const HDBBlock& parmblk,
00336    Int32 offset)
00337 {
00338    MutexLock l(m_guard);
00339    HDBBlock fblk = parmblk;
00340    fblk.isFree = true;
00341    // If the free list is empty, set the free list head pointer only
00342    if (m_hdrBlock.firstFree == -1)
00343    {
00344       fblk.nextSib = -1;
00345       fblk.prevSib = -1;
00346       writeBlock(fblk, file, offset);
00347       setFirstFreeOffSet(file, offset);
00348       return;
00349    }
00350    HDBBlock cblk;
00351    cblk.size = 0;
00352    Int32 coffset = m_hdrBlock.firstFree;
00353    Int32 loffset = 0;
00354    // Find insertion point in free list
00355    while (coffset != -1)
00356    {
00357       loffset = coffset;
00358       readBlock(cblk, file, coffset);
00359       if (fblk.size <= cblk.size)
00360       {
00361          break;
00362       }
00363       coffset = cblk.nextSib;
00364    }
00365    if (coffset == -1)      // Append to end of free list?
00366    {
00367       cblk.nextSib = offset;
00368       writeBlock(cblk, file, loffset);
00369       fblk.prevSib = loffset;
00370       fblk.nextSib = -1;
00371       writeBlock(fblk, file, offset);
00372    }
00373    else                 // Insert before last node read
00374    {
00375       if (cblk.prevSib == -1)       // If this Was the 1st on the list
00376       {                                // Set the free list head pointer
00377          setFirstFreeOffSet(file, offset);      
00378       }
00379       else
00380       {
00381          // Read the previous node from last read to set it's next
00382          // sibling pointer
00383          HDBBlock tblk;
00384          readBlock(tblk, file, cblk.prevSib);
00385          tblk.nextSib = offset;
00386          writeBlock(tblk, file, cblk.prevSib);
00387       }
00388       fblk.nextSib = coffset;
00389       fblk.prevSib = cblk.prevSib;
00390       writeBlock(fblk, file, offset);
00391       // Set the prev sib pointer in last read to the node being added.
00392       cblk.prevSib = offset;
00393       writeBlock(cblk, file, coffset);
00394    }
00395 }
00397 // addRootNode will insert the given node into the files root node list.
00398 // Upon return the file pointer should be positioned immediately after
00399 // the given node in the file.
00400 void
00401 HDB::addRootNode(File& file, HDBBlock& fblk, Int32 offset)
00402 {
00403    MutexLock l(m_guard);
00404    fblk.parent = -1;
00405    fblk.nextSib = -1;
00406    if (m_hdrBlock.firstRoot == -1)
00407    {
00408       setOffsets(file, offset, offset, m_hdrBlock.firstFree);
00409       fblk.prevSib = -1;
00410    }
00411    else
00412    {
00413       fblk.prevSib = m_hdrBlock.lastRoot;
00414       HDBBlock cblk;
00415       readBlock(cblk, file, m_hdrBlock.lastRoot);
00416       cblk.nextSib = offset;
00417       writeBlock(cblk, file, m_hdrBlock.lastRoot);
00418       setLastRootOffset(file, offset);
00419    }
00420    writeBlock(fblk, file, offset);
00421 }
00423 // STATIC
00424 void
00425 HDB::writeBlock(HDBBlock& fblk, File& file, Int32 offset)
00426 {
00427    fblk.chkSum = 0;
00428    UInt32 chkSum = calcCheckSum(reinterpret_cast<unsigned char*>(&fblk), sizeof(fblk));
00429    fblk.chkSum = chkSum;
00430    int cc = file.write(&fblk, sizeof(fblk), offset);
00431    if (cc != sizeof(fblk))
00432    {
00433       OW_THROW(HDBException, "Failed to write block");
00434    }
00435 }
00437 // STATIC   
00438 void
00439 HDB::readBlock(HDBBlock& fblk, const File& file, Int32 offset)
00440 {
00441    int cc = file.read(&fblk, sizeof(fblk), offset);
00442    if (cc != sizeof(fblk))
00443    {
00444       OW_THROW(HDBException, "Failed to read block");
00445    }
00446    UInt32 chkSum = fblk.chkSum;
00447    fblk.chkSum = 0;
00448    fblk.chkSum = calcCheckSum(reinterpret_cast<unsigned char*>(&fblk), sizeof(fblk));
00449    if (chkSum != fblk.chkSum)
00450    {
00451       OW_THROW(HDBException, "CORRUPT DATA? Invalid check sum in node");
00452    }
00453 }
00455 IndexEntry
00456 HDB::findFirstIndexEntry(const char* key)
00457 {
00458    if (!m_opened)
00459    {
00460       OW_THROW(HDBException, "HDB is not opened");
00461    }
00462    MutexLock il(m_indexGuard);
00463    return m_pindex->findFirst(key);
00464 }
00466 IndexEntry
00467 HDB::findNextIndexEntry()
00468 {
00469    if (!m_opened)
00470    {
00471       OW_THROW(HDBException, "HDB is not opened");
00472    }
00473    MutexLock il(m_indexGuard);
00474    return m_pindex->findNext();
00475 }
00477 IndexEntry
00478 HDB::findPrevIndexEntry()
00479 {
00480    if (!m_opened)
00481    {
00482       OW_THROW(HDBException, "HDB is not opened");
00483    }
00484    MutexLock il(m_indexGuard);
00485    return m_pindex->findPrev();
00486 }
00488 IndexEntry
00489 HDB::findIndexEntry(const char* key)
00490 {
00491    if (!m_opened)
00492    {
00493       OW_THROW(HDBException, "HDB is not opened");
00494    }
00495    MutexLock il(m_indexGuard);
00496    return m_pindex->find(key);
00497 }
00499 bool
00500 HDB::addIndexEntry(const char* key, Int32 offset)
00501 {
00502    if (!m_opened)
00503    {
00504       OW_THROW(HDBException, "HDB is not opened");
00505    }
00506    MutexLock il(m_indexGuard);
00507    return m_pindex->add(key, offset);
00508 }
00510 bool
00511 HDB::removeIndexEntry(const char* key)
00512 {
00513    if (!m_opened)
00514    {
00515       OW_THROW(HDBException, "HDB is not opened");
00516    }
00517    MutexLock il(m_indexGuard);
00518    return m_pindex->remove(key);
00519 }
00521 bool
00522 HDB::updateIndexEntry(const char* key, Int32 newOffset)
00523 {
00524    if (!m_opened)
00525    {
00526       OW_THROW(HDBException, "HDB is not opened");
00527    }
00528    MutexLock il(m_indexGuard);
00529    return m_pindex->update(key, newOffset);
00530 }
00532 void
00533 HDB::flushIndex()
00534 {
00535    if (m_opened)
00536    {
00537       MutexLock il(m_indexGuard);
00538       m_pindex->flush();
00539    }
00540 }
00542 static UInt32
00543 calcCheckSum(unsigned char* src, Int32 len)
00544 {
00545    UInt32 cksum = 0;
00546    Int32 i;
00547    for (i = 0; i < len; i++)
00548    {
00549       cksum += src[i];
00550    }
00551    return cksum;
00552 }
00554 // ROUTINES FOR HDBHandle class
00555 HDBHandle::HDBHandleData::~HDBHandleData()
00556 {
00557    try
00558    {
00559       m_file.close();
00560       m_pdb->decHandleCount();
00561    }
00562    catch (...)
00563    {
00564       // don't let exceptions escape
00565    }
00566 }
00568 HDBHandle::HDBHandle() :
00569    m_pdata(NULL)
00570 {
00571 }
00573 HDBHandle::HDBHandle(HDB* pdb, const File& file) :
00574    m_pdata(new HDBHandleData(pdb, file))
00575 {
00576 }
00578 Int32
00579 HDBHandle::registerWrite()
00580 {
00581    m_pdata->m_writeDone = true;
00582    return m_pdata->m_pdb->incVersion();
00583 }
00585 void
00586 HDBHandle::flush()
00587 {
00588    if (m_pdata->m_writeDone)
00589    {
00590       m_pdata->m_pdb->flushIndex();
00591       m_pdata->m_file.flush();
00592       m_pdata->m_writeDone = false;
00593    }
00594 }
00596 HDBNode
00597 HDBHandle::getFirstRoot()
00598 {
00599    if (m_pdata->m_pdb->getFirstRootOffSet() > 0)
00600    {
00601       return HDBNode(m_pdata->m_pdb->getFirstRootOffSet(), *this);
00602    }
00603    return HDBNode();
00604 }
00606 HDBNode
00607 HDBHandle::getNode(const String& key)
00608 {
00609    if (!key.empty())
00610    {
00611       return HDBNode(key.c_str(), *this);
00612    }
00613    return HDBNode();
00614 }
00616 HDBNode
00617 HDBHandle::getParent(HDBNode& node)
00618 {
00619    if (node)
00620    {
00621       if (node.reload(*this))
00622       {
00623          if (node.getParentOffset() > 0)
00624          {
00625             return HDBNode(node.getParentOffset(), *this);
00626          }
00627       }
00628    }
00629    return HDBNode();
00630 }
00632 HDBNode
00633 HDBHandle::getFirstChild(HDBNode& node)
00634 {
00635    if (node)
00636    {
00637       if (node.reload(*this))
00638       {
00639          if (node.getFirstChildOffset() > 0)
00640          {
00641             return HDBNode(node.getFirstChildOffset(), *this);
00642          }
00643       }
00644    }
00645    return HDBNode();
00646 }
00648 HDBNode
00649 HDBHandle::getLastChild(HDBNode& node)
00650 {
00651    if (node)
00652    {
00653       if (node.reload(*this))
00654       {
00655          if (node.getLastChildOffset() > 0)
00656          {
00657             return HDBNode(node.getLastChildOffset(), *this);
00658          }
00659       }
00660    }
00661    return HDBNode();
00662 }
00664 HDBNode
00665 HDBHandle::getNextSibling(HDBNode& node)
00666 {
00667    if (node)
00668    {
00669       if (node.reload(*this))
00670       {
00671          if (node.getNextSiblingOffset() > 0)
00672          {
00673             return HDBNode(node.getNextSiblingOffset(), *this);
00674          }
00675       }
00676    }
00677    return HDBNode();
00678 }
00680 HDBNode
00681 HDBHandle::getPrevSibling(HDBNode& node)
00682 {
00683    if (node)
00684    {
00685       if (node.reload(*this))
00686       {
00687          if (node.getPrevSiblingOffset() > 0)
00688          {
00689             return HDBNode(node.getPrevSiblingOffset(), *this);
00690          }
00691       }
00692    }
00693    return HDBNode();
00694 }
00696 bool
00697 HDBHandle::addRootNode(HDBNode& node)
00698 {
00699    bool cc = false;
00700    if (node)
00701    {
00702       if (node.getOffset() > 0)
00703       {
00704          OW_THROW(HDBException, "node is already on file");
00705       }
00706       if (m_pdata->m_pdb->findIndexEntry(node.getKey().c_str()))
00707       {
00708          OW_THROW(HDBException, "key for node is already in index");
00709       }
00710       node.write(*this);
00711       cc = true;
00712    }
00713    return cc;
00714 }
00716 bool
00717 HDBHandle::addChild(HDBNode& parentNode, HDBNode& childNode)
00718 {
00719    bool cc = false;
00720    if (parentNode && childNode)
00721    {
00722       if (childNode.getOffset() > 0)
00723       {
00724          OW_THROW(HDBException, "child node already has a parent");
00725       }
00726       if (parentNode.getOffset() <= 0)
00727       {
00728          OW_THROW(HDBException, "parent node is not on file");
00729       }
00730       if (m_pdata->m_pdb->findIndexEntry(childNode.getKey().c_str()))
00731       {
00732          OW_THROW(HDBException, "key for node is already in index");
00733       }
00734       if (parentNode.reload(*this))
00735       {
00736          parentNode.addChild(*this, childNode);
00737          cc = true;
00738       }
00739    }
00740    return cc;
00741 }
00743 bool
00744 HDBHandle::addChild(const String& parentKey, HDBNode& childNode)
00745 {
00746    if (parentKey.empty())
00747    {
00748       return false;
00749    }
00750    HDBNode pnode = HDBNode(parentKey.c_str(), *this);
00751    if (pnode)
00752    {
00753       return addChild(pnode, childNode);
00754    }
00755    return false;
00756 }
00758 bool
00759 HDBHandle::removeNode(HDBNode& node)
00760 {
00761    bool cc = false;
00762    if (node && node.getOffset() > 0)
00763    {
00764       if (node.reload(*this))
00765       {
00766          node.remove(*this);
00767          cc = true;
00768       }
00769    }
00770    return cc;
00771 }
00773 bool
00774 HDBHandle::removeNode(const String& key)
00775 {
00776    bool cc = false;
00777    if (!key.empty())
00778    {
00779       HDBNode node(key.c_str(), *this);
00780       if (node)
00781       {
00782          node.remove(*this);
00783       }
00784       cc = true;
00785    }
00786    return cc;
00787 }
00789 bool
00790 HDBHandle::updateNode(HDBNode& node, Int32 dataLen, const unsigned char* data)
00791 {
00792    bool cc = false;
00793    if (node)
00794    {
00795       // If node is already on file, then get a writelock on db
00796       if (node.getOffset() > 0)
00797       {
00798          if (node.reload(*this))
00799          {
00800             node.updateData(*this, dataLen, data);
00801             cc = true;
00802          }
00803       }
00804       else
00805       {
00806          // Node isn't yet on file. No need for a write lock
00807          node.updateData(*this, dataLen, data);
00808          cc = true;
00809       }
00810    }
00811    return cc;
00812 }
00814 void
00815 HDBHandle::turnFlagsOn(HDBNode& node, UInt32 flags)
00816 {
00817    if (node)
00818    {
00819       if (node.getOffset() > 0)
00820       {
00821          if (node.reload(*this))
00822          {
00823          node.turnFlagsOn(*this, flags);
00824          }
00825       }
00826       else
00827       {
00828          node.turnFlagsOn(*this, flags);
00829       }
00830    }
00831 }
00833 void
00834 HDBHandle::turnFlagsOff(HDBNode& node, UInt32 flags)
00835 {
00836    if (node)
00837    {
00838       if (node.getOffset() > 0)
00839       {
00840          if (node.reload(*this))
00841          {
00842             node.turnFlagsOff(*this, flags);
00843          }
00844       }
00845       else
00846       {
00847          node.turnFlagsOff(*this, flags);
00848       }
00849    }
00850 }
00852 IndexEntry
00853 HDBHandle::findFirstIndexEntry(const char* key)
00854 {
00855    return m_pdata->m_pdb->findFirstIndexEntry(key);
00856 }
00858 IndexEntry
00859 HDBHandle::findNextIndexEntry()
00860 {
00861    return m_pdata->m_pdb->findNextIndexEntry();
00862 }
00864 IndexEntry
00865 HDBHandle::findPrevIndexEntry()
00866 {
00867    return m_pdata->m_pdb->findPrevIndexEntry();
00868 }
00870 IndexEntry
00871 HDBHandle::findIndexEntry(const char* key)
00872 {
00873    return m_pdata->m_pdb->findIndexEntry(key);
00874 }
00876 bool
00877 HDBHandle::addIndexEntry(const char* key, Int32 offset)
00878 {
00879    return m_pdata->m_pdb->addIndexEntry(key, offset);
00880 }
00882 bool
00883 HDBHandle::removeIndexEntry(const char* key)
00884 {
00885    return m_pdata->m_pdb->removeIndexEntry(key);
00886 }
00888 bool
00889 HDBHandle::updateIndexEntry(const char* key, Int32 newOffset)
00890 {
00891    return m_pdata->m_pdb->updateIndexEntry(key, newOffset);
00892 }
00893 
00894 } // end namespace OW_NAMESPACE
00895 

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