1 //-< CURSOR.H >------------------------------------------------------*--------* 2 // GigaBASE Version 1.0 (c) 1999 GARRET * ? * 3 // (Post Relational Database Management System) * /\| * 4 // * / \ * 5 // Created: 20-Nov-98 K.A. Knizhnik * / [] \ * 6 // Last update: 10-Dec-98 K.A. Knizhnik * GARRET * 7 //-------------------------------------------------------------------*--------* 8 // Selection of objects 9 //-------------------------------------------------------------------*--------* 10 11 #ifndef __SELECTION_H__ 12 #define __SELECTION_H__ 13 14 class dbOrderByNode; 15 class dbDatabase; 16 class dbRecord; 17 18 /** 19 * Abstract result set iterator 20 */ 21 class GIGABASE_DLL_ENTRY dbAbstractIterator { 22 public: 23 virtual oid_t next() = 0; 24 virtual oid_t prev() = 0; 25 virtual oid_t first() = 0; 26 virtual oid_t last() = 0; 27 ~dbAbstractIterator()28 virtual ~dbAbstractIterator() {} 29 }; 30 31 32 class GIGABASE_DLL_ENTRY dbL2List { 33 public: 34 dbL2List* next; 35 dbL2List* prev; 36 link(dbL2List * elem)37 void link(dbL2List* elem) { 38 elem->prev = this; 39 elem->next = next; 40 next = next->prev = elem; 41 } unlink()42 void unlink() { 43 #ifdef __INSURE__ 44 if (((void*) next == (void*) prev) && 45 ((void*) next == (void*) this)) return; 46 #endif 47 next->prev = prev; 48 prev->next = next; 49 next = prev = this; 50 } isEmpty()51 bool isEmpty() { 52 return next == this; 53 } reset()54 void reset() { 55 next = prev = this; 56 } dbL2List()57 dbL2List() { 58 next = prev = this; 59 } ~dbL2List()60 ~dbL2List() { 61 unlink(); 62 } 63 }; 64 65 66 67 struct GIGABASE_DLL_ENTRY dbSortRecord { 68 oid_t oid; 69 union { 70 db_int8 longKey; 71 real8 realKey; 72 int4 intKey; 73 void* rawKey; 74 char_t* strKey; 75 } u; 76 }; 77 78 class GIGABASE_DLL_ENTRY dbStrBuffer { 79 protected: 80 struct dbStrSegment { 81 enum { 82 dbSegmentSize = 256*1024 83 }; 84 dbStrSegment* next; 85 char_t data[dbSegmentSize]; 86 }; 87 dbStrSegment* chain; 88 size_t used; 89 public: put(char_t const * str,size_t len)90 char_t* put(char_t const* str, size_t len) { 91 assert(len < dbStrSegment::dbSegmentSize); 92 if (used + len >= dbStrSegment::dbSegmentSize) { 93 dbStrSegment* seg = new dbStrSegment(); 94 seg->next = chain; 95 chain = seg; 96 used = 0; 97 } 98 char_t* p = chain->data + used; 99 memcpy(p, str, sizeof(char_t)*(len + 1)); 100 used += len + 1; 101 return p; 102 } dbStrBuffer()103 dbStrBuffer() { 104 chain = NULL; 105 used = dbStrSegment::dbSegmentSize; 106 } ~dbStrBuffer()107 ~dbStrBuffer() { 108 while (chain != NULL) { 109 dbStrSegment* next = chain->next; 110 delete chain; 111 chain = next; 112 } 113 } 114 }; 115 116 class GIGABASE_DLL_ENTRY dbSortResult { 117 public: 118 dbStrBuffer strBuf; 119 dbSortRecord* keys; 120 char* rawKeys; 121 ~dbSortResult()122 ~dbSortResult() { 123 delete[] keys; 124 delete[] rawKeys; 125 } 126 }; 127 128 129 class GIGABASE_DLL_ENTRY dbSelection { 130 public: 131 enum { FIRST_SEGMENT_SIZE = 16 }; 132 133 static size_t buildSelectionBitmapThreshold; 134 135 class segment { 136 public: 137 segment* prev; 138 segment* next; 139 size_t nRows; 140 size_t maxRows; 141 oid_t rows[FIRST_SEGMENT_SIZE]; 142 allocate(size_t nRows,segment * after)143 static segment* allocate(size_t nRows, segment* after) { 144 segment* s = (segment*)dbMalloc(sizeof(segment) + sizeof(oid_t)*(nRows-FIRST_SEGMENT_SIZE)); 145 s->next = after->next; 146 s->prev = after; 147 after->next = after->next->prev = s; 148 s->nRows = 0; 149 s->maxRows = nRows; 150 return s; 151 } 152 delete(void * p)153 void operator delete(void* p) { 154 dbFree(p); 155 } 156 segment()157 segment() { 158 maxRows = FIRST_SEGMENT_SIZE; 159 next = prev = this; 160 nRows = 0; 161 } 162 prune()163 void prune() { 164 next = prev = this; 165 } 166 ~segment()167 ~segment() { 168 prev->next = next; 169 next->prev = prev; 170 } 171 }; 172 segment first; 173 segment* curr; 174 cardinality_t nRows; 175 size_t pos; 176 int4* bitmap; 177 size_t bitmapSize; 178 add(oid_t oid)179 void add(oid_t oid) { 180 segment* s = first.prev; 181 if (s->nRows == s->maxRows) { 182 s = segment::allocate(s->maxRows*2, s); 183 } 184 s->rows[s->nRows++] = oid; 185 nRows += 1; 186 } 187 188 void truncate(cardinality_t from, cardinality_t length); 189 void toArray(oid_t* oids) const; 190 void merge(dbDatabase* db, dbSelection& selection); 191 void allocateBitmap(dbDatabase* db); 192 void deallocateBitmap(); 193 194 void sort(dbDatabase* db, dbOrderByNode* order, bool caseInsensitive = false, dbSortResult* sortResult = NULL); 195 static int compare(oid_t o1, dbRecord* a, oid_t o2, dbRecord* b, dbOrderByNode* order); 196 197 static int __cdecl exactKeyCmp(void const* a, void const* b); 198 static int __cdecl udtComparator(void const* a, void const* b); 199 dbSelection()200 dbSelection() { 201 nRows = 0; 202 pos = 0; 203 curr = &first; 204 bitmap = NULL; 205 bitmapSize = 0; 206 } 207 ~dbSelection()208 ~dbSelection() { 209 delete[] bitmap; 210 } 211 212 void reverse(); 213 void reset(); 214 }; 215 216 #endif 217