BAM
Abstract Machine for Bottom-Up Evaluation with the Push Method
gen_cur1.h
Go to the documentation of this file.
1 // ============================================================================
2 // Project: Deductive Database
3 // Filename: gen_cur1.h
4 // Purpose: Cursor over generated one-column relations (for tests).
5 // Last Change: 04.08.2017
6 // Language: C++
7 // EMail: brass@informatik.uni-halle.de
8 // WWW: http://www.informatik.uni-halle.de/~brass/
9 // Address: Feldschloesschen 15, D-06120 Halle (Saale), GERMANY
10 // Copyright: (c) 2016-2017 by Stefan Brass
11 // License: See file "LICENSE" for copying conditions.
12 // Note: There is no warranty at all - this code may contain bugs.
13 // ============================================================================
14 
15 
22 //=============================================================================
23 // Include File Frame:
24 //=============================================================================
25 
26 #ifndef GEN_CUR1_INCLUDED
27 #define GEN_CUR1_INCLUDED
28 
29 //=============================================================================
30 // Used Types and Macros:
31 //=============================================================================
32 
33 #ifndef VER_INCLUDED
34 #include "../base/ver.h"
35 #endif
36 
37 #ifndef STR_INCLUDED
38 #include "../base/str.h"
39 #endif
40 
41 #ifndef CHECK_INCLUDED
42 #include "../base/check.h"
43 #endif
44 
45 #ifndef STACK_INCLUDED
46 #include "../bds/stack.h"
47 #endif
48 
49 //=============================================================================
50 // Private Constants:
51 //=============================================================================
52 
53 //-----------------------------------------------------------------------------
54 // GEN_CUR1_MAGIC: Magic number (identifies objects of this class).
55 //-----------------------------------------------------------------------------
56 
57 static const long GEN_CUR1_MAGIC = 0x4743310AL; // 'GC1\n'
58 
59 //=============================================================================
60 // Class for Cursor to Generated Relation with One Integer Column (for Tests):
61 //=============================================================================
62 
63 class gen_cur1_c {
64  public:
65 
66 //-----------------------------------------------------------------------------
67 // Constructor, Destructor:
68 //-----------------------------------------------------------------------------
69 
70  // Constructor 1 with full parameter selection:
71  gen_cur1_c(int type, int size, int max_value);
72 
73  // Constructor 2 with simplified relation ID:
74  gen_cur1_c(int rel_id);
75 
76  // Destructor:
77  ~gen_cur1_c();
78 
79 //-----------------------------------------------------------------------------
80 // Methods:
81 //-----------------------------------------------------------------------------
82 
83  // open: Open the cursor.
84  void open();
85 
86  // fetch: Get next tuple, returns false if there is no further tuple.
87  bool fetch() {
88 
89  // Check this object:
90  CHECK_VALID("gen_cur1_c::fetch");
91 
92  // Check state:
93  CHECK(TupleNo != -1,
94  "gen_cur1_c::fetch: cursor not open");
95  CHECK(TupleNo <= Size,
96  "gen_cur1_c::fetch: fetch beyond end");
97 
98  // Increase tuple number (counts number of fetches):
99  TupleNo++;
100 
101  // Check whether we are at the end of the relation:
102  if(TupleNo > Size)
103  return false;
104 
105  // Simple linear sequence:
106  if(Type == 1) {
107  if(TupleNo == 1) {
108  // First fetch:
109  C1 = 0;
110  }
111  else {
112  C1++;
113  }
114  return true;
115  }
116 
117  // Mixed sequences:
118  if(Type == 2) {
119  int state = TupleNo % 6;
120  // Note that TupleNo is 1 for the first tuple.
121  switch(state) {
122  case 1:
123  case 4:
124  if(BottomUp <= MaxValue) {
125  C1 = BottomUp;
126  BottomUp += 3;
127  return true;
128  }
129  break;
130  case 0:
131  case 3:
132  if(TopDown > 0) {
133  C1 = TopDown;
134  TopDown -= 3;
135  return true;
136  }
137  break;
138  case 2:
139  if(MiddleUp <= MaxValue) {
140  C1 = MiddleUp;
141  MiddleUp += 3;
142  return true;
143  }
144  break;
145  case 5:
146  if(MiddleDown > 0) {
147  C1 = MiddleDown;
148  MiddleDown -= 3;
149  return true;
150  }
151  break;
152  }
153 
154  // A limit has been reached. Take whatever possible:
155  if(BottomUp <= MaxValue) {
156  C1 = BottomUp;
157  BottomUp += 3;
158  return true;
159  }
160  if(TopDown > 0) {
161  C1 = TopDown;
162  TopDown -= 3;
163  return true;
164  }
165  if(MiddleUp <= MaxValue) {
166  C1 = MiddleUp;
167  MiddleUp += 3;
168  return true;
169  }
170  if(MiddleDown > 0) {
171  C1 = MiddleDown;
172  MiddleDown -= 3;
173  return true;
174  }
175  CHECK_IMPOSSIBLE("gen_cur1_c::fetch: No more values");
176  }
177 
178  // We should never arrive here:
179  return false;
180  }
181 
182  // c1: Return value of column 1 to which the cursor points.
183  int c1() {
184 
185  // Check this object:
186  CHECK_VALID("gen_cur1_c::c1");
187 
188  // Check state:
189  CHECK(TupleNo != -1,
190  "gen_cur1_c::c1: cursor not open");
191  CHECK(TupleNo > 0,
192  "gen_cur1_c::c1: fetch must be called first");
193  CHECK(TupleNo <= Size,
194  "gen_cur1_c::c1: fetch beyond end");
195 
196  // Return current value for column 1:
197  return C1;
198  }
199 
200  // close: Close cursor.
201  void close() {
202 
203  // Check this object:
204  CHECK_VALID("gen_cur1_c::close");
205 
206  // Check state:
207  CHECK(TupleNo >= 0,
208  "gen_cur1_c::close: cursor not open");
209 
210  // Close cursor:
211  TupleNo = -1;
212  C1 = -1;
213  }
214 
215  // push: Save the cursor state on a stack.
216  bool push(stack_c<int> *stack) {
217 
218  // Check this object:
219  CHECK_VALID("gen_cur1_c::push");
220 
221  // Save changeable attributes:
222  if(!stack->push(TupleNo))
223  return false;
224  if(!stack->push(C1))
225  return false;
226  if(!stack->push(BottomUp))
227  return false;
228  if(!stack->push(TopDown))
229  return false;
230  if(!stack->push(MiddleUp))
231  return false;
232  if(!stack->push(MiddleDown))
233  return false;
234 
235  // Ok:
236  return true;
237  }
238 
239  // pop: Restore the cursor state from a stack.
240  void pop(stack_c<int> *stack) {
241 
242  // Check this object:
243  CHECK_VALID("gen_cur1_c::pop");
244 
245  // Restore changeable attributes (in opposite order):
246  MiddleDown = stack->pop();
247  MiddleUp = stack->pop();
248  TopDown = stack->pop();
249  BottomUp = stack->pop();
250  C1 = stack->pop();
251  TupleNo = stack->pop();
252  }
253 
254 //-----------------------------------------------------------------------------
255 // Debugging Support:
256 //-----------------------------------------------------------------------------
257 
258 #if VER_DEBUG
259  public:
260  // Integrity check:
261  str_t check() const;
262 
263  private:
264  // Magic number (identifies objects of this class for debugging).
265  long Magic; // Must be "GEN_CUR1_MAGIC".
266 #endif
267 
268 #if VER_DUMP
269  public:
270  // Display data structure:
271  void dump(str_t headline = STR_NULL) const;
272 #endif
273 
274 //-----------------------------------------------------------------------------
275 // Copy-constructor and assignment operator are not supported for this class:
276 //-----------------------------------------------------------------------------
277 
278  private:
279 
280  gen_cur1_c(const gen_cur1_c& obj); // Not implemented
281  gen_cur1_c& operator=(const gen_cur1_c& obj); // Not implemented
282 
283 //-----------------------------------------------------------------------------
284 // Private Object Members:
285 //-----------------------------------------------------------------------------
286 
287  private:
288 
289  // Type of this sequence
290  // (1: simple sequential, 2: mixed sequences):
291  int Type;
292 
293  // Relation size (number of tuples to be generated):
294  int Size;
295 
296  // Maximal Value that can be used (domain size):
297  int MaxValue;
298 
299  // Current tuple number:
300  int TupleNo;
301 
302  // Current value for column 1 in the tuple sequence:
303  int C1;
304 
305  // Current value of number generator starting at 0,
306  // stepping +3 (this is always == 0 modulo 3):
307  int BottomUp;
308 
309  // Current value of number generator starting at largest value
310  // (that is == 1 mod 3) stepping -3 (this is always == 1 modulo 3):
311  int TopDown;
312 
313  // Current value of number generator starting in the middle,
314  // stepping +3 (this is always == 2 modulo 3):
315  int MiddleUp;
316 
317  // Current value of number generator starting in the middle,
318  // stepping -3 (this is always == 2 modulo 3):
319  int MiddleDown;
320 
321 
322 //-----------------------------------------------------------------------------
323 // Auxiliary Methods:
324 //-----------------------------------------------------------------------------
325 
326  // Initialize sequence generator attributes:
327  void init();
328 
329 //=============================================================================
330 // End of Class:
331 //=============================================================================
332 
333 };
334 
335 //-----------------------------------------------------------------------------
336 // Define pointer type:
337 //-----------------------------------------------------------------------------
338 
339 typedef gen_cur1_c *gen_cur1_t;
340 
341 //-----------------------------------------------------------------------------
342 // Define null pointer:
343 //-----------------------------------------------------------------------------
344 
345 #define GEN_CUR1_NULL (static_cast<gen_cur1_t>(0))
346 
347 //=============================================================================
348 // End of Include File:
349 //=============================================================================
350 
351 #endif
352 
#define CHECK_IMPOSSIBLE(MSG)
Definition: check.h:151
#define CHECK_VALID(EX)
Definition: check.h:85
const char * str_t
Definition: str.h:41
Definition: gen_cur1.h:63
#define STR_NULL
Definition: str.h:52
#define CHECK(EX, MSG)
Definition: check.h:69