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

📄 class.h

📁 实现内存数据库的源代码
💻 H
字号:
//-< CLASS.H >-------------------------------------------------------*--------*
// FastDB                    Version 1.0         (c) 1999  GARRET    *     ?  *
// (Main Memory Database Management System)                          *   /\|  *
//                                                                   *  /  \  *
//                          Created:     20-Nov-98    K.A. Knizhnik  * / [] \ *
//                          Last update: 10-Dec-98    K.A. Knizhnik  * GARRET *
//-------------------------------------------------------------------*--------*
// Metaclass information
//-------------------------------------------------------------------*--------*

#ifndef __CLASS_H__
#define __CLASS_H__

#include "stdtp.h"
#include "sync.h"

#ifdef USE_STD_STRING
#include <string>
#endif

#ifndef dbDatabaseOffsetBits 
#define dbDatabaseOffsetBits 32
#endif

#ifndef dbDatabaseOidBits 
#define dbDatabaseOidBits 32
#endif

#if dbDatabaseOidBits > 32
typedef nat8 oid_t;  // It will work only for 64-bit OS
#else
typedef nat4 oid_t;
#endif

#if dbDatabaseOffsetBits > 32
typedef nat8 offs_t; // It will work only for 64-bit OS
#else
typedef nat4 offs_t;
#endif

enum dbIndexType { 
    HASHED  = 1, // hash table
    INDEXED = 2, // T-tree

    DB_FIELD_CASCADE_DELETE = 8,   // Used by OWNER macro, do not set it explicitly

    AUTOINCREMENT = 16, // field is assigned automaticall incremented value

    DB_FIELD_INHERITED_MASK = ~(HASHED|INDEXED)
};

#define KEY(x, index) \
    *dbDescribeField(new dbFieldDescriptor(#x, (char*)&x-(char*)this, \
                                           sizeof(x), index), x)

#define FIELD(x) KEY(x, 0)

// user defined raw binary field
typedef int (*dbUDTComparator)(void*, void*, size_t);

#define UDT(x, index, comparator) \
    *dbDescribeRawField(new dbFieldDescriptor(#x, (char*)&x-(char*)this, \
                                              sizeof(x), index), (dbUDTComparator)comparator)

#define RAWFIELD(x) UDT(x, 0, &memcmp)
#define RAWKEY(x, index) UDT(x, index, &memcmp)


#define RELATION(x,inverse) \
    *dbDescribeField(new dbFieldDescriptor(#x, (char*)&x-(char*)this, \
                                           sizeof(x), 0, #inverse), x)

#define OWNER(x,member) \
    *dbDescribeField(new dbFieldDescriptor(#x, (char*)&x-(char*)this, \
                                           sizeof(x), DB_FIELD_CASCADE_DELETE, \
                                           #member), x)

#define METHOD(x) \
    *dbDescribeMethod(new dbFieldDescriptor(#x), &self::x)

#define SUPERCLASS(x) \
    x::dbDescribeComponents(NULL)->adjustOffsets((char*)((x*)this)-(char*)this)

#define TYPE_DESCRIPTOR(fields) \
    dbFieldDescriptor* dbDescribeComponents(dbFieldDescriptor*) { \
	return &fields; \
    } \
    static dbTableDescriptor dbDescriptor 

#define CLASS_DESCRIPTOR(name, fields) \
    typedef name self; \
    dbFieldDescriptor* dbDescribeComponents(dbFieldDescriptor*) { \
	return &fields; \
    } \
    static dbTableDescriptor dbDescriptor 

#define REGISTER_IN(table, database) \
    dbTableDescriptor* dbGetTableDescriptor(table*) \
      { return &table::dbDescriptor; }            \
    static dbFieldDescriptor* dbDescribeComponentsOf##table() \
      { return ((table*)0)->dbDescribeComponents(NULL); }     \
    dbTableDescriptor table::dbDescriptor(#table, database, sizeof(table), \
                                          &dbDescribeComponentsOf##table)

#define REGISTER(table) REGISTER_IN(table, NULL)

#define DETACHED_TABLE ((dbDatabase*)-1)
#define REGISTER_UNASSIGNED(table) REGISTER_IN(table, DETACHED_TABLE)


class dbDatabase;
class dbAnyArray;
class dbTableDescriptor;
class dbAnyMethodTrampoline;

class FASTDB_DLL_ENTRY dbFieldDescriptor { 
  public:
    dbFieldDescriptor* next; // next file within scope
    dbFieldDescriptor* prev; // previous field within scope

    dbFieldDescriptor* nextField;

    dbFieldDescriptor* nextHashedField;
    dbFieldDescriptor* nextIndexedField;
    dbFieldDescriptor* nextInverseField;

    int                fieldNo;
    char*              name;
    char*              longName;
    char*              refTableName;
    dbTableDescriptor* refTable;
    dbTableDescriptor* defTable;
    dbFieldDescriptor* inverseRef;
    char*              inverseRefName;  
    int                type;
    int                appType;
    int                indexType;
    int                dbsOffs;
    int                appOffs;
    dbFieldDescriptor* components;
    void*              trampoline;
    oid_t              hashTable;
    oid_t              tTree;
    size_t             dbsSize;
    size_t             appSize;
    size_t             alignment;
    dbUDTComparator    comparator;

    enum FieldAttributes { 
	ComponentOfArray   = 0x01,
	HasArrayComponents = 0x02,
	OneToOneMapping    = 0x04,
	Updated            = 0x08
    };
    int                attr;

    int                oldDbsType;
    int                oldDbsOffs;
    int                oldDbsSize;

    dbAnyMethodTrampoline* method;

    void (*arrayAllocator)(dbAnyArray* array, void* data, size_t length);
    
    size_t calculateRecordSize(byte* base, size_t offs);
    size_t calculateNewRecordSize(byte* base, size_t offs);
    size_t convertRecord(byte* dst, byte* src, size_t offs);

    int    sizeWithoutOneField(dbFieldDescriptor* field, 
			       byte* base, size_t& size);
    
    size_t copyRecordExceptOneField(dbFieldDescriptor* field, 
				    byte* dst, byte* src, size_t offs); 

    size_t storeRecordFields(byte* dst, byte* src, size_t offs, bool insert);

    void markUpdatedFields(byte* dst, byte* src);

    void fetchRecordFields(byte* dst, byte* src);

    void adjustReferences(byte* record, size_t base, size_t size, long shift);

    dbFieldDescriptor* find(const char* name);

    dbFieldDescriptor& operator, (dbFieldDescriptor& field) { 
	dbFieldDescriptor* tail = field.prev;
	tail->next = this;
	prev->next = &field;
	field.prev = prev;
	prev = tail;
	return *this;
    }

    dbFieldDescriptor& adjustOffsets(long offs);

    dbFieldDescriptor(char* name, int offs, int size, int indexType, 
		      char* inverse = NULL,
		      dbFieldDescriptor* components = NULL);

    dbFieldDescriptor(char* name);
    ~dbFieldDescriptor();
};

class FASTDB_DLL_ENTRY dbTableDescriptor { 
    friend class dbCompiler;
    friend class dbDatabase;
    friend class dbTable;
    friend class dbAnyCursor;
    friend class dbSubSql;
    friend class dbHashTable;
    friend class dbTtreeNode;
    friend class dbServer;
    friend class dbColumnBinding;
    friend class dbFieldDescriptor;
  protected:
    dbTableDescriptor*  next;
    static dbTableDescriptor* chain;

    dbTableDescriptor*  nextDbTable; // next table in the database

    char*               name;
    oid_t               tableId;
    dbFieldDescriptor*  columns; 
    dbFieldDescriptor*  hashedFields;
    dbFieldDescriptor*  indexedFields;
    dbFieldDescriptor*  inverseFields;
    dbFieldDescriptor*  firstField;
    dbFieldDescriptor** nextFieldLink;
    dbDatabase*         db;
    bool                fixedDatabase;
    bool                isStatic;
    size_t              appSize;
    size_t              fixedSize;
    size_t              nFields;
    size_t              nColumns;
    int4                autoincrementCount;

    dbTableDescriptor*  cloneOf;
    typedef dbFieldDescriptor* (*describeFunc)();
    describeFunc        describeComponentsFunc;

    dbTableDescriptor*  clone();

    size_t              totalNamesLength();

    int calculateFieldsAttributes(dbFieldDescriptor* fieldsList, 
				  char const* prefix, int offs, 
				  int indexMask, int& attr);

    dbFieldDescriptor* buildFieldsList(dbTable* table, char const* prefix, int prefixLen, int& attr);

  public:
    static int initialAutoincrementCount;

    dbFieldDescriptor* find(char const* name);

    char* getName() { 
	return name;
    }

    void setFlags();

    bool equal(dbTable* table);

    bool match(dbTable* table);

    void checkRelationship();

    dbDatabase* getDatabase() { return db; }

    void storeInDatabase(dbTable* table);

    static void cleanup();

    dbTableDescriptor(dbTable* table);

    dbTableDescriptor(char* tableName, dbDatabase* db, size_t objSize, 
		      describeFunc func, dbTableDescriptor* original = NULL);
    ~dbTableDescriptor();
};

struct dbVarying { 
    nat4 size; // number of elements in the array
    int4 offs; // offset from the beginning of the record
};

struct dbField { 
    enum FieldTypes { 
	tpBool,
	tpInt1,
	tpInt2,
	tpInt4,
	tpInt8,
	tpReal4, 
	tpReal8, 
	tpString,
	tpReference,
	tpArray,
	tpMethodBool,
	tpMethodInt1,
	tpMethodInt2,
	tpMethodInt4,
	tpMethodInt8,
	tpMethodReal4,
	tpMethodReal8,
	tpMethodString,
	tpMethodReference,
	tpStructure,
	tpRawBinary, 
	tpStdString,
	tpUnknown
    };
	
    dbVarying name;     
    dbVarying tableName; // only for references: name of referenced table
    dbVarying inverse;   // only for relations: name of inverse reference field
    int4      type;
    int4      offset; 
    nat4      size;
    oid_t     hashTable;
    oid_t     tTree;
};     


class dbRecord { 
  public:
    nat4   size;
    oid_t  next;
    oid_t  prev;
};

class dbTable : public dbRecord { 
  public:
    dbVarying name;
    dbVarying fields;
    nat4      fixedSize;
    nat4      nRows;
    nat4      nColumns;
    oid_t     firstRow;
    oid_t     lastRow;
#ifdef AUTOINCREMENT_SUPPORT
    nat4      count;
#endif
};

inline dbFieldDescriptor* dbDescribeRawField(dbFieldDescriptor* fd, dbUDTComparator comparator)
{
    fd->type = fd->appType = dbField::tpRawBinary;
    fd->alignment = 1;
    fd->comparator = comparator;
    return fd;
}


template<class T>
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, T& x) 
{ 
    fd->type = fd->appType = dbField::tpStructure;
    fd->components = x.dbDescribeComponents(fd);
    return fd;
}

inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int1&) 
{ 
    fd->type = fd->appType = dbField::tpInt1; 
    return fd;
}
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int2&) 
{ 
    fd->type = fd->appType = dbField::tpInt2; 
    return fd;
}
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int4&) 
{ 
    fd->type = fd->appType = dbField::tpInt4; 
    return fd;
}
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int8&) 
{ 
    fd->type = fd->appType = dbField::tpInt8; 
    return fd;
}
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat1&) 
{ 
    fd->type = fd->appType = dbField::tpInt1; 
    return fd;
}
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat2&) 
{ 
    fd->type = fd->appType = dbField::tpInt2; 
    return fd;
}
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat4&) 
{ 
    fd->type = fd->appType = dbField::tpInt4; 
    return fd;
}
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat8&) 
{ 
    fd->type = fd->appType = dbField::tpInt8; 
    return fd;
}
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, bool&) 
{ 
    fd->type = fd->appType = dbField::tpBool; 
    return fd;
}
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real4&) 
{ 
    fd->type = fd->appType = dbField::tpReal4; 
    return fd;
}
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real8&) 
{ 
    fd->type = fd->appType = dbField::tpReal8; 
    return fd;
}
#ifdef USE_STD_STRING
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, std::string&)
{
    fd->type = dbField::tpString;
    fd->appType = dbField::tpStdString;
    fd->dbsSize = sizeof(dbVarying);
    fd->alignment = 4;
    fd->components = new dbFieldDescriptor("[]");
    fd->components->type = fd->components->appType = dbField::tpInt1;
    fd->components->dbsSize = fd->components->appSize = fd->components->alignment = 1; 
    return fd;
}
#endif
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char const*&) 
{ 
    fd->type = fd->appType = dbField::tpString; 
    fd->dbsSize = sizeof(dbVarying); 
    fd->alignment = 4;
    fd->components = new dbFieldDescriptor("[]");
    fd->components->type = fd->components->appType = dbField::tpInt1;
    fd->components->dbsSize = fd->components->appSize = 1;
    fd->components->alignment = 1; 
    return fd;
}
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char*&) 
{ 
    fd->type = fd->appType = dbField::tpString; 
    fd->dbsSize = sizeof(dbVarying); 
    fd->alignment = 4;
    fd->components = new dbFieldDescriptor("[]");
    fd->components->type = fd->components->appType = dbField::tpInt1;
    fd->components->dbsSize = fd->components->appSize = 1;
    fd->components->alignment = 1; 
    return fd;
}

class FASTDB_DLL_ENTRY dbAnyMethodTrampoline { 
  public:
    dbFieldDescriptor* cls;

    virtual void invoke(byte* data, void* result) = 0;
    virtual dbAnyMethodTrampoline* optimize() = 0;

    dbAnyMethodTrampoline(dbFieldDescriptor* fd) { cls = fd; }
    virtual~dbAnyMethodTrampoline();
};
    
template<class T, class R>
class dbMethodTrampoline : public dbAnyMethodTrampoline { 
  public:
    typedef R (T::*mfunc)();
    mfunc method;

    void invoke(byte* data, void* result) {
	T rec;
	cls->components->fetchRecordFields((byte*)&rec, data);
	*(R*)result = (rec.*method)();
    }
    dbAnyMethodTrampoline* optimize();
 
    dbMethodTrampoline(dbFieldDescriptor* fd, mfunc f) 
    : dbAnyMethodTrampoline(fd), method(f) {} 
};

template<class T, class R>
class dbMethodFastTrampoline : public dbMethodTrampoline<T,R> { 
  public:
    void invoke(byte* data, void* result) {
	*(R*)result = (((T*)(data + cls->dbsOffs))->*method)();
    }
    dbMethodFastTrampoline(dbMethodTrampoline<T,R>* mt) 
    : dbMethodTrampoline<T,R>(mt->cls, mt->method) { 
	delete mt;
    }
};

template<class T, class R>
inline dbAnyMethodTrampoline* dbMethodTrampoline<T,R>::optimize() { 
    return new dbMethodFastTrampoline<T,R>(this);
}
    

template<class T, class R>
inline dbFieldDescriptor* dbDescribeMethod(dbFieldDescriptor* fd, R (T::*p)()) 
{ 
    R ret;
    dbDescribeField(fd, ret);
    assert(fd->type <= dbField::tpReference);
    fd->type += dbField::tpMethodBool;
    fd->method = new dbMethodTrampoline<T,R>(fd, p);
    return fd;
}

#endif


⌨️ 快捷键说明

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