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

📄 class.cpp

📁 最新版本!fastdb是高效的内存数据库系统
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    for (dbFieldDescriptor* fd = firstField; fd != NULL; fd = fd->nextField) { 
        if (strcmp(fd->longName, (char*)field + field->name.offs) != 0 
            || (!fd->refTable && *((char*)field+field->tableName.offs) != '\0')
            || (fd->refTable && strcmp((char*)field + field->tableName.offs,
                                       fd->refTable->name) != 0)
            || (fd->inverseRefName == NULL 
                && *((char*)field + field->inverse.offs) != '\0')
            || (fd->inverseRefName != NULL
                && strcmp((char*)field + field->inverse.offs,
                          fd->inverseRefName) != 0)
            || fd->dbsOffs != field->offset
#ifndef OLD_FIELD_DESCRIPTOR_FORMAT
            || fd->indexType != (int)field->flags
#endif
            || fd->type != field->type)
        {
            return false;
        }
        fd->tTree = field->tTree;
        fd->hashTable = field->hashTable;
        field += 1;
    }
    return true;
}


dbTableDescriptor::dbTableDescriptor(dbTable* table)
{
    cloneOf = NULL;
    isStatic = false;
    name = (char*)table + table->name.offs;
    dbSymbolTable::add(name, tkn_ident, true);
    nextFieldLink = &firstField;
    hashedFields = NULL;
    indexedFields = NULL;
    inverseFields = NULL;
    nFields = 0;
    nColumns = 0;
    fixedSize = table->fixedSize;
    int attr = 0;
    appSize = 0;
    columns = buildFieldsList(table, "", 0, attr);
    *nextFieldLink = NULL;
    db = NULL;
    fixedDatabase = false;
    tableId = 0;
#ifdef AUTOINCREMENT_SUPPORT
    autoincrementCount = table->count;
#endif
}

struct _abool { char n; bool v; };
struct _aint1 { char n; int1 v; };
struct _aint2 { char n; int2 v; };
struct _aint4 { char n; int4 v; };
struct _aint8 { char n; db_int8 v; };
struct _areal4 { char n; real4 v; };
struct _areal8 { char n; real8 v; };
struct _astring { char n; char *v; };
struct _arawbinary { char n; char v[1]; };
struct _areference { char n; oid_t v; };
struct _aarray { char n; void* v; };
struct _arectangle { char n; rectangle v; };

#define COMPUTE_ALIGNED_SIZE(type) offsetof(_a##type, v)


dbFieldDescriptor* dbTableDescriptor::buildFieldsList(dbTable*    table, 
                                                      char const* prefix,
                                                      int         prefixLen,
                                                      int&        attr)
{
    dbFieldDescriptor* components = NULL;
    dbField* field = (dbField*)((char*)table+table->fields.offs) + nFields;
        
    while (nFields < table->fields.size
           && strncmp((char*)field + field->name.offs, prefix, prefixLen) == 0)
    {
        char* longName = (char*)field + field->name.offs;
        char* name = longName + prefixLen;
        if (*name == '.') { 
            name += 1;
        } else if (prefixLen != 0 && *name != '[') { 
            break;
        }
        dbSymbolTable::add(name, tkn_ident, true);      
        dbFieldDescriptor* fd = new dbFieldDescriptor(name);
        fd->dbsOffs = field->offset;
        fd->alignment = fd->dbsSize = field->size;
        fd->longName = new char[strlen(longName)+1];
        strcpy(fd->longName, longName);
        fd->type = fd->appType = field->type;
        fd->indexType = field->flags;
        int appFieldSize, appAlignedFieldSize;
         
        switch (field->type) {
          case dbField::tpBool:
            appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(bool);
            appFieldSize = sizeof(bool);
            break;
          case dbField::tpInt1:
            appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(int1);
            appFieldSize = sizeof(int1);
            break;
          case dbField::tpInt2:
            appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(int2);
            appFieldSize = sizeof(int2);
            break;
          case dbField::tpInt4:
            appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(int4);
            appFieldSize = sizeof(int4);
            break;
          case dbField::tpInt8:
            appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(int8);
            appFieldSize = sizeof(db_int8);
            break;
          case dbField::tpReal4:
            appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(real4);
            appFieldSize = sizeof(real4);
            break;
          case dbField::tpReal8:
            appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(real8);
            appFieldSize = sizeof(real8);
            break;
          case dbField::tpString:
            appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(string);
            appFieldSize = sizeof(char *);
            break;
          case dbField::tpRawBinary:
            appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(rawbinary);
            appFieldSize = field->size;
            break;
          case dbField::tpReference:
            appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(reference);
            appFieldSize = sizeof(dbAnyReference);
            break;
          case dbField::tpArray:
            appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(array);
            appFieldSize = sizeof(dbArray<byte>);
            break;
          case dbField::tpRectangle:
            appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(rectangle);
            appFieldSize = sizeof(rectangle);
            break;
          default:
            appAlignedFieldSize = 1;
            appFieldSize = 0;
        }
        fd->appOffs = appSize = DOALIGN(appSize, appAlignedFieldSize);
        appSize += fd->appSize = appFieldSize;

        if ((fd->hashTable = field->hashTable) != 0) { 
            fd->nextHashedField = hashedFields;
            hashedFields = fd;
        }
        if ((fd->tTree = field->tTree) != 0) { 
            fd->nextIndexedField = indexedFields;
            indexedFields = fd;
        }
        fd->fieldNo = nFields++;
        fd->defTable = this;
        fd->refTable = NULL;
        fd->refTableName = NULL;
        if (field->hashTable != 0) { 
            fd->indexType |= HASHED;
        }
        if (field->tTree != 0) { 
            fd->indexType |= INDEXED;
        }
        if (field->tableName.size > 1) { 
            fd->refTableName = (char*)field + field->tableName.offs;
            dbSymbolTable::add(fd->refTableName, tkn_ident, true);      
        }
        fd->inverseRefName = NULL;
        if (field->inverse.size > 1) { 
            fd->nextInverseField = inverseFields;
            inverseFields = fd;             
            fd->inverseRefName = (char*)field + field->inverse.offs;
            dbSymbolTable::add(fd->inverseRefName, tkn_ident, true);    
        }
        fd->attr = (attr & dbFieldDescriptor::ComponentOfArray) | dbFieldDescriptor::OneToOneMapping;

        *nextFieldLink = fd;
        nextFieldLink = &fd->nextField;

        if (prefixLen == 0) { 
            nColumns += 1;
        }
        if (components == NULL) { 
            components = fd;
        } else { 
            fd->next = components;
            fd->prev = components->prev;
            components->prev->next = fd;
            components->prev = fd;
        }
        if (fd->type == dbField::tpArray || fd->type == dbField::tpString) { 
            attr = (attr | dbFieldDescriptor::HasArrayComponents)
                & ~dbFieldDescriptor::OneToOneMapping;
            fd->attr |= dbFieldDescriptor::ComponentOfArray;
            fd->alignment = 4;
        }
        if (fd->type == dbField::tpArray || fd->type == dbField::tpStructure) {
            int saveAppSize = appSize;
            appSize = 0;
            fd->components = 
                buildFieldsList(table, longName, strlen(longName), fd->attr);
            attr |= fd->attr & dbFieldDescriptor::HasArrayComponents;
            attr &= fd->attr | ~dbFieldDescriptor::OneToOneMapping;
            field = (dbField*)((char*)table + table->fields.offs) + nFields;
            if (fd->type == dbField::tpStructure) {
                size_t alignment = 1;
                dbFieldDescriptor* component = fd->components;
                do { 
                    if (component->alignment > alignment) { 
                        alignment = component->alignment;
                    }
                } while ((component = component->next) != fd->components);
                fd->alignment = alignment;
                fd->appSize = appSize = DOALIGN(appSize, alignment);
                fd->appOffs = saveAppSize = DOALIGN(saveAppSize, alignment);
                appSize += saveAppSize;
            } else { 
                appSize = saveAppSize;
                switch (fd->components->type) { 
                  case dbField::tpString:
                    fd->arrayAllocator = &dbArray<char*>::arrayAllocator;
                    fd->attr &= ~dbFieldDescriptor::OneToOneMapping;
                    break;
                  case dbField::tpBool:
                    fd->arrayAllocator = &dbArray<bool>::arrayAllocator;
                    break;
                  case dbField::tpInt1:
                    fd->arrayAllocator = &dbArray<int1>::arrayAllocator;
                    break;
                  case dbField::tpInt2:
                    fd->arrayAllocator = &dbArray<int2>::arrayAllocator;
                    break;
                  case dbField::tpInt4:
                    fd->arrayAllocator = &dbArray<int4>::arrayAllocator;
                    break;
                  case dbField::tpInt8:
                    fd->arrayAllocator = &dbArray<int8>::arrayAllocator;
                    break;
                  case dbField::tpReal4:
                    fd->arrayAllocator = &dbArray<real4>::arrayAllocator;
                    break;
                  case dbField::tpReal8:
                    fd->arrayAllocator = &dbArray<real8>::arrayAllocator;
                    break;
                  case dbField::tpReference:
                    fd->arrayAllocator = &dbArray<dbAnyReference>::arrayAllocator;
                    break;
                  default:
                    fd->arrayAllocator = &dbAnyArray::arrayAllocator;
                    break;
                }
            }
        } else { 
            if (fd->type == dbField::tpString) { 
                fd->components = new dbFieldDescriptor("[]");
                fd->components->type = fd->components->appType = dbField::tpInt1;
                fd->components->dbsSize = fd->components->appSize = 1;
                fd->components->alignment = 1; 
            }
            field += 1;
        }
    }
    return components;
}


size_t dbTableDescriptor::totalNamesLength()
{
    dbFieldDescriptor* fd;
    size_t len = strlen(name) + 1;
    for (fd = firstField; fd != NULL; fd = fd->nextField) { 
        if (fd->name != NULL) { 
            len += strlen(fd->longName) + 3;
            if (fd->inverseRefName != NULL) { 
                len += strlen(fd->inverseRefName);
            }
            if (fd->refTable != NULL) { 
                len += strlen(fd->refTable->name);
            }
        }
    }
    return len;
}


dbTableDescriptor* dbTableDescriptor::clone() 
{
    return new dbTableDescriptor(name,
                                 DETACHED_TABLE,
                                 appSize,
                                 describeComponentsFunc,
                                 this);
}

dbTableDescriptor::~dbTableDescriptor()
{    
    if (isStatic) {
        unlink();
    }
    dbFieldDescriptor* last = columns->prev;
    while (last->method != NULL) { 
        dbFieldDescriptor* prev = last->prev;
        delete last->method;
        delete last;
        if (last == columns) {
            break;
        }
        last = prev;
    }
    dbFieldDescriptor *field, *nextField;
    for (field = firstField; field != NULL; field = nextField) { 
        nextField = field->nextField;
        delete field;
    }
}


void dbTableDescriptor::cleanup()
{
    delete chainMutex;                               
    chainMutex = NULL;
}


void dbTableDescriptor::storeInDatabase(dbTable* table)
{
    int offs = sizeof(dbTable) + sizeof(dbField)*nFields;
    table->name.offs = offs;
    table->name.size = strlen(name)+1;
    strcpy((char*)table + offs, name);
    offs += table->name.size;
    table->fields.offs = sizeof(dbTable);
    table->fields.size = nFields;
    table->nRows = 0;
    table->nColumns = nColumns;
    table->fixedSize = fixedSize;
    table->firstRow = 0;
    table->lastRow = 0;
#ifdef AUTOINCREMENT_SUPPORT
    if (autoincrementCount < initialAutoincrementCount) { 
        autoincrementCount = initialAutoincrementCount;
    }
    table->count = autoincrementCount;
#endif

    dbFieldDescriptor* fd;
    dbField* field = (dbField*)((char*)table + table->fields.offs);
    offs -= sizeof(dbTable);
    for (fd = firstField; fd != NULL; fd = fd->nextField) { 
        field->name.offs = offs;
        field->name.size = strlen(fd->longName) + 1;
        strcpy((char*)field + offs, fd->longName);
        offs += field->name.size;
        field->tableName.offs = offs;
        if (fd->refTable != NULL) { 
            field->tableName.size = strlen(fd->refTable->name) + 1;
            strcpy((char*)field + offs, fd->refTable->name);
        } else if (fd->refTableName != NULL) { 
            field->tableName.size = strlen(fd->refTableName) + 1;
            strcpy((char*)field + offs, fd->refTableName);
        } else { 
            field->tableName.size = 1;
            *((char*)field + offs) = '\0';
        }
        offs += field->tableName.size;
        
        field->inverse.offs = offs;
        if (fd->inverseRefName != NULL) { 
            field->inverse.size = strlen(fd->inverseRefName) + 1;
            strcpy((char*)field + offs, fd->inverseRefName);
        } else { 
            field->inverse.size = 1;
            *((char*)field + offs) = '\0';
        }
        offs += field->inverse.size;
        
        field->tTree = fd->tTree;
        field->hashTable = fd->hashTable;
        field->type = fd->type;
        field->size = fd->dbsSize;
        field->offset = fd->dbsOffs;
        field->flags = fd->indexType;
        field += 1;
        offs -= sizeof(dbField);
    }
}

void* dbAnyMethodTrampoline::operator new(size_t size EXTRA_DEBUG_NEW_PARAMS)
{
    return dbMalloc(size);
}

void  dbAnyMethodTrampoline::operator delete(void* p EXTRA_DEBUG_NEW_PARAMS)
{
    dbFree(p);
}
        
dbAnyMethodTrampoline::~dbAnyMethodTrampoline() {}

END_FASTDB_NAMESPACE

⌨️ 快捷键说明

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