⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cursor.cpp

📁 最新版本!fastdb是高效的内存数据库系统
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    }
    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.probes = 0;
    sc.offs = field->dbsOffs;
    sc.cursor = this;
    sc.condition = NULL;
    sc.prefixLength = 0;
    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;
    lastRecordWasDeleted = false;
    if (removedId == 0) { 
        db->handleError(dbDatabase::NullReferenceError, "Attempt to remove unexisted record");
    } 
    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 { 
            lastRecordWasDeleted = true;
            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 { 
                    lastRecordWasDeleted = true;
                    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;
        }
    }
    byte* saveRecord = record;
    record = NULL;
    db->remove(table, removedId);
    record = saveRecord;
    removed = true;
    if (currId != 0 && prefetch) {
        fetch();        
    }
}


void dbAnyCursor::removeAllSelected()
{
    assert(type == dbCursorForUpdate);
    byte* saveRecord = record;
    record = NULL;
    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;
    }
    record = saveRecord;
}


bool dbAnyCursor::hasNext() const
{ 
    return allRecords
        ? currId != 0 && db->getRow(currId)->next != 0
        : selection.curr != NULL && (selection.pos+1 < selection.curr->nRows || selection.curr->next != NULL);
}

byte* dbAnyCursor::fetchNext()
{
    if (!removed) {
        if (gotoNext()) {
            fetch();
            return record;
        }
    } else { 
        removed = false; 
        if (currId != 0 && !lastRecordWasDeleted) { 
            if (!prefetch) { 
                fetch();
            }
            return record;
        }
    }
    return NULL;
}

byte* dbAnyCursor::fetchPrev()
{
    if (removed) {
        removed = false; 
        if (lastRecordWasDeleted) { 
            if (currId != 0) { 
                if (!prefetch) { 
                    fetch();
                }
                return record;
            }
            return NULL;
        }
    }
    if (gotoPrev()) {
        fetch();
        return record;
    }
    return NULL;
}

bool dbAnyCursor::moveNext() 
{
    if (!removed) { 
        return gotoNext(); 
    } else {
        removed = false;
        return !lastRecordWasDeleted;
    }
}
    
bool dbAnyCursor::movePrev() 
{
    if (!removed) { 
        return gotoPrev(); 
    } else {
        removed = false;
        return lastRecordWasDeleted ? (currId != 0) : gotoPrev();
    }
}
    

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 100

bool 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;
}

END_FASTDB_NAMESPACE





⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -