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