00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00036 #ifndef OW_HDB_HPP_INCLUDE_GUARD_
00037 #define OW_HDB_HPP_INCLUDE_GUARD_
00038 #include "OW_config.h"
00039 #include "OW_HDBCommon.hpp"
00040 #include "OW_String.hpp"
00041 #include "OW_Index.hpp"
00042 #include "OW_IntrusiveReference.hpp"
00043 #include "OW_IntrusiveCountableBase.hpp"
00044 #include "OW_File.hpp"
00045 #include "OW_HDBNode.hpp"
00046 #include "OW_RWLocker.hpp"
00047 #include "OW_MutexLock.hpp"
00048 #include <cstdio>
00049
00050 namespace OW_NAMESPACE
00051 {
00052
00053 class HDB;
00055 class OW_HDB_API HDBHandle
00056 {
00057 private:
00058 struct HDBHandleData : public IntrusiveCountableBase
00059 {
00060 HDBHandleData(HDB* pdb, const File& file) :
00061 m_pdb(pdb), m_file(file), m_writeDone(false),
00062 m_userVal(0L) {}
00063 HDBHandleData() :
00064 m_pdb(NULL), m_file(), m_writeDone(false),
00065 m_userVal(0L) {}
00066 ~HDBHandleData();
00067
00068 HDB* m_pdb;
00069 File m_file;
00070 bool m_writeDone;
00071 Int32 m_userVal;
00072 };
00073 typedef IntrusiveReference<HDBHandleData> HDBHandleDataRef;
00074 public:
00079 HDBHandle(const HDBHandle& x) : m_pdata(x.m_pdata) {}
00080 HDBHandle();
00086 HDBHandle& operator= (const HDBHandle& x)
00087 {
00088 m_pdata = x.m_pdata;
00089 return *this;
00090 }
00094 void flush();
00102 HDBNode getNode(const String& key);
00110 HDBNode getParent(HDBNode& node);
00118 HDBNode getFirstChild(HDBNode& node);
00126 HDBNode getLastChild(HDBNode& node);
00134 HDBNode getNextSibling(HDBNode& node);
00142 HDBNode getPrevSibling(HDBNode& node);
00148 HDBNode getFirstRoot();
00155 bool addRootNode(HDBNode& node);
00163 bool addChild(HDBNode& parentNode, HDBNode& childNode);
00171 bool addChild(const String& parentKey, HDBNode& childNode);
00178 bool removeNode(HDBNode& node);
00185 bool removeNode(const String& key);
00194 bool updateNode(HDBNode& node, Int32 dataLen, const unsigned char* data);
00200 void turnFlagsOn(HDBNode& node, UInt32 flags);
00206 void turnFlagsOff(HDBNode& node, UInt32 flags);
00214 void setUserValue(Int32 value) { m_pdata->m_userVal = value; }
00219 Int32 getUserValue() const { return m_pdata->m_userVal; }
00220
00221 typedef HDBHandleDataRef HDBHandle::*safe_bool;
00225 operator safe_bool () const
00226 { return m_pdata ? &HDBHandle::m_pdata : 0; }
00227 bool operator!() const
00228 { return !m_pdata; }
00229 private:
00230 HDBHandle(HDB* pdb, const File& file);
00231 File getFile() { return m_pdata->m_file; }
00232 HDB* getHDB() { return m_pdata->m_pdb; }
00233 Int32 registerWrite();
00234 IndexEntry findFirstIndexEntry(const char* key=NULL);
00235 IndexEntry findNextIndexEntry();
00236 IndexEntry findPrevIndexEntry();
00237 IndexEntry findIndexEntry(const char* key);
00238 bool addIndexEntry(const char* key, Int32 offset);
00239 bool removeIndexEntry(const char* key);
00240 bool updateIndexEntry(const char* key, Int32 newOffset);
00241 friend class HDB;
00242 friend class HDBNode;
00243
00244 #ifdef OW_WIN32
00245 #pragma warning (push)
00246 #pragma warning (disable: 4251)
00247 #endif
00248
00249 HDBHandleDataRef m_pdata;
00250
00251 #ifdef OW_WIN32
00252 #pragma warning (pop)
00253 #endif
00254
00255 };
00257 class OW_HDB_API HDB
00258 {
00259 public:
00260
00264 HDB();
00268 ~HDB();
00274 void open(const char* fileName);
00278 void close();
00285 HDBHandle getHandle();
00286
00287 typedef bool HDB::*safe_bool;
00291 operator safe_bool () const
00292 { return m_opened ? &HDB::m_opened : 0; }
00293 bool operator!() const
00294 { return !m_opened; }
00298 int getHandleCount() const { return m_hdlCount; }
00302 String getFileName() const { return m_fileName; }
00310 static void writeBlock(HDBBlock& fblk, File& file, Int32 offset);
00319 static void readBlock(HDBBlock& fblk, const File& file, Int32 offset);
00320 private:
00321 bool createFile();
00322 void checkFile();
00323 void setOffsets(File& file, Int32 firstRootOffset, Int32 lastRootOffset,
00324 Int32 firstFreeOffset);
00325 void setFirstRootOffSet(File& file, Int32 offset);
00326 void setLastRootOffset(File& file, Int32 offset);
00327 void setFirstFreeOffSet(File& file, Int32 offset);
00328 Int32 getFirstRootOffSet() { return m_hdrBlock.firstRoot; }
00329 Int32 getLastRootOffset() { return m_hdrBlock.lastRoot; }
00330 Int32 getFirstFreeOffSet() { return m_hdrBlock.firstFree; }
00331 Int32 findBlock(File& file, int size);
00332 void removeBlockFromFreeList(File& file, HDBBlock& fblk);
00333 void addRootNode(File& file, HDBBlock& fblk, Int32 offset);
00334 void addBlockToFreeList(File& file, const HDBBlock& parmblk,
00335 Int32 offset);
00336 Int32 getVersion() { return m_version; }
00337 Int32 incVersion();
00338 void decHandleCount();
00339 IndexEntry findFirstIndexEntry(const char* key=NULL);
00340 IndexEntry findNextIndexEntry();
00341 IndexEntry findPrevIndexEntry();
00342 IndexEntry findIndexEntry(const char* key);
00343 bool addIndexEntry(const char* key, Int32 offset);
00344 bool removeIndexEntry(const char* key);
00345 bool updateIndexEntry(const char* key, Int32 newOffset);
00346 void flushIndex();
00347
00348 #ifdef OW_WIN32
00349 #pragma warning (push)
00350 #pragma warning (disable: 4251)
00351 #endif
00352
00353 HDBHeaderBlock m_hdrBlock;
00354 File m_lockFile;
00355 String m_fileName;
00356 Int32 m_version;
00357 int m_hdlCount;
00358 bool m_opened;
00359 IndexRef m_pindex;
00360 Mutex m_indexGuard;
00361 Mutex m_guard;
00362 friend class HDBNode;
00363 friend class HDBHandle;
00364 friend struct HDBHandle::HDBHandleData;
00365
00366 #ifdef OW_WIN32
00367 #pragma warning (pop)
00368 #endif
00369
00370 };
00371
00372 }
00373
00374 #endif