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 #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:
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:
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:
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
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
00741 Status next(unsigned int *found_cnt, Idx::Key *key = 0);
00742
00743 ~HIdxCursor();
00744 };
00745
00750 };
00751
00752 #endif