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

📄 class.cpp

📁 一个功能强大的内存数据库源代码,c++编写,有详细的注释
💻 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#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 + -