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

📄 compiler.h

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

#ifndef __COMPILER_H__
#define __COMPILER_H__

#include <setjmp.h>

#if defined(__osf__) || defined(__FreeBSD__)
#define longjmp(b,s) _longjmp(b,s) // do not restore signal context
#define setjmp(b)  _setjmp(b)
#endif

#define DEBUG_NONE  0
#define DEBUG_CHECK 1
#define DEBUG_TRACE 2

#if DEBUG == DEBUG_TRACE
#define TRACE_MSG(x)  dbTrace x
#else
#define TRACE_MSG(x)
#endif

extern FASTDB_DLL_ENTRY void dbTrace(char* message, ...);

enum dbvmCodes { 
#define DBVM(cop, type, n_operands, commutative) cop,
#include "compiler.d"
dbvmLastCode
};

#define IS_CONSTANT(c) \
(unsigned(c) - dbvmLoadVarBool <= (unsigned)dbvmLoadRawBinary - dbvmLoadVarBool)

enum nodeType { 
    tpInteger,
    tpBoolean,
    tpReal,
    tpString,
    tpReference,
    tpArray,
    tpRawBinary, 
    tpFreeVar,  // index of EXISTS clause 
    tpList,     // list of expressions
    tpVoid
};

enum tokens { 
    tkn_ident,
    tkn_lpar,
    tkn_rpar,
    tkn_lbr,
    tkn_rbr,
    tkn_dot,
    tkn_comma,
    tkn_power,
    tkn_iconst,
    tkn_sconst,
    tkn_fconst,
    tkn_add,
    tkn_sub,
    tkn_mul,
    tkn_div,
    tkn_and,
    tkn_or,
    tkn_not,
    tkn_null,
    tkn_neg,
    tkn_eq,
    tkn_ne,
    tkn_gt,
    tkn_ge,
    tkn_lt,
    tkn_le,
    tkn_between,
    tkn_escape,
    tkn_exists,
    tkn_like,
    tkn_in,
    tkn_length,
    tkn_lower,
    tkn_upper,
    tkn_abs,
    tkn_is,
    tkn_integer,
    tkn_real,
    tkn_string,
    tkn_first,
    tkn_last,
    tkn_current,
    tkn_var,
    tkn_col,
    tkn_true,
    tkn_false,
    tkn_where, 
    tkn_follow,
    tkn_start,
    tkn_from,
    tkn_order,
    tkn_by,
    tkn_asc,
    tkn_desc, 
    tkn_eof,
    tkn_last_token
};    

struct dbStrLiteral { 
    char* str;
    int   len;
};


class dbUserFunction;

class FASTDB_DLL_ENTRY dbExprNode { 
    friend class dbExprNodeSegment;
  public:
    nat1 cop;
    nat1 type;
    nat2 offs;

    static const nat1  nodeTypes[];
    static const nat1  nodeOperands[];
    static const nat1  commutativeOperator[];
    static dbExprNode* freeNodeList;
    static dbMutex&    mutex;

    static dbExprNodeSegment* segmentList;

    union { 
        dbExprNode*  operand[3];
        dbExprNode*  next;
	oid_t        oid;
	int8         ivalue;
	real8        fvalue;
	dbStrLiteral svalue;
	void const*  var;

	struct { 
	    dbExprNode*         base;  // the same as operand[0]
	    dbFieldDescriptor*  field;
	} ref;

	struct { 
	    dbExprNode*         arg[3]; 
	    void*               fptr;
	} func;
    };

    dbExprNode(dbExprNode* node);

    dbExprNode(int cop, dbExprNode* left = NULL, dbExprNode* right = NULL, 
	       dbExprNode* right2 = NULL)
    {
	this->cop = cop;
	type = nodeTypes[cop];
	operand[0] = left;
	operand[1] = right;
	operand[2] = right2;
    }
    dbExprNode(int cop, dbExprNode* expr1, dbExprNode* expr2, int offs) { 
	this->cop = cop;
	this->offs = (nat2)offs;
	type = nodeTypes[cop];
	operand[0] = expr1;
	operand[1] = expr2;
    }
    dbExprNode(int cop, dbExprNode* expr, int offs) { 
	this->cop = cop;
	this->offs = (nat2)offs;
	type = nodeTypes[cop];
	operand[0] = expr;
    }
    dbExprNode(int cop, dbFieldDescriptor* field, dbExprNode* base = NULL) 
    {
	this->cop = cop;
	this->offs = (nat2)field->dbsOffs;
	type = nodeTypes[cop];
	ref.field = field;
	ref.base = base;
    }
    dbExprNode(int cop, int8 ivalue) { 
 	this->cop = cop;
	this->ivalue = ivalue;
	type = tpInteger;
    }
    dbExprNode(int cop, real8 fvalue) { 
 	this->cop = cop;
	this->fvalue = fvalue;
	type = tpReal;
    }
    dbExprNode(int cop, dbStrLiteral& svalue) { 
 	this->cop = cop;
	this->svalue = svalue;
	type = tpString;
    }
    dbExprNode(int cop, void const* var) { 
 	this->cop = cop;
	this->var = var;
	type = nodeTypes[cop];
    }
    dbExprNode(int cop, void* fptr, dbExprNode* expr1, dbExprNode* expr2 = NULL, dbExprNode* expr3 = NULL) { 
 	this->cop = cop;
	func.arg[0] = expr1;
	func.arg[1] = expr2;
	func.arg[2] = expr3;
	func.fptr = fptr;
	type = nodeTypes[cop];
    }
    ~dbExprNode();

    void* operator new(size_t size);

    void operator delete(void* ptr) { 
	if (ptr != NULL) { 
	    dbExprNode* node = (dbExprNode*)ptr;
	    node->next = freeNodeList;
	    freeNodeList = node;
	}
    }

    static void cleanup();
};


class dbExprNodeSegment { 
  public:
    enum { allocationQuantum = 1024};
    char               buf[sizeof(dbExprNode)*allocationQuantum];
    dbExprNodeSegment* next;
};


class dbBinding { 
  public:
    dbBinding*  next;
    char const* name;
    bool        used;
    int         index;
};

class dbOrderByNode { 
  public:
    dbOrderByNode*     next;
    dbFieldDescriptor* field;
    bool               stringLength;  // true if order by length of string instead of string value
    bool               ascent;  // true for ascent order, false for descent 
};

class dbFollowByNode { 
  public:
    dbFollowByNode*    next;
    dbFieldDescriptor* field;
};

class dbCompiler { 
    friend class dbQuery;
    friend class dbQueryElement;
  public:
    enum { 
	maxStrLen    = 4096,
	maxFreeVars  = 4
    };

    dbTableDescriptor* table;
    dbQueryElement*    queryElement;
    int                currPos;
    int                firstPos;
    int                offsetWithinStatement;
    int                bvalue;
    int8               ivalue;
    real8              fvalue;
    dbStrLiteral       svalue;
    int                lex;
    char*              name;
    dbBinding*         bindings;
    int                nFreeVars;
    int                varType;
    void const*        varPtr;
    dbTableDescriptor* varRefTable;

    jmp_buf            abortCompilation;
    static bool        initialized;

    int         compare(dbExprNode* expr, dbExprNode* list);

    int         scan();
    void        error(const char* msg, int pos = -1);
    dbExprNode* conjunction();    
    dbExprNode* disjunction();
    dbExprNode* comparison();    
    dbExprNode* addition();    
    dbExprNode* multiplication();    
    dbExprNode* power();
    dbExprNode* term();
    dbExprNode* userDefinedOperator();
    dbExprNode* field(dbExprNode* expr, dbTableDescriptor* refTable,
		      dbFieldDescriptor* fd);

    bool        compile(dbTableDescriptor* table, dbQuery& query);
    dbExprNode* compileExpression(dbTableDescriptor* table,  char const* expr, int startPos);
    void        compileOrderByPart(dbQuery& query);
    void        compileStartFollowPart(dbQuery& query);

    dbCompiler();
};

class dbDatabaseThreadContext { 
  public:
    int readAccess;
    int writeAccess;
    int concurrentId;
    dbL2List cursors; 
    
    dbCompiler compiler;

    dbProcessId currPid;

    bool     interactive;
    bool     catched;
    bool       commitDelayed;
    bool       removeContext;
    jmp_buf  unwind;
    
    dbDatabaseThreadContext() { 
	concurrentId = 0;
	readAccess = false;
	writeAccess = false;
	interactive = false;
	catched = false;
	commitDelayed = false;
	removeContext = false;
	currPid = dbProcessId::getCurrent();
    }
};

union dbSynthesizedAttribute { 
    byte* base;
    int   bvalue;
    int8  ivalue;
    real8 fvalue;
    void* raw;
    oid_t oid;

    struct { 
	char* base;
	int   size;
    } array;
};

struct dbStringValue;

struct dbInheritedAttribute { 
    byte*          record;
    oid_t          oid;
    dbTable*       table;
    dbDatabase*    db;
    dbStringValue* tempStrings;
    size_t         paramBase;
    enum { 
	internalStrBufSize = 8*1024 
    };
    size_t         strBufPos;
    char           strBuf[internalStrBufSize];
    
    struct { 
	int     index;
	jmp_buf unwind;
    } iterator[dbCompiler::maxFreeVars];

    void removeTemporaries();

    dbInheritedAttribute() { 
	tempStrings = NULL;
	strBufPos = 0;
    }

    ~dbInheritedAttribute() { 
	removeTemporaries(); 
    }
};

struct dbStringValue { 
    dbStringValue* next;
    char           str[1];

    static char* create(size_t size, dbInheritedAttribute& attr) { 
	if (attr.strBufPos + size > sizeof(attr.strBuf)) { 
	    dbStringValue* sv = 
		(dbStringValue*)new char[offsetof(dbStringValue, str) + size];
	    sv->next = attr.tempStrings;
	    attr.tempStrings = sv;
	    return sv->str;
	} else { 
	    char* p = attr.strBuf + attr.strBufPos;
	    attr.strBufPos += size;
	    return p;
	}
    }

    static char* create(char const* s, dbInheritedAttribute& attr) {
	size_t len = strlen(s) + 1;
	char*  buf;
	if (attr.strBufPos + len > sizeof(attr.strBuf)) { 
	    dbStringValue* sv = 
		(dbStringValue*)new char[offsetof(dbStringValue,str)+len];
	    sv->next = attr.tempStrings;
	    attr.tempStrings = sv;
	    buf = sv->str;
	} else { 
	    buf = attr.strBuf + attr.strBufPos;
	    attr.strBufPos += len;
	}
	return strcpy(buf, s);
    }
};
    
#endif

⌨️ 快捷键说明

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