📄 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
#endif
dbTableDescriptor* dbTableDescriptor::chain;
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 = 0;
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:
*(int8*)(dst+fd->appOffs) = *(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:
*(int8*)(dst+fd->dbsOffs) = *(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 (*(int8*)(dst+fd->dbsOffs) != *(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;
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 = *(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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -