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

📄 cursor.cpp

📁 fastdb-2.92的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//-< CURSOR.CPP >----------------------------------------------------*--------*// FastDB                    Version 1.0         (c) 1999  GARRET    *     ?  *// (Main Memory Database Management System)                          *   /\|  *//                                                                   *  /  \  *//                          Created:     20-Nov-98    K.A. Knizhnik  * / [] \ *//                          Last update: 21-Dec-98    K.A. Knizhnik  * GARRET *//-------------------------------------------------------------------*--------*// Table cursor//-------------------------------------------------------------------*--------*#define INSIDE_FASTDB#include "fastdb.h"#include "compiler.h"#include "hashtab.h"#include "ttree.h"#include <ctype.h>dbSelection::segment*  dbSelection::createNewSegment(dbSelection::segment* after){    return new segment(after);}inline void dbSelection::reset(){    for (segment *next, *seg = first; seg != NULL; seg = next) {         next = seg->next;        delete seg;    }    first = last = curr = NULL;    nRows = 0;    pos = 0;}void dbSelection::reverse() {    segment *next, *seg;    for (seg = first; seg != NULL; seg = next) {         next = seg->next;        seg->next = seg->prev;        seg->prev = next;        for (int l = 0, r = seg->nRows-1; l < r; l++, r--) {             oid_t oid = seg->rows[l];            seg->rows[l] = seg->rows[r];            seg->rows[r] = oid;        }    }    seg = first;    first = last;    last = seg;}void dbSelection::toArray(oid_t* oids) const{    for (segment *seg = first; seg != NULL; seg = seg->next) {         for (int i = 0, n = seg->nRows; i < n; i++) {            *oids++ = seg->rows[i];        }    }}int dbSelection::compare(dbRecord* a, dbRecord* b, dbOrderByNode* order){    char* p = (char*)a;    char* q = (char*)b;    int diff = 0;    do {         if (order->expr != NULL) {             dbDatabase* db = order->table->db;            dbInheritedAttribute   iattr1;            dbInheritedAttribute   iattr2;            dbSynthesizedAttribute sattr1;            dbSynthesizedAttribute sattr2;            iattr1.db = iattr2.db = db;            iattr1.table = iattr2.table = (dbTable*)db->getRow(order->table->tableId);            iattr1.record = sattr1.base = (byte*)p;            iattr2.record = sattr2.base = (byte*)q;            db->execute(order->expr, iattr1, sattr1);            db->execute(order->expr, iattr2, sattr2);            switch (order->expr->type) {               case tpInteger:                diff = sattr1.ivalue < sattr1.ivalue ? -1 : sattr1.ivalue == sattr1.ivalue ? 0 : 1;                break;              case tpReal:                diff = sattr1.fvalue < sattr1.fvalue ? -1 : sattr1.fvalue == sattr1.fvalue ? 0 : 1;                break;              case tpBoolean:                diff = sattr1.bvalue != 0 ? sattr2.bvalue != 0 ? 0 : 1 : sattr2.bvalue != 0 ? -1 : 0;                break;              case tpString:#ifdef USE_LOCALE_SETTINGS                diff = strcoll((char*)sattr1.array.base, (char*)sattr2.array.base); #else                diff = strcmp((char*)sattr1.array.base, (char*)sattr2.array.base);#endif                break;              case tpReference:                diff = sattr1.oid < sattr1.oid ? -1 : sattr1.oid == sattr1.oid ? 0 : 1;                break;              default:                assert(false);            }        } else {             int offs = order->field->dbsOffs;            switch (order->field->type) {               case dbField::tpBool:                diff = *(bool*)(p + offs) - *(bool*)(q + offs);                break;              case dbField::tpInt1:                diff = *(int1*)(p + offs) - *(int1*)(q + offs);                break;              case dbField::tpInt2:                diff = *(int2*)(p + offs) - *(int2*)(q + offs);                break;              case dbField::tpInt4:              case dbField::tpArray:                diff = *(int4*)(p + offs) < *(int4*)(q + offs) ? -1                     : *(int4*)(p + offs) == *(int4*)(q + offs) ? 0 : 1;                break;              case dbField::tpInt8:                diff = *(db_int8*)(p + offs) < *(db_int8*)(q + offs) ? -1 :                    *(db_int8*)(p + offs) == *(db_int8*)(q + offs) ? 0 : 1;                break;              case dbField::tpReference:                diff = *(oid_t*)(p + offs) < *(oid_t*)(q + offs) ? -1 :                    *(oid_t*)(p + offs) == *(oid_t*)(q + offs) ? 0 : 1;                break;              case dbField::tpReal4:                diff = *(real4*)(p + offs) < *(real4*)(q + offs) ? -1 :                    *(real4*)(p + offs) == *(real4*)(q + offs) ? 0 : 1;                break;              case dbField::tpReal8:                diff = *(real8*)(p + offs) < *(real8*)(q + offs) ? -1 :                    *(real8*)(p + offs) == *(real8*)(q + offs) ? 0 : 1;                break;              case dbField::tpString:#ifdef USE_LOCALE_SETTINGS                diff = strcoll(p + ((dbVarying*)(p + offs))->offs,                                q + ((dbVarying*)(q + offs))->offs);#else                diff = strcmp(p + ((dbVarying*)(p + offs))->offs,                               q + ((dbVarying*)(q + offs))->offs);#endif                break;              case dbField::tpRawBinary:                diff = order->field->comparator(p + offs, q + offs, order->field->dbsSize);                break;              default:                assert(false);            }        }        if (!order->ascent) {             diff = -diff;        }    } while (diff == 0 && (order = order->next) != NULL);    return diff;}int dbSelection::compare(oid_t a, oid_t b, dbOrderByNode* order){    dbDatabase* db = order->table->db;    return compare(db->getRow(a), db->getRow(b), order);}#ifdef USE_HEAP_SORT#define ELEM(i)   index[(i-1)/quantum]->rows[(i-1)%quantum]#define ROW(i)    db->getRow(ELEM(i))#define SWAP(i,j) temp = ELEM(i), ELEM(i) = ELEM(j), ELEM(j) = tempvoid dbSelection::sort(dbDatabase* db, dbOrderByNode* order){    size_t i, j, k, n = nRows;    oid_t temp;    if (n <= 1) {         return;    }    TRACE_MSG(("Sort %d records\n", n));    segment** index = new segment*[(n + quantum - 1) / quantum];    segment* seg = first;    for (i = 0; seg != NULL; seg = seg->next) {         index[i++] = seg;    }    for (i = n/2, j = i; i >= 1; i--) {         k = i;        oid_t topId = ELEM(k);        dbRecord* top = db->getRow(topId);        do {             if (k*2 == n || compare(ROW(k*2), ROW(k*2+1), order) > 0) {                 if (compare(top, ROW(k*2), order) >= 0) {                    break;                }                ELEM(k) = ELEM(k*2);                k = k*2;            } else {                 if (compare(top, ROW(k*2+1), order) >= 0) {                    break;                }                ELEM(k) = ELEM(k*2+1);                k = k*2+1;            }        } while (k <= j);        ELEM(k) = topId;     }    for (i = n; i >= 2; i--) {         SWAP(1, i);        oid_t topId = ELEM(1);        dbRecord* top = db->getRow(topId);        for (k = 1, j = (i-1)/2; k <= j;) {             if (k*2 == i-1 || compare(ROW(k*2), ROW(k*2+1), order) > 0) {                 if (compare(top, ROW(k*2), order) >= 0) {                    break;                }                ELEM(k) = ELEM(k*2);                k = k*2;            } else {                 if (compare(top, ROW(k*2+1), order) >= 0) {                    break;                }                ELEM(k) = ELEM(k*2+1);                k = k*2+1;            }        }         ELEM(k) = topId;     }    delete[] index;}#elsestruct dbSortContext {    dbOrderByNode* order;};static dbThreadContext<dbSortContext> sortThreadContext;#ifdef USE_STDLIB_QSORTstatic int compareRecords(void const* a, void const* b){    dbSortContext* ctx = sortThreadContext.get();    return dbSelection::compare(*(oid_t*)a, *(oid_t*)b, ctx->order);}void dbSelection::sort(dbDatabase* db, dbOrderByNode* order){    size_t n = nRows;    if (n <= 1) {         return;    }    TRACE_MSG(("Sort %d records\n", n));    oid_t* oids = new oid_t[n];    toArray(oids);    dbSortContext ctx;    ctx.order = order;    sortThreadContext.set(&ctx);        qsort(oids, n, sizeof(oid_t), &compareRecords);    oid_t* p = oids;    for (segment *seg = first; seg != NULL; seg = seg->next) {         for (int i = 0, n = seg->nRows; i < n; i++) {            seg->rows[i] = *p++;        }    }}#else#include "iqsort.h"struct ObjectRef {    oid_t oid;    bool operator > (ObjectRef& ref) {         return compare(this, &ref) > 0;    }    bool operator < (ObjectRef& ref) {         return compare(this, &ref) < 0;    }    bool operator >= (ObjectRef& ref) {         return compare(this, &ref) >= 0;    }    bool operator <= (ObjectRef& ref) {         return compare(this, &ref) <= 0;    }    bool operator == (ObjectRef& ref) {         return compare(this, &ref) == 0;    }    bool operator != (ObjectRef& ref) {         return compare(this, &ref) != 0;    }    static int compare(ObjectRef* a, ObjectRef* b) {         dbSortContext* ctx = sortThreadContext.get();        return dbSelection::compare(a->oid, b->oid, ctx->order);    }};void dbSelection::sort(dbDatabase* db, dbOrderByNode* order){    size_t n = nRows;    if (n <= 1) {         return;    }    TRACE_MSG(("Sort %d records\n", n));    ObjectRef* refs = new ObjectRef[n];    segment *seg;    int k = 0;    for (seg = first; seg != NULL; seg = seg->next) {         for (int i = 0, n = seg->nRows; i < n; i++) {            refs[k++].oid = seg->rows[i];        }    }    dbSortContext ctx;    ctx.order = order;    sortThreadContext.set(&ctx);        iqsort(refs, n);    k = 0;    for (seg = first; seg != NULL; seg = seg->next) {         for (int i = 0, n = seg->nRows; i < n; i++) {            seg->rows[i] = refs[k++].oid;        }    }    delete[] refs;}#endif#endifvoid dbAnyCursor::checkForDuplicates() {     if (!eliminateDuplicates && limit > 1) {         eliminateDuplicates = true;        size_t size = (db->currIndexSize + 31) / 32;        if (size > bitmapSize) {             delete[] bitmap;            bitmap = new int4[size];            bitmapSize = size;        }        memset(bitmap, 0, size*4);    }}oid_t* dbAnyCursor::toArrayOfOid(oid_t* arr) const{     if (arr == NULL) {         arr = new oid_t[selection.nRows];    }    if (allRecords) {         oid_t* oids = arr;        for (oid_t oid = firstId; oid != 0; oid = db->getRow(oid)->next) {             *oids++ = oid;        }    } else {         selection.toArray(arr);    }    return arr;}void dbAnyCursor::setCurrent(dbAnyReference const& ref) {     removed = false;    assert(ref.oid != 0);    reset();    db->beginTransaction(type == dbCursorForUpdate                          ? dbDatabase::dbExclusiveLock : dbDatabase::dbSharedLock);    db->threadContext.get()->cursors.link(this);    currId = ref.oid;    add(currId);    if (prefetch) {         fetch();    }}int dbAnyCursor::selectByKey(char const* key, void const* value){    dbFieldDescriptor* field = table->find(key);    assert(field != NULL);    assert(field->hashTable != 0 || 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 = sc.lastKey = (char*)value;    sc.firstKeyInclusion = sc.lastKeyInclusion = true;    sc.comparator = field->comparator;    sc.sizeofType = field->dbsSize;    sc.type = field->type;

⌨️ 快捷键说明

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