34 #include "../base/ver.h"
38 #include "../base/str.h"
42 #include "../base/err.h"
45 #ifndef CHECK_INCLUDED
46 #include "../base/check.h"
50 #include "../mem/page.h"
53 #ifndef MPOOL_INCLUDED
54 #include "../mem/mpool.h"
58 #include "../rel/rel.h"
70 static const long LIST_MAGIC = 0x4C53540AL;
76 #define LIST_LEAF_NULL (static_cast<T*>(PAGE_NULL))
77 #define LIST_MID_NULL (static_cast<T**>(PAGE_NULL))
78 #define LIST_TOP_NULL (static_cast<T***>(PAGE_NULL))
99 "Tree of Tuple Arrays") {
103 "list_c::constructor: list_name is NULL");
107 LeafNode = LIST_LEAF_NULL;
108 MidNode = LIST_MID_NULL;
109 TopNode = LIST_TOP_NULL;
110 LeafPtr = LIST_LEAF_NULL;
111 MidPtr = LIST_MID_NULL;
112 TopPtr = LIST_TOP_NULL;
116 UnusedPage1 = PAGE_NULL;
117 UnusedPage2 = PAGE_NULL;
171 inline page_t alloc_page() {
172 if(UnusedPage1 == PAGE_NULL)
173 return MemPool.alloc_page();
174 page_t page = UnusedPage1;
175 UnusedPage1 = UnusedPage2;
176 UnusedPage2 = PAGE_NULL;
184 inline void free_page(page_t page) {
185 CHECK(page != PAGE_NULL,
"list_c::free_page: page is NULL");
186 if(UnusedPage1 == PAGE_NULL)
189 CHECK(UnusedPage2 == PAGE_NULL,
190 "list_c::free_page: too many pages");
205 inline bool insert(T elem) {
220 if(LeafNode == LIST_LEAF_NULL) {
222 "list_c::insert: null leaf, height != 0");
224 "list_c::insert: null leaf, num_rows != 0");
226 if(page == PAGE_NULL) {
230 LeafNode =
reinterpret_cast<T*
>(page);
231 LeafFree = PAGE_SIZE(T) - 1;
232 CHECK(LeafFree >= 0,
"list_c::insert: T too large");
241 CHECK(LeafNode != LIST_LEAF_NULL,
242 "list_c::insert: LeafNode is NULL");
244 "list_c::insert: LeafFree not 0");
247 T* old_leaf_node = LeafNode;
251 if(page == PAGE_NULL) {
255 LeafNode =
reinterpret_cast<T*
>(page);
256 LeafFree = PAGE_SIZE(T) - 1;
258 "list_c::insert: T too large (2)");
268 if(MidNode == LIST_MID_NULL) {
270 if(page == PAGE_NULL) {
273 LeafNode = old_leaf_node;
278 MidNode =
reinterpret_cast<T**
>(page);
279 MidFree = PAGE_SIZE(T*) - 2;
281 "list_c::insert: T* too large");
283 *MidPtr++ = old_leaf_node;
284 *MidPtr++ = LeafNode;
291 else if(MidFree > 0) {
293 *MidPtr++ = LeafNode;
299 CHECK(MidNode != LIST_MID_NULL,
300 "list_c::insert: MidNode is NULL");
302 "list_c::insert: MidFree not 0");
306 if(page == PAGE_NULL) {
309 LeafNode = old_leaf_node;
314 T** old_mid_node = MidNode;
315 MidNode =
reinterpret_cast<T**
>(page);
316 MidFree = PAGE_SIZE(T*) - 1;
318 "list_c::insert: T* too large (2)");
320 *MidPtr++ = LeafNode;
325 if(TopNode != LIST_TOP_NULL) {
330 LeafNode = old_leaf_node;
333 MidNode = old_mid_node;
346 CHECK(TopNode == LIST_TOP_NULL,
347 "list_c::insert: TopNode is not null");
349 if(page == PAGE_NULL) {
352 LeafNode = old_leaf_node;
355 MidNode = old_mid_node;
360 TopNode =
reinterpret_cast<T***
>(page);
361 TopFree = PAGE_SIZE(T**) - 2;
363 "list_c::insert: T** too large");
365 *TopPtr++ = old_mid_node;
384 str_t check()
const {
387 if(Magic != LIST_MAGIC)
388 return "wrong magic number";
391 str_t msg = rel_c::check();
402 if(LeafFree >= PAGE_SIZE(T))
404 if(MidFree >= PAGE_SIZE(T*))
406 if(TopFree >= PAGE_SIZE(T**))
410 if(LeafNode == LIST_LEAF_NULL && LeafFree != 0)
411 CHECK_ERR(
"LeafNode is null, but LeafFree != 0");
412 if(MidNode == LIST_MID_NULL && MidFree != 0)
413 CHECK_ERR(
"MidNode is null, but MidFree != 0");
414 if(TopNode == LIST_TOP_NULL && TopFree != 0)
415 CHECK_ERR(
"TopNode is null, but TopFree != 0");
418 if(LeafNode == LIST_LEAF_NULL && LeafPtr != LIST_LEAF_NULL)
419 CHECK_ERR(
"LeafNode is null, but LeafPtr is not");
420 if(LeafNode != LIST_LEAF_NULL && LeafPtr == LIST_LEAF_NULL)
421 CHECK_ERR(
"LeafNode is not null, but LeafPtr is null");
422 if(MidNode == LIST_MID_NULL && MidPtr != LIST_MID_NULL)
423 CHECK_ERR(
"MidNode is null, but MidPtr is not");
424 if(MidNode != LIST_MID_NULL && MidPtr == LIST_MID_NULL)
425 CHECK_ERR(
"MidNode is not null, but MidPtr is null");
426 if(TopNode == LIST_TOP_NULL && TopPtr != LIST_TOP_NULL)
427 CHECK_ERR(
"TopNode is null, but TopPtr is not");
428 if(TopNode != LIST_TOP_NULL && TopPtr == LIST_TOP_NULL)
429 CHECK_ERR(
"TopNode is not null, but TopPtr is null");
432 if(LeafNode != LIST_LEAF_NULL &&
433 LeafFree != PAGE_SIZE(T) - (LeafPtr-LeafNode))
434 CHECK_ERR(
"LeafFree and LeafPtr are inconsistent");
435 if(MidNode != LIST_MID_NULL &&
436 MidFree != PAGE_SIZE(T*) - (MidPtr-MidNode))
437 CHECK_ERR(
"MidFree and MidPtr are inconsistent");
438 if(TopNode != LIST_TOP_NULL &&
439 TopFree != PAGE_SIZE(T**) - (TopPtr-TopNode))
440 CHECK_ERR(
"TopFree and TopPtr are inconsistent");
447 if(LeafNode != LIST_LEAF_NULL)
449 if(MidNode != LIST_MID_NULL)
451 if(TopNode != LIST_TOP_NULL)
461 if(NumRows > PAGE_SIZE(T))
463 "Height 1 - NumRows too large");
464 if(LeafNode == LIST_LEAF_NULL)
466 if(MidNode != LIST_MID_NULL)
468 if(TopNode != LIST_TOP_NULL)
476 if(NumRows > PAGE_SIZE(T) * PAGE_SIZE(T*))
478 "Height 2 - NumRows too large");
479 if(LeafNode == LIST_LEAF_NULL)
481 if(MidNode == LIST_MID_NULL)
483 if(TopNode != LIST_TOP_NULL)
489 if(NumRows > PAGE_SIZE(T) * PAGE_SIZE(T*)
492 "Height 3 - NumRows too large");
493 if(LeafNode == LIST_LEAF_NULL)
495 if(MidNode == LIST_MID_NULL)
497 if(TopNode == LIST_TOP_NULL)
525 headline =
"Relation/Sequence";
#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_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
static void list_capacity_limit(str_t name, int curr_length)
Definition: err.cpp:204
#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