📄 class.cpp
字号:
//-< CLASS.CPP >-----------------------------------------------------*--------*// FastDB Version 1.0 (c) 1999 GARRET * ? *// (Main Memory Database Management System) * /\| *// * / \ *// Created: 20-Nov-98 K.A. Knizhnik * / [] \ *// Last update: 1-Jan-99 K.A. Knizhnik * GARRET *//-------------------------------------------------------------------*--------*// Metaclass information//-------------------------------------------------------------------*--------*#define INSIDE_FASTDB#include "fastdb.h"#include "compiler.h"#include "symtab.h"#ifndef CHECK_RECORD_SIZE#define CHECK_RECORD_SIZE 1#endifdbTableDescriptor* dbTableDescriptor::chain;void* dbFieldDescriptor::operator new(size_t size){ return new char[size];}void dbFieldDescriptor::operator delete(void* p){ delete[] (char*)p;}dbFieldDescriptor::dbFieldDescriptor(char* name) { next = prev = this; this->name = name; longName = NULL; dbSymbolTable::add(this->name, tkn_ident, FASTDB_CLONE_ANY_IDENTIFIER); appOffs = dbsOffs = 0; defTable = refTable = NULL; refTableName = NULL; components = NULL; inverseRefName = NULL; indexType = 0; method = NULL; attr = OneToOneMapping; tTree = 0; hashTable = 0; comparator = (dbUDTComparator)&memcmp;}dbFieldDescriptor::dbFieldDescriptor(char* fieldName, int offs, int size, int index, char* inverse, dbFieldDescriptor* fieldComponents){ next = prev = this; name = fieldName; longName = NULL; dbSymbolTable::add(name, tkn_ident, FASTDB_CLONE_ANY_IDENTIFIER); appOffs = offs; dbsOffs = 0; alignment = appSize = dbsSize = size; defTable = refTable = NULL; indexType = index; type = appType = dbField::tpStructure; inverseRefName = inverse; if (inverseRefName != NULL) { dbSymbolTable::add(inverseRefName, tkn_ident, FASTDB_CLONE_ANY_IDENTIFIER); } inverseRef = NULL; components = fieldComponents; method = NULL; attr = 0; tTree = 0; hashTable = 0; comparator = (dbUDTComparator)&memcmp;}dbFieldDescriptor::~dbFieldDescriptor() { if (type == dbField::tpString) { delete components; } delete[] longName; }dbFieldDescriptor* dbFieldDescriptor::find(const char* name){ dbFieldDescriptor* field = components; do { if (field->name == name) { return field; } } while ((field = field->next) != components); return NULL;}void dbFieldDescriptor::adjustReferences(byte* record, size_t base, size_t size, long shift){ dbFieldDescriptor* fd = this; do { if (fd->type == dbField::tpArray) { byte** ptr = (byte**)((dbAnyArray*)(record + fd->appOffs) + 1); if ((unsigned long)*ptr - base <= size) { *ptr += shift; } else { if (fd->attr & HasArrayComponents) { int nElems = ((dbAnyArray*)(record+fd->appOffs))->length(); byte* arrBase = *ptr; while (--nElems >= 0) { fd->components->adjustReferences(arrBase, base, size, shift); arrBase += fd->components->appSize; } } } } else if (fd->type == dbField::tpString) { char** str = (char**)(record + fd->appOffs); if ((unsigned long)*str - base <= size) { *str += shift; } } else if (fd->attr & HasArrayComponents) { fd->components->adjustReferences(record + fd->appOffs, base, size, shift); } } while ((fd = fd->next) != this);}size_t dbFieldDescriptor::calculateRecordSize(byte* base, size_t offs){ dbFieldDescriptor* fd = this; do { switch (fd->appType) { case dbField::tpArray: { int nElems = ((dbAnyArray*)(base + fd->appOffs))->length(); offs = DOALIGN(offs, fd->components->alignment) + nElems*fd->components->dbsSize; if (fd->attr & HasArrayComponents) { byte* elem = (byte*)((dbAnyArray*)(base+fd->appOffs))->base(); dbFieldDescriptor* component = fd->components; size_t elemSize = component->appSize; while (--nElems >= 0) { offs = component->calculateRecordSize(elem, offs); elem += elemSize; } } continue; } case dbField::tpString: { char* str = *(char**)(base + fd->appOffs); assert(str != NULL); offs += strlen(str) + 1; continue; }#ifdef USE_STD_STRING case dbField::tpStdString: offs += ((std::string*)(base + fd->appOffs))->length() + 1; continue;#endif default: if (fd->attr & HasArrayComponents) { offs = fd->components->calculateRecordSize(base+fd->appOffs, offs); } } } while ((fd = fd->next) != this); return offs;}size_t dbFieldDescriptor::calculateNewRecordSize(byte* base, size_t offs) { dbFieldDescriptor* fd = this; do { if (fd->type == dbField::tpArray) { if (fd->oldDbsType == dbField::tpUnknown) { continue; } int nElems = ((dbVarying*)(base + fd->oldDbsOffs))->size; offs = DOALIGN(offs, fd->components->alignment) + nElems*fd->components->dbsSize; if (fd->attr & HasArrayComponents) { byte* elem = base + ((dbVarying*)(base+fd->oldDbsOffs))->offs; while (--nElems >= 0) { offs = fd->components->calculateNewRecordSize(elem, offs); elem += fd->components->oldDbsSize; } } } else if (fd->type == dbField::tpString) { if (fd->oldDbsType == dbField::tpUnknown) { offs += 1; } else { offs += ((dbVarying*)(base + fd->oldDbsOffs))->size; } } else if (fd->attr & HasArrayComponents) { offs = fd->components->calculateNewRecordSize(base, offs); } } while ((fd = fd->next) != this); return offs;}void dbFieldDescriptor::fetchRecordFields(byte* dst, byte* src){ dbFieldDescriptor* fd = this; do { switch (fd->appType) { case dbField::tpBool: *(bool*)(dst+fd->appOffs) = *(bool*)(src+fd->dbsOffs); break; case dbField::tpInt1: *(int1*)(dst+fd->appOffs) = *(int1*)(src+fd->dbsOffs); break; case dbField::tpInt2: *(int2*)(dst+fd->appOffs) = *(int2*)(src+fd->dbsOffs); break; case dbField::tpInt4: *(int4*)(dst+fd->appOffs) = *(int4*)(src+fd->dbsOffs); break; case dbField::tpInt8: *(db_int8*)(dst+fd->appOffs) = *(db_int8*)(src+fd->dbsOffs); break; case dbField::tpReal4: *(real4*)(dst+fd->appOffs) = *(real4*)(src+fd->dbsOffs); break; case dbField::tpReal8: *(real8*)(dst+fd->appOffs) = *(real8*)(src+fd->dbsOffs); break; case dbField::tpRawBinary: memcpy(dst+fd->appOffs, src+fd->dbsOffs, fd->dbsSize); break; case dbField::tpString: *(char**)(dst+fd->appOffs) = (char*)(src + ((dbVarying*)(src+fd->dbsOffs))->offs); break;#ifdef USE_STD_STRING case dbField::tpStdString: ((std::string*)(dst + fd->appOffs))->assign((char*)(src + ((dbVarying*)(src+fd->dbsOffs))->offs), ((dbVarying*)(src+fd->dbsOffs))->size - 1); break;#endif case dbField::tpArray: { int nElems = ((dbVarying*)(src+fd->dbsOffs))->size; byte* srcElem = src + ((dbVarying*)(src+fd->dbsOffs))->offs; dbAnyArray* array = (dbAnyArray*)(dst+fd->appOffs); if (fd->attr & dbFieldDescriptor::OneToOneMapping) { fd->arrayAllocator(array, srcElem, nElems); } else { fd->arrayAllocator(array, NULL, nElems); byte* dstElem = (byte*)array->base(); dbFieldDescriptor* component = fd->components; while (--nElems >= 0) { component->fetchRecordFields(dstElem, srcElem); dstElem += component->appSize; srcElem += component->dbsSize; } } } break; case dbField::tpReference: ((dbAnyReference*)(dst+fd->appOffs))->oid = *(oid_t*)(src+fd->dbsOffs); break; case dbField::tpStructure: fd->components->fetchRecordFields(dst + fd->appOffs, src); break; default: return; } } while ((fd = fd->next) != this);}size_t dbFieldDescriptor::storeRecordFields(byte* dst, byte* src, size_t offs, bool insert){ dbFieldDescriptor* fd = this; do { #ifdef AUTOINCREMENT_SUPPORT if (insert && (fd->indexType & AUTOINCREMENT) != 0) { assert (fd->appType == dbField::tpInt4); *(int4*)(dst+fd->dbsOffs) = *(int4*)(src+fd->appOffs) = fd->defTable->autoincrementCount; continue; }#endif switch (fd->appType) { case dbField::tpBool: *(bool*)(dst+fd->dbsOffs) = *(bool*)(src+fd->appOffs); break; case dbField::tpInt1: *(int1*)(dst+fd->dbsOffs) = *(int1*)(src+fd->appOffs); break; case dbField::tpInt2: *(int2*)(dst+fd->dbsOffs) = *(int2*)(src+fd->appOffs); break; case dbField::tpInt4: *(int4*)(dst+fd->dbsOffs) = *(int4*)(src+fd->appOffs); break; case dbField::tpInt8: *(db_int8*)(dst+fd->dbsOffs) = *(db_int8*)(src+fd->appOffs); break; case dbField::tpReal4: *(real4*)(dst+fd->dbsOffs) = *(real4*)(src+fd->appOffs); break; case dbField::tpReal8: *(real8*)(dst+fd->dbsOffs) = *(real8*)(src+fd->appOffs); break; case dbField::tpRawBinary: memcpy(dst+fd->dbsOffs, src+fd->appOffs, fd->dbsSize); break; #ifdef USE_STD_STRING case dbField::tpStdString: { ((dbVarying*)(dst+fd->dbsOffs))->offs = offs; std::string* str = (std::string*)(src + fd->appOffs); int len = str->length(); str->copy((char*)dst + offs, len); dst[offs + len] = '\0'; ((dbVarying*)(dst+fd->dbsOffs))->size = len+1; offs += (len+1); } break;#endif case dbField::tpString: ((dbVarying*)(dst+fd->dbsOffs))->offs = offs; strcpy((char*)dst + offs, *(char**)(src + fd->appOffs)); offs += ((dbVarying*)(dst+fd->dbsOffs))->size = strlen(*(char**)(src + fd->appOffs)) + 1; break; case dbField::tpArray: { int nElems = ((dbAnyArray*)(src + fd->appOffs))->length(); byte* srcElem=(byte*)((dbAnyArray*)(src+fd->appOffs))->base(); byte* dstElem = (byte*)DOALIGN(long(dst)+offs, fd->components->alignment); offs = dstElem - dst; ((dbVarying*)(dst+fd->dbsOffs))->size = nElems; ((dbVarying*)(dst+fd->dbsOffs))->offs = offs; size_t sizeElem = fd->components->dbsSize; size_t offsElem = nElems*sizeElem; offs += offsElem; if (srcElem != NULL) { if (fd->attr & dbFieldDescriptor::OneToOneMapping) { memcpy(dstElem, srcElem, offsElem); } else { dbFieldDescriptor* component = fd->components; while (--nElems >= 0) { offsElem = component->storeRecordFields(dstElem, srcElem, offsElem, insert); offsElem -= sizeElem; dstElem += sizeElem; srcElem += component->appSize; } offs += offsElem; } } } break; case dbField::tpReference: *(oid_t*)(dst+fd->dbsOffs) = ((dbAnyReference*)(src+fd->appOffs))->oid; break; case dbField::tpStructure: offs = fd->components->storeRecordFields(dst, src+fd->appOffs, offs, insert); break; default: return offs; } } while ((fd = fd->next) != this); return offs;}void dbFieldDescriptor::markUpdatedFields(byte* dst, byte* src){ dbFieldDescriptor* fd = this; do { if (fd->indexType & (HASHED|INDEXED)) { switch (fd->appType) { case dbField::tpBool: if (*(bool*)(dst+fd->dbsOffs) != *(bool*)(src+fd->appOffs)) { fd->attr |= Updated; } break; case dbField::tpInt1: if (*(int1*)(dst+fd->dbsOffs) != *(int1*)(src+fd->appOffs)) { fd->attr |= Updated; } break; case dbField::tpInt2: if (*(int2*)(dst+fd->dbsOffs) != *(int2*)(src+fd->appOffs)) { fd->attr |= Updated; } break; case dbField::tpInt4: if (*(int4*)(dst+fd->dbsOffs) != *(int4*)(src+fd->appOffs)) { fd->attr |= Updated; } break; case dbField::tpInt8: if (*(db_int8*)(dst+fd->dbsOffs) != *(db_int8*)(src+fd->appOffs)) { fd->attr |= Updated; } break; case dbField::tpReference: if (*(oid_t*)(dst+fd->dbsOffs) != *(oid_t*)(src+fd->appOffs)) { fd->attr |= Updated; } break; case dbField::tpReal4: if (*(real4*)(dst+fd->dbsOffs) != *(real4*)(src+fd->appOffs)) { fd->attr |= Updated; } break; case dbField::tpReal8: if (*(real8*)(dst+fd->dbsOffs) != *(real8*)(src+fd->appOffs)) { fd->attr |= Updated; } break; case dbField::tpRawBinary: if (memcmp(dst+fd->dbsOffs, src+fd->appOffs, fd->dbsSize) != 0) { fd->attr |= Updated; } break; case dbField::tpString: if (strcmp((char*)dst + ((dbVarying*)(dst+fd->dbsOffs))->offs, *(char**)(src + fd->appOffs)) != 0) { fd->attr |= Updated; } break;#ifdef USE_STD_STRING case dbField::tpStdString: if (*(std::string*)(src + fd->appOffs) != (char*)(dst + ((dbVarying*)(dst+fd->dbsOffs))->offs)) { fd->attr |= Updated; } break;#endif case dbField::tpStructure: fd->components->markUpdatedFields(dst, src+fd->appOffs); break; case dbField::tpArray: break; default: return; } } } while ((fd = fd->next) != this);}size_t dbFieldDescriptor::convertRecord(byte* dst, byte* src, size_t offs){ dbFieldDescriptor* fd = this; int1 i1; int2 i2; int4 i4; db_int8 i8; real4 f4; real8 f8; bool b; do { switch (fd->type) { case dbField::tpBool: switch (fd->oldDbsType) { case dbField::tpBool: b = *(bool*)(src + fd->oldDbsOffs); break; case dbField::tpInt1: b = *(int1*)(src + fd->oldDbsOffs) != 0; break; case dbField::tpInt2: b = *(int2*)(src + fd->oldDbsOffs) != 0; break; case dbField::tpInt4: b = *(int4*)(src + fd->oldDbsOffs) != 0; break; case dbField::tpInt8: b = *(db_int8*)(src + fd->oldDbsOffs) != 0; break; case dbField::tpReal4: b = *(real4*)(src + fd->oldDbsOffs) != 0; break; case dbField::tpReal8: b = *(real8*)(src + fd->oldDbsOffs) != 0; break; default: b = false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -