00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef __SELECTION_H__
00012 #define __SELECTION_H__
00013
00014 class dbOrderByNode;
00015 class dbDatabase;
00016 class dbRecord;
00017
00021 class GIGABASE_DLL_ENTRY dbAbstractIterator {
00022 public:
00023 virtual oid_t next() = 0;
00024 virtual oid_t prev() = 0;
00025 virtual oid_t first() = 0;
00026 virtual oid_t last() = 0;
00027
00028 virtual ~dbAbstractIterator() {}
00029 };
00030
00031
00032 class GIGABASE_DLL_ENTRY dbL2List {
00033 public:
00034 dbL2List* next;
00035 dbL2List* prev;
00036
00037 void link(dbL2List* elem) {
00038 elem->prev = this;
00039 elem->next = next;
00040 next = next->prev = elem;
00041 }
00042 void unlink() {
00043 #ifdef __INSURE__
00044 if (((void*) next == (void*) prev) &&
00045 ((void*) next == (void*) this)) return;
00046 #endif
00047 next->prev = prev;
00048 prev->next = next;
00049 next = prev = this;
00050 }
00051 bool isEmpty() {
00052 return next == this;
00053 }
00054 void reset() {
00055 next = prev = this;
00056 }
00057 dbL2List() {
00058 next = prev = this;
00059 }
00060 ~dbL2List() {
00061 unlink();
00062 }
00063 };
00064
00065
00066
00067 struct GIGABASE_DLL_ENTRY dbSortRecord {
00068 oid_t oid;
00069 union {
00070 db_int8 longKey;
00071 real8 realKey;
00072 int4 intKey;
00073 void* rawKey;
00074 char_t* strKey;
00075 } u;
00076 };
00077
00078 class GIGABASE_DLL_ENTRY dbStrBuffer {
00079 protected:
00080 struct dbStrSegment {
00081 enum {
00082 dbSegmentSize = 256*1024
00083 };
00084 dbStrSegment* next;
00085 char_t data[dbSegmentSize];
00086 };
00087 dbStrSegment* chain;
00088 size_t used;
00089 public:
00090 char_t* put(char_t const* str, size_t len) {
00091 assert(len < dbStrSegment::dbSegmentSize);
00092 if (used + len >= dbStrSegment::dbSegmentSize) {
00093 dbStrSegment* seg = new dbStrSegment();
00094 seg->next = chain;
00095 chain = seg;
00096 used = 0;
00097 }
00098 char_t* p = chain->data + used;
00099 memcpy(p, str, sizeof(char_t)*(len + 1));
00100 used += len + 1;
00101 return p;
00102 }
00103 dbStrBuffer() {
00104 chain = NULL;
00105 used = dbStrSegment::dbSegmentSize;
00106 }
00107 ~dbStrBuffer() {
00108 while (chain != NULL) {
00109 dbStrSegment* next = chain->next;
00110 delete chain;
00111 chain = next;
00112 }
00113 }
00114 };
00115
00116 class GIGABASE_DLL_ENTRY dbSortResult {
00117 public:
00118 dbStrBuffer strBuf;
00119 dbSortRecord* keys;
00120 char* rawKeys;
00121
00122 ~dbSortResult() {
00123 delete[] keys;
00124 delete[] rawKeys;
00125 }
00126 };
00127
00128
00129 class GIGABASE_DLL_ENTRY dbSelection {
00130 public:
00131 enum { FIRST_SEGMENT_SIZE = 16 };
00132
00133 static size_t buildSelectionBitmapThreshold;
00134
00135 class segment {
00136 public:
00137 segment* prev;
00138 segment* next;
00139 size_t nRows;
00140 size_t maxRows;
00141 oid_t rows[FIRST_SEGMENT_SIZE];
00142
00143 static segment* allocate(size_t nRows, segment* after) {
00144 segment* s = (segment*)dbMalloc(sizeof(segment) + sizeof(oid_t)*(nRows-FIRST_SEGMENT_SIZE));
00145 s->next = after->next;
00146 s->prev = after;
00147 after->next = after->next->prev = s;
00148 s->nRows = 0;
00149 s->maxRows = nRows;
00150 return s;
00151 }
00152
00153 void operator delete(void* p) {
00154 dbFree(p);
00155 }
00156
00157 segment() {
00158 maxRows = FIRST_SEGMENT_SIZE;
00159 next = prev = this;
00160 nRows = 0;
00161 }
00162
00163 void prune() {
00164 next = prev = this;
00165 }
00166
00167 ~segment() {
00168 prev->next = next;
00169 next->prev = prev;
00170 }
00171 };
00172 segment first;
00173 segment* curr;
00174 size_t nRows;
00175 size_t pos;
00176 int4* bitmap;
00177 size_t bitmapSize;
00178
00179 void add(oid_t oid) {
00180 segment* s = first.prev;
00181 if (s->nRows == s->maxRows) {
00182 s = segment::allocate(s->maxRows*2, s);
00183 }
00184 s->rows[s->nRows++] = oid;
00185 nRows += 1;
00186 }
00187
00188 void truncate(size_t from, size_t length);
00189 void toArray(oid_t* oids) const;
00190 void merge(dbDatabase* db, dbSelection& selection);
00191 void allocateBitmap(dbDatabase* db);
00192 void deallocateBitmap();
00193
00194 void sort(dbDatabase* db, dbOrderByNode* order, bool caseInsensitive = false, dbSortResult* sortResult = NULL);
00195 static int compare(oid_t o1, dbRecord* a, oid_t o2, dbRecord* b, dbOrderByNode* order);
00196
00197 static int __cdecl exactKeyCmp(void const* a, void const* b);
00198 static int __cdecl udtComparator(void const* a, void const* b);
00199
00200 dbSelection() {
00201 nRows = 0;
00202 pos = 0;
00203 curr = &first;
00204 bitmap = NULL;
00205 bitmapSize = 0;
00206 }
00207
00208 ~dbSelection() {
00209 delete[] bitmap;
00210 }
00211
00212 void reverse();
00213 void reset();
00214 };
00215
00216 #endif