26 #ifndef CUR_LIST_INCLUDED
27 #define CUR_LIST_INCLUDED
34 #include "../base/ver.h"
38 #include "../base/str.h"
41 #ifndef CHECK_INCLUDED
42 #include "../base/check.h"
45 #ifndef STACK_INCLUDED
46 #include "../bds/stack.h"
50 #include "../rel/list.h"
62 static const long CUR_LIST_MAGIC = 0x434C540AL;
79 "cur_list_c::constructor: list is NULL");
80 CHECK_PAR(list,
"cur_list_c::constructor");
87 LeafPtr = LIST_LEAF_NULL;
88 MidPtr = LIST_MID_NULL;
89 TopPtr = LIST_TOP_NULL;
121 init(0, List->NumRows);
128 inline void open(
int start_pos) {
134 CHECK(start_pos >= 0,
"cur_list_c::open: start_pos < 0");
135 CHECK(start_pos <= List->NumRows,
136 "cur_list_c::open: start_pos too big");
139 StartPos = start_pos;
140 EndPos = List->NumRows;
141 TotalRest = EndPos - StartPos;
149 LeafPtr = LIST_LEAF_NULL;
150 MidPtr = LIST_MID_NULL;
151 TopPtr = LIST_TOP_NULL;
158 inline bool fetch() {
175 LeafRest = PAGE_SIZE(T) - 1;
183 MidRest = PAGE_SIZE(T*) - 1;
185 LeafRest = PAGE_SIZE(T) - 1;
190 int leaf_offset = StartPos % PAGE_SIZE(T);
191 int mid_offset = StartPos / PAGE_SIZE(T);
192 int top_offset = mid_offset / PAGE_SIZE(T*);
193 mid_offset = mid_offset % PAGE_SIZE(T*);
194 CHECK(leaf_offset >= 0,
"cur_list_c::fetch: leaf_offset < 0");
195 CHECK(mid_offset >= 0,
"cur_list_c::fetch: mid_offset < 0");
196 CHECK(top_offset >= 0,
"cur_list_c::fetch: top_offset < 0");
197 CHECK(leaf_offset < PAGE_SIZE(T),
198 "cur_list_c::fetch: leaf_offset too big");
199 CHECK(mid_offset < PAGE_SIZE(T*),
200 "cur_list_c::fetch: mid_offset too big");
201 CHECK(top_offset < PAGE_SIZE(T**),
202 "cur_list_c::fetch: top_offset too big");
203 switch(List->Height) {
206 "cur_list_c::fetch: TotalRest>0 but list empty");
211 LeafPtr = List->LeafNode + leaf_offset;
212 LeafRest = PAGE_SIZE(T) - 1 - leaf_offset;
216 MidPtr = List->MidNode + mid_offset;
217 MidRest = PAGE_SIZE(T*) - 1 - mid_offset;
218 LeafPtr = *MidPtr + leaf_offset;
219 LeafRest = PAGE_SIZE(T) - 1 - leaf_offset;
222 TopPtr = List->TopNode + top_offset;
223 TopRest = PAGE_SIZE(T**) - 1 - top_offset;
224 MidPtr = *TopPtr + mid_offset;
225 MidRest = PAGE_SIZE(T*) - 1 - mid_offset;
226 LeafPtr = *MidPtr + leaf_offset;
227 LeafRest = PAGE_SIZE(T) - 1 - leaf_offset;
231 "cur_list_c::fetch: Invalid height");
246 CHECK(LeafPtr != LIST_LEAF_NULL,
247 "cur_list_c::row: No current tuple");
265 int start_pos = EndPos - TotalRest;
266 CHECK(start_pos >= 0,
"cur_list_c::push: start_pos < 0");
267 CHECK(start_pos <= EndPos,
268 "cur_list_c::push: start_pos too big");
269 if(!stack->push(start_pos))
274 if(!stack->push(EndPos))
291 int end_pos = stack->pop();
292 int start_pos = stack->pop();
293 CHECK(start_pos >= 0,
"cur_list_c::pop: start_pos < 0");
294 CHECK(end_pos >= 0,
"cur_list_c::pop: end_pos < 0");
295 CHECK(start_pos <= end_pos,
296 "cur_list_c::pop: start_pos too big");
297 CHECK(end_pos <= List->NumRows,
298 "cur_list_c::pop: end_pos too big");
299 init(start_pos, end_pos);
306 inline void close() {
322 inline void init(
int start_pos,
int end_pos) {
328 CHECK(start_pos >= 0,
"cur_list_c::init: start_pos < 0");
329 CHECK(start_pos <= List->NumRows,
330 "cur_list_c::init: start_pos too big");
331 CHECK(end_pos >= 0,
"cur_list_c::init: end_pos < 0");
332 CHECK(end_pos <= List->NumRows,
333 "cur_list_c::init: end_pos too big");
336 StartPos = start_pos;
338 TotalRest = EndPos - StartPos;
346 LeafPtr = LIST_LEAF_NULL;
347 MidPtr = LIST_MID_NULL;
348 TopPtr = LIST_TOP_NULL;
372 str_t check()
const {
375 if(Magic != CUR_LIST_MAGIC)
376 return "wrong magic number";
385 if(StartPos > List->NumRows)
386 CHECK_ERR(
"StartPos is bigger than list length");
389 if(EndPos > List->NumRows)
390 CHECK_ERR(
"EndPos is bigger than list length");
391 if(StartPos > EndPos + 1)
393 if(TotalRest > EndPos - StartPos)
403 if(LeafRest >= PAGE_SIZE(T))
405 if(MidRest >= PAGE_SIZE(T*))
407 if(TopRest >= PAGE_SIZE(T**))
411 if(LeafRest > 0 && LeafPtr == LIST_LEAF_NULL)
412 CHECK_ERR(
"LeafRest is positive, but pointer is null");
413 if(MidRest > 0 && MidPtr == LIST_MID_NULL)
414 CHECK_ERR(
"MidRest is positive, but pointer is null");
415 if(TopRest > 0 && TopPtr == LIST_TOP_NULL)
416 CHECK_ERR(
"TopRest is positive, but pointer is null");
419 if(MidPtr != LIST_MID_NULL &&
421 (PAGE_SIZE(T) - LeafRest - 1))
422 CHECK_ERR(
"LeafPtr inconsistent with MidPtr+Rest");
423 if(TopPtr != LIST_TOP_NULL &&
425 (PAGE_SIZE(T*) - MidRest - 1))
426 CHECK_ERR(
"MidPtr inconsistent with TopPtr+Rest");
429 switch(List->Height) {
434 if(LeafPtr < List->LeafNode)
436 if(LeafPtr >= List->LeafNode + PAGE_SIZE(T))
438 if(LeafPtr != List->LeafNode +
439 (PAGE_SIZE(T)-LeafRest-1))
445 if(MidPtr < List->MidNode)
447 if(MidPtr >= List->MidNode + PAGE_SIZE(T*))
449 if(MidPtr != List->MidNode +
450 (PAGE_SIZE(T*)-MidRest-1))
456 if(TopPtr < List->TopNode)
458 if(TopPtr >= List->TopNode + PAGE_SIZE(T**))
460 if(TopPtr != List->TopNode +
461 (PAGE_SIZE(T**)-TopRest-1))
490 headline =
"Cursor for List";
#define CHECK_CODE(CODE)
Definition: check.h:167
static void dump_ptr(const void *p)
Definition: err.cpp:791
#define CHECK_ERR(MSG)
Definition: check.h:182
static void dump_str(str_t str)
Definition: err.cpp:705
#define VER_PAGESIZE
Definition: ver.h:186
#define CHECK_IMPOSSIBLE(MSG)
Definition: check.h:151
#define CHECK_VALID(EX)
Definition: check.h:85
static void dump_begin(str_t headline)
Definition: err.cpp:685
const char * str_t
Definition: str.h:41
#define STR_NULL
Definition: str.h:52
Definition: cur_list.h:68
static void dump_end()
Definition: err.cpp:811
static void dump_int(int n)
Definition: err.cpp:739
static void dump_nl()
Definition: err.cpp:717
#define CHECK(EX, MSG)
Definition: check.h:69
#define CHECK_PAR(PAR, PLACE)
Definition: check.h:102