📄 ttree.cpp
字号:
//-< TTREE.CPP >-----------------------------------------------------*--------*// FastDB Version 1.0 (c) 1999 GARRET * ? *// (Main Memory Database Management System) * /\| *// * / \ *// Created: 20-Nov-98 K.A. Knizhnik * / [] \ *// Last update: 6-Jan-99 K.A. Knizhnik * GARRET *//-------------------------------------------------------------------*--------*// T-Tree implementation//-------------------------------------------------------------------*--------*#define INSIDE_FASTDB#include "fastdb.h"#include "ttree.h"#ifdef USE_LOCALE_SETTINGS#ifdef IGNORE_CASE#define strcmp(x, y) stricoll(x, y)#define strncmp(x, y, n) strincmp(x, y, n)#else#define strcmp(x, y) strcoll(x, y)#endif#else#ifdef IGNORE_CASE#define strcmp(x, y) stricmp(x, y)#define strncmp(x, y, n) strincmp(x, y, n)#endif#endifinline int keycmp(void* p, void* q, int type, int sizeofType, dbUDTComparator comparator){ switch (type) { case dbField::tpBool: return *(bool*)p - *(bool*)q; case dbField::tpInt1: return *(int1*)p - *(int1*)q; case dbField::tpInt2: return *(int2*)p - *(int2*)q; case dbField::tpInt4: return *(int4*)p < *(int4*)q ? -1 : *(int4*)p == *(int4*)q ? 0 : 1; case dbField::tpInt8: return *(db_int8*)p < *(db_int8*)q ? -1 : *(db_int8*)p == *(db_int8*)q ? 0 : 1; case dbField::tpReference: return *(oid_t*)p < *(oid_t*)q ? -1 : *(oid_t*)p == *(oid_t*)q ? 0 : 1; case dbField::tpReal4: return *(real4*)p < *(real4*)q ? -1 : *(real4*)p == *(real4*)q ? 0 : 1; case dbField::tpReal8: return *(real8*)p < *(real8*)q ? -1 : *(real8*)p == *(real8*)q ? 0 : 1; case dbField::tpRawBinary: return comparator(p, q, sizeofType); default: assert(false); return 0; }}void dbTtree::find(dbDatabase* db, oid_t treeId, dbSearchContext& sc){ oid_t rootId = ((dbTtree*)db->get(treeId))->root; if (rootId != 0) { ((dbTtreeNode*)db->get(rootId))->find(db, sc); }}void dbTtree::prefixSearch(dbDatabase* db, oid_t treeId, dbSearchContext& sc){ oid_t rootId = ((dbTtree*)db->get(treeId))->root; if (rootId != 0) { ((dbTtreeNode*)db->get(rootId))->prefixSearch(db, sc); }}oid_t dbTtree::allocate(dbDatabase* db){ oid_t oid = db->allocateObject(dbTtreeMarker); dbTtree* tree = (dbTtree*)db->get(oid); tree->root = 0; return oid;}void dbTtree::insert(dbDatabase* db, oid_t treeId, oid_t recordId, int type, int sizeofType, dbUDTComparator comparator, int offs){ oid_t rootId = ((dbTtree*)db->get(treeId))->root; if (rootId == 0) { oid_t nodeId = dbTtreeNode::allocate(db, recordId); ((dbTtree*)db->put(treeId))->root = nodeId; } else { byte* rec = (byte*)db->getRow(recordId); byte* key = rec + offs; if (type == dbField::tpString) { key = rec + ((dbVarying*)key)->offs; } oid_t nodeId = rootId; dbTtreeNode::insert(db, nodeId, recordId, key, type, sizeofType, comparator, offs); if (rootId != nodeId) { ((dbTtree*)db->put(treeId))->root = nodeId; } }}void dbTtree::remove(dbDatabase* db, oid_t treeId, oid_t recordId, int type, int sizeofType, dbUDTComparator comparator, int offs){ oid_t rootId = ((dbTtree*)db->get(treeId))->root; byte* rec = (byte*)db->getRow(recordId); byte* key = rec + offs; if (type == dbField::tpString) { key = rec + ((dbVarying*)key)->offs; } oid_t nodeId = rootId; int h = dbTtreeNode::remove(db, nodeId, recordId, key, type, sizeofType, comparator, offs); assert(h >= 0); if (nodeId != rootId) { ((dbTtree*)db->put(treeId))->root = nodeId; }} void dbTtree::purge(dbDatabase* db, oid_t treeId) { oid_t rootId = ((dbTtree*)db->get(treeId))->root; dbTtreeNode::purge(db, rootId); ((dbTtree*)db->put(treeId))->root = 0;} void dbTtree::drop(dbDatabase* db, oid_t treeId) { purge(db, treeId); db->freeObject(treeId);} void dbTtree::traverseForward(dbDatabase* db, oid_t treeId, dbAnyCursor* cursor){ oid_t rootId = ((dbTtree*)db->get(treeId))->root; if (rootId != 0) { ((dbTtreeNode*)db->get(rootId))->traverseForward(db, cursor); }}void dbTtree::traverseBackward(dbDatabase* db, oid_t treeId, dbAnyCursor* cursor){ oid_t rootId = ((dbTtree*)db->get(treeId))->root; if (rootId != 0) { ((dbTtreeNode*)db->get(rootId))->traverseBackward(db, cursor); }}void dbTtree::traverseForward(dbDatabase* db, oid_t treeId, dbAnyCursor* cursor, dbExprNode* condition){ oid_t rootId = ((dbTtree*)db->get(treeId))->root; if (rootId != 0) { ((dbTtreeNode*)db->get(rootId))->traverseForward(db, cursor,condition); }}void dbTtree::traverseBackward(dbDatabase* db, oid_t treeId, dbAnyCursor* cursor, dbExprNode* condition){ oid_t rootId = ((dbTtree*)db->get(treeId))->root; if (rootId != 0) { ((dbTtreeNode*)db->get(rootId))->traverseBackward(db,cursor,condition); }}static inline int prefcmp(char const* key, char const* prefix) { return strncmp(key, prefix, strlen(prefix));}bool dbTtreeNode::prefixSearch(dbDatabase* db, dbSearchContext& sc){ char* rec; int l, r, m, n = nItems; sc.probes += 1; dbTable* table = (dbTable*)db->getRow(sc.cursor->table->tableId); assert (sc.type == dbField::tpString); rec = (char*)db->getRow(item[0]); char* key = sc.firstKey; if (prefcmp(key, rec+((dbVarying*)(rec+sc.offs))->offs) > 0) { rec = (char*)db->getRow(item[n-1]); if (prefcmp(key, rec+((dbVarying*)(rec+sc.offs))->offs) > 0) { if (right != 0) { return ((dbTtreeNode*)db->get(right))->find(db, sc); } return true; } for (l = 0, r = n; l < r;) { m = (l + r) >> 1; rec = (char*)db->getRow(item[m]); if (prefcmp(sc.firstKey, rec + ((dbVarying*)(rec+sc.offs))->offs) > 0) { l = m+1; } else { r = m; } } while (r < n) { rec = (char*)db->getRow(item[r]); if (prefcmp(key, rec + ((dbVarying*)(rec+sc.offs))->offs) < 0) { return false; } if (!sc.condition || db->evaluate(sc.condition, item[r], table, sc.cursor)) { if (!sc.cursor->add(item[r])) { return false; } } r += 1; } if (right != 0) { return ((dbTtreeNode*)db->get(right))->find(db, sc); } return true; } if (left != 0) { if (!((dbTtreeNode*)db->get(left))->find(db, sc)) { return false; } } for (l = 0; l < n; l++) { rec = (char*)db->getRow(item[l]); if (prefcmp(key, rec + ((dbVarying*)(rec+sc.offs))->offs) < 0) { return false; } if (!sc.condition || db->evaluate(sc.condition, item[l], table, sc.cursor)) { if (!sc.cursor->add(item[l])) { return false; } } } if (right != 0) { return ((dbTtreeNode*)db->get(right))->find(db, sc); } return false;}bool dbTtreeNode::find(dbDatabase* db, dbSearchContext& sc){ char* rec; int diff; int l, r, m, n = nItems; sc.probes += 1; dbTable* table = (dbTable*)db->getRow(sc.cursor->table->tableId); if (sc.type == dbField::tpString) { if (sc.firstKey != NULL) { rec = (char*)db->getRow(item[0]); diff = strcmp(sc.firstKey, rec+((dbVarying*)(rec+sc.offs))->offs); if (diff >= sc.firstKeyInclusion) { rec = (char*)db->getRow(item[n-1]); diff = strcmp(sc.firstKey, rec+((dbVarying*)(rec+sc.offs))->offs); if (diff >= sc.firstKeyInclusion) { if (right != 0) { return ((dbTtreeNode*)db->get(right))->find(db, sc); } return true; } for (l = 0, r = n; l < r;) { m = (l + r) >> 1; rec = (char*)db->getRow(item[m]); diff = strcmp(sc.firstKey, rec + ((dbVarying*)(rec+sc.offs))->offs); if (diff >= sc.firstKeyInclusion) { l = m+1; } else { r = m; } } while (r < n) { rec = (char*)db->getRow(item[r]); if (sc.lastKey != NULL && strcmp(rec + ((dbVarying*)(rec+sc.offs))->offs, sc.lastKey) >= sc.lastKeyInclusion) { return false; } if (!sc.condition || db->evaluate(sc.condition, item[r], table, sc.cursor)) { if (!sc.cursor->add(item[r])) { return false; } } r += 1; } if (right != 0) { return ((dbTtreeNode*)db->get(right))->find(db, sc);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -