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

📄 class.cpp

📁 FastDb是高效的内存数据库系统
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//-< 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;

void* dbFieldDescriptor::operator new(size_t size EXTRA_DEBUG_NEW_PARAMS)
{
  return dbMalloc(size);
}

void  dbFieldDescriptor::operator delete(void* p EXTRA_DEBUG_NEW_PARAMS)
{
  dbFree(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;
  }
  else if (type == dbField::tpStructure)
  {
    dbFieldDescriptor* last = components->prev;

    while (last->method != NULL)
    {
      dbFieldDescriptor* prev = last->prev;
      delete last->method;
      delete last;

      if (last == components)
      {
        break;
      }

      last = prev;
    }
  }

  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);

        if (str != NULL)
        {
          offs += strlen(str) + 1;
        }
        else
        {
          offs += 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;
        char* str = *(char**)(src + fd->appOffs);

        if (str != NULL)
        {
          strcpy((char*)dst + offs, str);
          offs += ((dbVarying*)(dst+fd->dbsOffs))->size
                  = strlen(*(char**)(src + fd->appOffs)) + 1;
        }
        else
        {
          *((char*)dst + offs) = '\0';
          offs += 1;
        }
      }

      break;

    case dbField::tpArray:
      {
        int nElems = ((dbAnyArray*)(src + fd->appOffs))->length();
        byte* srcElem=(byte*)((dbAnyArray*)(src+fd->appOffs))->base();
        offs = DOALIGN(offs, fd->components->alignment);
        byte* dstElem = dst+offs;
        ((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;

⌨️ 快捷键说明

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