HIdx.h

00001 /* 
00002    EyeDB Object Database Management System
00003    Copyright (C) 1994-2008 SYSRA
00004    
00005    EyeDB is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009    
00010    EyeDB is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014    
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with this library; if not, write to the Free Software
00017    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA 
00018 */
00019 
00020 /*
00021    Author: Eric Viara <viara@sysra.com>
00022 */
00023 
00024 
00025 #ifndef _eyedbsm_HIdx_
00026 #define _eyedbsm_HIdx_
00027 
00028 #include <stdio.h>
00029 #include <eyedblib/machtypes.h>
00030 #include <eyedbsm/Idx.h>
00031 #include <vector>
00032 #include <map>
00033 
00034 namespace eyedblib {
00035   class ThreadPool;
00036   class ThreadPerformer;
00037 }
00038 
00039 #define HAS_ALLOC_BUFFER
00040 
00041 namespace eyedbsm {
00042 
00048   class HIdxCursor;
00049 
00050   static const int HIdxImplHintsCount = 8;
00051   static const unsigned int HIdxDataVarSize = ~0U;
00052 
00057   class HIdx : public Idx {
00058 
00059     friend class HIdxCursor;
00060 
00061 #ifdef HAS_ALLOC_BUFFER
00062     AllocBuffer insert_buffer;
00063     AllocBuffer makeobj_buffer;
00064 #endif
00065 
00066   public: /* conceptually private */
00067     class CellHeader;
00068     class CListObjHeader;
00069     class CListHeader;
00070 
00071   public:
00072     enum HIdxKeyType {
00073       stringType = 1,
00074       dataType
00075     };
00076 
00077 
00078     struct _Idx {
00079       unsigned int idxtype;
00080       unsigned int object_count;
00081       unsigned int mag_order;
00082       unsigned int key_count;
00083       short dspid;
00084       unsigned int keytype;
00085       unsigned int keysz;
00086       unsigned int datasz;
00087       unsigned int offset;
00088       int impl_hints[HIdxImplHintsCount];
00089       void trace(FILE *fd = stdout) const;
00090       std::string toString() const;
00091     };
00092 
00093   public: //@@@@ A.W just try to cure
00094     struct _Idx hidx;
00095   private:
00096     unsigned int mask;
00097     Boolean pow2;
00098     Boolean uextend;
00099     Boolean data_grouped_by_key;
00100     unsigned int data_grouped_sizeof;
00101     Oid treeoid;
00102     Status stat;
00103     DbHandle *dbh;
00104     int bsize;
00105     hash_key_t hash_key;
00106     void *hash_data;
00107     int version;
00108     Boolean nocopy;
00109 
00110     class HKey {
00111       const void *key;
00112       HIdx *hidx;
00113       bool _garbage;
00114 
00115     public:
00116 
00117       HKey(HIdx *hidx, const void *key, bool copy = false);
00118       HKey(const HKey &);
00119       HKey& operator=(const HKey &);
00120 
00121       int operator<(const HKey &okey) const {
00122         return hidx->cmp(key, okey.key, 0) < 0 ? 1 : 0;
00123       }
00124 
00125       const void *getKey() const {return key;}
00126 
00127       void garbage() {
00128         if (_garbage) {
00129           free((char *)key);
00130           key = 0;
00131         }
00132       }
00133 
00134       ~HKey() {
00135         garbage();
00136       }
00137     };
00138 
00139     friend class HKey;
00140    
00141     std::map<HKey, std::vector<const void *> > cache_map;
00142 
00143     static void *copy_key(const void *, unsigned int, Boolean, Boolean *state = 0);
00144     Status dumpMemoryMap(const CListHeader &, const char *msg = "", FILE *fd = stdout);
00145 
00146     Status readCellHeader(int off, const Oid &, CellHeader &) const;
00147     Status writeCellHeader(int off, const Oid &, const CellHeader &) const;
00148     Status readCListObjHeader(const Oid &, CListObjHeader &) const;
00149     Status writeCListObjHeader(const Oid &, const CListObjHeader &) const;
00150     Status readCListHeader(unsigned int k, CListHeader &chd) const;
00151     Status writeCListHeader(unsigned int k, const CListHeader &chd) const;
00152     Status readCListHeaders(CListHeader *&chds) const;
00153     Status writeCListHeaders(const CListHeader *chds) const;
00154 
00155     Status insertCell(int offset, unsigned int size, CListObjHeader &h,
00156                       const Oid &koid) const;
00157     Status suppressCell(int offset, CListObjHeader &h, const Oid &koid) const;
00158     Status get_key(unsigned int &, const void *, unsigned int * = 0) const;
00159     int cmp(const void *, const void *, unsigned char) const;
00160     Status count_manage(DbHandle *dbh, int inc);
00161     Status getCell(unsigned int size, CListHeader &chd, unsigned int chd_k,
00162                    Oid &koid, CListObjHeader &h, int &offset, CellHeader &o);
00163     Status insert_realize(CListHeader &chd, unsigned int chd_k, const void *key,
00164                           unsigned int size, const void *xdata,
00165                           const Oid &koid, CListObjHeader &h, int offset,
00166                           CellHeader &o, unsigned int datasz);
00167     Status insert_perform(const void *key, std::vector<const void *> &xdata_v, unsigned int datasz);
00168     Status insert_perform(const void *key, const void *xdata, unsigned int datasz);
00169     Status remove_perform(const void *key, const void *xdata, unsigned int datasz, Boolean *found, unsigned char **prdata, unsigned int *pdatacnt, int *found_idx, unsigned int incr_alloc);
00170     Status remove_realize(CListHeader *chd, unsigned int chd_key,
00171                           const char *, const char *, const char *,
00172                           const CellHeader *, const Oid *);
00173     Status search_realize(const void *key, unsigned int *found_cnt, Boolean found_any, void * data);
00174     Status getObjectToExtend(unsigned int size, CListHeader &chd, unsigned int chd_k,
00175                              Oid &koid, CListObjHeader &h, int &offset,
00176                              CellHeader &o, Boolean &found);
00177     Status extendObject(CListHeader &chd, unsigned int chd_k, const Oid &koid,
00178                         CListObjHeader &h, Boolean &extended);
00179     Status extendObject(unsigned int size, CListHeader &chd, unsigned int chd_k, Oid &koid,
00180                         CListObjHeader &h, int &offset, CellHeader &o,
00181                         Boolean &extended);
00182     Boolean candidateForExtension(const CListObjHeader &);
00183     Status makeObject(CListHeader &chd, unsigned int chd_k, Oid &koid, int &offset,
00184                       CListObjHeader &h, CellHeader &o, unsigned int objsize);
00185     static bool inFreeList(const CListObjHeader &h, const CListHeader &chd, const Oid &koid);
00186     Status insertObjectInFreeList(CListHeader &chd, unsigned int chd_k, CListObjHeader &h,
00187                                   const Oid &koid);
00188     Status suppressObjectFromFreeList(CListHeader &chd, unsigned int chd_k, CListObjHeader &h,
00189                                       const Oid &koid);
00190     Status suppressObjectFromList(CListHeader &chd, unsigned int chd_k, CListObjHeader &h,
00191                                   const Oid &koid);
00192     Status replaceObjectInList(CListHeader &chd, unsigned int chd_k, CListObjHeader &h,
00193                                const Oid &koid, const Oid &nkoid);
00194     Status modifyObjectSize(int osize, int nsize, const Oid &koid, 
00195                             Oid &nkoid);
00196     Status headPrint(FILE *, int, Oid *, int&) const;
00197     Status getEntryCount(Oid *, unsigned int& ) const;
00198     Status getHashObjectBusySize(const Oid *koid, unsigned int &busysize,
00199                                  unsigned int &count, unsigned int size = 0) const;
00200     static Status get_def_string_hash_key(const void *key, unsigned int len,
00201                                           void *, unsigned int &);
00202     static Status get_def_nstring_hash_key(const void *key, unsigned int len,
00203                                            void *, unsigned int &);
00204     static Status get_def_rawdata_hash_key(const void *key, unsigned int len,
00205                                            void *, unsigned int &);
00206     static Status get_def_int16data_hash_key(const void *key,
00207                                              unsigned int len, void *, unsigned int &);
00208     static Status get_def_int32data_hash_key(const void *key,
00209                                              unsigned int len, void *, unsigned int &);
00210     static Status get_def_int64data_hash_key(const void *key,
00211                                              unsigned int len, void *, unsigned int &);
00212     static Status get_def_oiddata_hash_key(const void *key, unsigned int len,
00213                                            void *, unsigned int &);
00214     static Status get_def_float32data_hash_key(const void *key,
00215                                                unsigned int len,
00216                                                void *, unsigned int &);
00217     static Status get_def_float64data_hash_key(const void *key,
00218                                                unsigned int len,
00219                                                void *, unsigned int &);
00220 
00221     Status get_string_hash_key(const void *key, unsigned int len, unsigned int &) const;
00222     Status get_rawdata_hash_key(const void *key, unsigned int len, unsigned int &) const;
00223     void printCellHeader(const HIdx::CellHeader *o, int offset) const;
00224     void checkCellHeader(int offset, const Oid *koid) const;
00225     void printCListObjHeader(const HIdx::CListObjHeader *h) const;
00226     void checkCListObjHeader(const Oid *koid) const;
00227     void checkChain(const Oid *koid) const;
00228     void checkChain(const CListHeader *chd, const std::string &msg) const;
00229 
00230     void set_hash_key();
00231     Status destroy_r();
00232     Status copy_realize(Idx *) const;
00233     void init(DbHandle *, unsigned int keytype, unsigned int keysz,
00234               unsigned int offset,
00235               unsigned int datasz, short dspid,
00236               int mag_order, int key_count,
00237               const int *impl_hints,
00238               unsigned int impl_hints_cnt);
00239     KeyType keytype;
00240     Status collapse_realize(short dspid, HIdx *idx_n);
00241     Status h2x_datacnt_cpy(unsigned char *rdata, const unsigned int *pdatacnt) const;
00242     Status x2h_datacnt_cpy(unsigned int *pdatacnt, const unsigned char *pdata) const;
00243 
00244   public:
00245 
00246     enum Hints {
00247       IniSize_Hints,
00248       IniObjCnt_Hints,
00249       XCoef_Hints,
00250       SzMax_Hints,
00251       DataGroupedByKey_Hints
00252     };
00253 
00254     static const unsigned int MaxKeys;
00255     static const unsigned int VarSize;
00256     static const unsigned int MagorderKeycountCoef;
00257 
00269     HIdx(DbHandle *vh, KeyType type,
00270          unsigned int datasz, short dspid,
00271          int magorder, int key_count = 0,
00272          const int *impl_hints = 0,
00273          unsigned int impl_hints_cnt = 0);
00274 
00283     HIdx(DbHandle *vh, const Oid *poid,
00284          hash_key_t hash_key = 0,
00285          void *hash_data = 0,
00286          Boolean (*precmp)(void const * p, void const * q,
00287                            KeyType const * type, int & r) = 0);
00288 
00295     void open(hash_key_t hash_key = 0,
00296               void *hash_data = 0,
00297               Boolean (*precmp)(void const * p, void const * q,
00298                                 KeyType const * type, int & r) = 0);
00299 
00304     unsigned int getCount() const;
00305 
00310     short getDefaultDspid() const;
00311 
00316     void setDefaultDspid(short dspid);
00317 
00324     Status getObjects(Oid *&oids, unsigned int &cnt) const;
00325 
00330     virtual HIdx *asHIdx() {return this;}
00331 
00336     const KeyType & getKeyType() const {return keytype;}
00337 
00342     const HIdx::_Idx & getIdx() const {return hidx;}
00343 
00344     ~HIdx();
00345   
00352     Status insert(const void *key, const void *data);
00353 
00361     Status insert(const void *key, const void *data, unsigned int datasz);
00362 
00369     Status insert(const void *key, std::vector<const void *> &data_v);
00370 
00377     Status insert_cache(const void *key, const void *data);
00378 
00385     Status insert_cache(const void *key, std::vector<const void *> &data_v);
00386 
00391     Status flush_cache(bool insert_data = true);
00392 
00400     Status remove(const void *key, const void *data, Boolean *found = 0);
00401 
00410     Status remove(const void *key, const void *data, unsigned int datasz, Boolean *found = 0);
00411 
00419     Status search(const void *key, unsigned int *found_cnt);
00420 
00428     Status searchAny(const void *key, Boolean *found, void *data = 0);
00429 
00434     Status destroy();
00435 
00441     Status printStat(FILE *fd = stdout) const;
00442 
00448     Status dumpMemoryMap(FILE *fd = stdout);
00449 
00454     Oid const& oid() const {return treeoid;}
00455 
00460     Boolean isDataGroupedByKey() const {return data_grouped_by_key;}
00461 
00466     bool isDataVarSize() const {return hidx.datasz == HIdxDataVarSize;}
00467 
00472     unsigned int getDataGroupedSizeof() const {return data_grouped_sizeof;}
00473 
00478     Status status() const {return stat;}
00479 
00484     unsigned int getKeyCount() const {return hidx.key_count;}
00485 
00490     Status collapse();
00491 
00505     Status copy(HIdx *&idx_n, int key_count, int mag_order = 0,
00506                 short dspid = DefaultDspid,
00507                 const int *impl_hints = 0, unsigned int impl_hints_cnt = 0,
00508                 hash_key_t _hash_key = 0,
00509                 void *_hash_data = 0,
00510                 KeyType *ktype = 0) const;
00511 
00517     static unsigned int getMagOrder(unsigned int keycount);
00518 
00524     static unsigned int getKeyCount(unsigned int magorder);
00525 
00531     Status getStats(std::string& stats) const;
00532 
00533     struct Stats {
00534       _Idx idx;
00535       struct Entry {
00536         unsigned int object_count;
00537         unsigned int hash_object_count;
00538         unsigned int hash_object_size;
00539         unsigned int hash_object_busy_size;
00540       } *entries;
00541       unsigned int min_objects_per_entry;
00542       unsigned int max_objects_per_entry;
00543       unsigned int total_object_count;
00544       unsigned int total_hash_object_count;
00545       unsigned int total_hash_object_size;
00546       unsigned int total_hash_object_busy_size;
00547       unsigned int busy_key_count;
00548       unsigned int free_key_count;
00549 
00550       Stats();
00551       ~Stats();
00552       void trace(Boolean full = True, FILE *fd = stdout) const;
00553       std::string toString(Boolean full = True) const;
00554     };
00555 
00561     Status getStats(HIdx::Stats &stats) const;
00562 
00568     Status move(short dspid, eyedbsm::Oid &newoid,
00569                 hash_key_t hash_key = 0,
00570                 void *hash_data = 0);
00571 
00585     Status reimplementToHash(Oid &newoid, int key_count, int mag_order = 0,
00586                              short dspid = DefaultDspid,
00587                              const int *impl_hints = 0,
00588                              unsigned int impl_hints_cnt = 0,
00589                              hash_key_t hash_key = 0,
00590                              void *hash_data = 0,
00591                              KeyType *ktype = 0);
00592 
00600     Status reimplementToBTree(Oid &newoid, int degree = 0,
00601                               short dspid = DefaultDspid);
00602 
00614     Status simulate(HIdx::Stats &stats, int key_count,
00615                     int mag_order = 0,
00616                     const int *impl_hints = 0,
00617                     unsigned int impl_hints_cnt = 0,
00618                     hash_key_t hash_key = 0,
00619                     void *hash_data = 0) const;
00620 
00621   public: /* conceptually private */
00622     struct CellHeader {
00623     public:
00624       eyedblib::uint32 free:1, size:31;
00625       eyedblib::int32 cell_free_prev, cell_free_next;
00626     };
00627 
00628     struct CListObjHeader {
00629     public:
00630       unsigned int size;
00631       eyedblib::uint16 free_cnt, alloc_cnt;
00632       eyedblib::uint32 free_whole;
00633       eyedblib::int32 cell_free_first;
00634       Oid clobj_free_prev, clobj_free_next;
00635       Oid clobj_prev, clobj_next;
00636     };
00637   
00638     struct CListHeader {
00639     public:
00640       Oid clobj_first, clobj_last;
00641       Oid clobj_free_first;
00642     };
00643   };
00644 
00648   class HIdxCursor : public IdxCursor {
00649 
00650     const HIdx *idx;
00651     void *skey, *ekey;
00652     Boolean sexcl, eexcl;
00653     static const char defaultSKey[];
00654     char *sdata, *edata, *cur;
00655     unsigned int datacnt, idata;
00656     unsigned int jumpsize;
00657     Boolean nocopy;
00658     Boolean data_tofree;
00659     Status read(Boolean& end);
00660     Boolean equal;
00661     unsigned int k_cur, k_end;
00662     int cmp_realize(const void *, const void *, Boolean, unsigned char) const;
00663     int cmp(const void *) const;
00664     Oid koid;
00665     Boolean state;
00666     Boolean (*user_cmp)(const void *key, void *cmp_arg);
00667     void *cmp_arg;
00668     void append_next(void *data, Idx::Key *key, unsigned int n, DataBuffer *dataBuffer);
00669 
00670     void init(DbHandle *);
00671 
00672     // parallel management
00673     unsigned int perf_cnt, perf_end_cnt;
00674     Boolean master, slave;
00675     class LinkList;
00676     Boolean parallelInit(int thread_cnt);
00677     eyedblib::ThreadPerformer **perfs;
00678     HIdxCursor **perf_curs;
00679     LinkList *list;
00680     LinkList **lists;
00681     eyedblib::ThreadPool *thrpool;
00682     HIdxCursor(const HIdx *,
00683                unsigned int k_start,
00684                unsigned int k_end,
00685                const void *,
00686                const void *,
00687                Boolean,
00688                Boolean,
00689                Boolean (*user_cmp)(const void *, void *),
00690                void *cmp_arg,
00691                LinkList *);
00692 
00693     Status next(Boolean *found, unsigned int *found_cnt, void *data, Idx::Key *key, DataBuffer *dataBuffer);
00694 
00695   public:
00707     HIdxCursor(const HIdx *idx,
00708                const void *skey = 0,
00709                const void *ekey = defaultSKey,
00710                Boolean sexcl = False,
00711                Boolean eexcl = False,
00712                Boolean (*user_cmp)(const void *key, void *cmp_arg) = 0,
00713                void *cmp_arg = 0,
00714                int thread_cnt = 0);
00715 
00723     Status next(Boolean *found, void *data = 0, Idx::Key *key = 0);
00724 
00732     Status next(Boolean *found, DataBuffer &data, Idx::Key *key = 0);
00733 
00740     // note: can be only used on data_grouped_by_key index
00741     Status next(unsigned int *found_cnt, Idx::Key *key = 0);
00742 
00743     ~HIdxCursor();
00744   };
00745 
00750 };
00751 
00752 #endif

Generated on Mon Dec 22 18:15:56 2008 for eyedb by  doxygen 1.5.3