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

📄 class.cpp

📁 fastdb-241源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//-< 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 + -