📄 cursor.cpp
字号:
sc.type = field->type; if (field->hashTable != 0) { dbHashTable::find(db, field->hashTable, sc); } else { dbTtree::find(db, field->tTree, sc); } if (gotoFirst() && prefetch) { fetch(); } return selection.nRows;}int dbAnyCursor::seek(oid_t oid){ int pos = 0; if (gotoFirst()) { do { if (currId == oid) { if (prefetch) { fetch(); } return pos; } pos += 1; } while (gotoNext()); } return -1;}bool dbAnyCursor::skip(int n) { while (n > 0) { if (!gotoNext()) { return false; } n -= 1; } while (n < 0) { if (!gotoPrev()) { return false; } n += 1; } if (prefetch) { fetch(); } return true;}int dbAnyCursor::selectByKeyRange(char const* key, void const* minValue, void const* maxValue){ dbFieldDescriptor* field = table->find(key); assert(field != NULL); assert(field->tTree != 0); reset(); db->beginTransaction(type == dbCursorForUpdate ? dbDatabase::dbExclusiveLock : dbDatabase::dbSharedLock); db->threadContext.get()->cursors.link(this); dbSearchContext sc; sc.db = db; sc.offs = field->dbsOffs; sc.cursor = this; sc.condition = NULL; sc.firstKey = (char*)minValue; sc.lastKey = (char*)maxValue; sc.firstKeyInclusion = sc.lastKeyInclusion = true; sc.comparator = field->comparator; sc.sizeofType = field->dbsSize; sc.type = field->type; dbTtree::find(db, field->tTree, sc); if (gotoFirst() && prefetch) { fetch(); } return selection.nRows;}void dbAnyCursor::remove(){ oid_t removedId = currId; assert(type == dbCursorForUpdate && removedId != 0); if (allRecords) { dbRecord* rec = db->getRow(removedId); oid_t nextId = rec->next; oid_t prevId = rec->prev; if (nextId != 0) { if (currId == firstId) { firstId = currId = nextId; } else { currId = nextId; } } else { if (removedId == firstId) { firstId = lastId = currId = 0; } else { lastId = currId = prevId; } } } else { if (selection.curr != NULL) { if (--selection.curr->nRows == 0 || selection.pos == selection.curr->nRows) { dbSelection::segment* next = selection.curr->next; dbSelection::segment* prev = selection.curr->prev; if (selection.curr->nRows == 0) { if (prev != NULL) { prev->next = next; } else { selection.first = next; } if (next != NULL) { next->prev = prev; } else { selection.last = prev; } delete selection.curr; } if (next != NULL) { currId = next->rows[0]; selection.curr = next; selection.pos = 0; } else { if ((selection.curr = selection.last) != NULL) { selection.pos = selection.curr->nRows-1; currId = selection.curr->rows[selection.pos]; } else { currId = 0; } } } else { memcpy(selection.curr->rows + selection.pos, selection.curr->rows + selection.pos + 1, (selection.curr->nRows - selection.pos) *sizeof(oid_t)); currId = selection.curr->rows[selection.pos]; } } else { currId = 0; } } db->remove(table, removedId); removed = true; if (currId != 0) { fetch(); }}void dbAnyCursor::removeAllSelected(){ assert(type == dbCursorForUpdate); if (allRecords) { removeAll(); } else if (selection.first != NULL) { dbSelection::segment* curr; for (curr = selection.first; curr != NULL; curr = curr->next) { for (int i = 0, n = curr->nRows; i < n; i++) { db->remove(table, curr->rows[i]); } } reset(); } else if (currId != 0) { db->remove(table, currId); currId = 0; }}bool dbAnyCursor::gotoNext() { removed = false; if (allRecords) { if (currId != 0) { oid_t next = db->getRow(currId)->next; if (next != 0) { currId = next; return true; } } } else if (selection.curr != NULL) { if (++selection.pos == selection.curr->nRows) { if (selection.curr->next == NULL) { selection.pos -= 1; return false; } selection.pos = 0; selection.curr = selection.curr->next; } currId = selection.curr->rows[selection.pos]; return true; } return false;}bool dbAnyCursor::isLast() const{ if (allRecords) { if (currId != 0) { return db->getRow(currId)->next == 0; } } else if (selection.curr != NULL) { return selection.pos+1 == selection.curr->nRows && selection.curr->next == NULL; } return false;}bool dbAnyCursor::isFirst() const{ if (allRecords) { if (currId != 0) { return db->getRow(currId)->prev == 0; } } else if (selection.curr != NULL) { return selection.pos == 0 && selection.curr->prev == NULL; } return false;}bool dbAnyCursor::gotoPrev(){ removed = false; if (allRecords) { if (currId != 0) { oid_t prev = db->getRow(currId)->prev; if (prev != 0) { currId = prev; return true; } } } else if (selection.curr != NULL) { if (selection.pos == 0) { if (selection.curr->prev == NULL) { return false; } selection.curr = selection.curr->prev; selection.pos = selection.curr->nRows; } currId = selection.curr->rows[--selection.pos]; return true; } return false;}bool dbAnyCursor::gotoFirst(){ removed = false; if (allRecords) { currId = firstId; return (currId != 0); } else { selection.curr = selection.first; selection.pos = 0; if (selection.curr == NULL) { return (currId != 0); } else { currId = selection.curr->rows[0]; return true; } }}bool dbAnyCursor::gotoLast(){ removed = false; if (allRecords) { currId = lastId; return (currId != 0); } else { selection.curr = selection.last; if (selection.curr == NULL) { return (currId != 0); } else { selection.pos = selection.curr->nRows-1; currId = selection.curr->rows[selection.pos]; return true; } }}#define BUILD_BITMAP_THRESHOLD 100bool dbAnyCursor::isInSelection(oid_t oid) { dbSelection::segment* curr; if (eliminateDuplicates) { return isMarked(oid); } else if (selection.nRows > BUILD_BITMAP_THRESHOLD) { checkForDuplicates(); for (curr = selection.first; curr != NULL; curr = curr->next) { for (int i = 0, n = curr->nRows; i < n; i++) { oid_t o = curr->rows[i]; bitmap[o >> 5] |= 1 << (o & 31); } } return isMarked(oid); } else { for (curr = selection.first; curr != NULL; curr = curr->next) { for (int i = 0, n = curr->nRows; i < n; i++) { if (curr->rows[i] == oid) { return true; } } } return false; }}void dbAnyCursor::reset(){ if (db == NULL) { db = table->db; assert(((void)"cursor associated with online database table", table->tableId != 0)); } else if (table->db != db) { table = db->lookupTable(table); } unlink(); selection.reset(); eliminateDuplicates = false; allRecords = false; currId = 0; removed = false;}void dbAnyCursor::freeze(){ unlink(); }void dbAnyCursor::unfreeze(){ db->beginTransaction(type == dbCursorForUpdate ? dbDatabase::dbExclusiveLock : dbDatabase::dbSharedLock); db->threadContext.get()->cursors.link(this); if (currId != 0 && prefetch) { fetch(); }}dbAnyCursor::~dbAnyCursor() { selection.reset(); delete[] bitmap;}void dbParallelQueryContext::search(int i){ int nThreads = db->parThreads; oid_t oid = firstRow; int j; for (j = i; --j >= 0;) { oid = db->getRow(oid)->next; } while (oid != 0) { if (db->evaluate(query->tree, oid, table, cursor)) { selection[i].add(oid); } oid = db->getRow(oid)->next; for (j = nThreads; --j > 0 && oid != 0;) { oid = db->getRow(oid)->next; } } if (query->order != NULL) { selection[i].sort(db, query->order); }}char* strupper(char* s){ byte* p = (byte*)s; while (*p != '\0') { *p = toupper(*p); p += 1; } return s;}char* strlower(char* s){ byte* p = (byte*)s; while (*p != '\0') { *p = (byte)tolower(*p); p += 1; } return s;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -