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

📄 class.cpp

📁 FastDb是高效的内存数据库系统
💻 CPP
📖 第 1 页 / 共 4 页
字号:

  int attr = 0;

  appSize = 0;

  columns = buildFieldsList(table, "", 0, attr);

  *nextFieldLink = NULL;

  db = NULL;

  tableId = 0;

#ifdef AUTOINCREMENT_SUPPORT

  autoincrementCount = table->count;

#endif
}




class _AlignArray : public dbAnyArray
{

protected:
  void*  data;
  size_t allocated;
};

class _AlignReference
{

protected:
  oid_t       oid;
};

union _aligns {

  struct
  {
    char n;
    bool v;
  }

  _abool;

  struct
  {
    char n;
    int1 v;
  }

  _aint1;

  struct
  {
    char n;
    int2 v;
  }

  _aint2;

  struct
  {
    char n;
    int4 v;
  }

  _aint4;

  struct
  {
    char n;
    db_int8 v;
  }

  _aint8;

  struct
  {
    char n;
    real4 v;
  }

  _areal4;

  struct
  {
    char n;
    real8 v;
  }

  _areal8;

  struct
  {
    char n;
    char *v;
  }

  _astring;

  struct
  {
    char n;
    char v[1];
  }

  _arawbinary;

  struct
  {
    char n;
    _AlignReference v;
  }

  _areference;

  struct
  {
    char n;
    _AlignArray v;
  }

  _aarray;
} __aligns;

#define COMPUTE_ALIGNED_SIZE(type) \
 (((char *)&(((union _aligns *)0)->_a##type.v)) - ((char *)&(((union _aligns *)0)->_a##type.n)))



dbFieldDescriptor* dbTableDescriptor::buildFieldsList(dbTable*    table,
    char const* prefix,
    int         prefixLen,
    int&        attr)
{
  dbFieldDescriptor* components = NULL;
  dbField* field = (dbField*)((char*)table+table->fields.offs) + nFields;

  while (nFields < table->fields.size
         && strncmp((char*)field + field->name.offs, prefix, prefixLen) == 0)
  {
    char* longName = (char*)field + field->name.offs;
    char* name = longName + prefixLen;

    if (*name == '.')
    {
      name += 1;
    }
    else if (prefixLen != 0 && *name != '[')
    {
      break;
    }

    dbSymbolTable::add
      (name, tkn_ident, true);

    dbFieldDescriptor* fd = new dbFieldDescriptor(name);

    fd->dbsOffs = field->offset;

    fd->alignment = fd->dbsSize = field->size;

    fd->longName = new char[strlen(longName)+1];

    strcpy(fd->longName, longName);

    fd->type = fd->appType = field->type;

    int appFieldSize, appAlignedFieldSize;

    switch (field->type)
    {

    case dbField::tpBool:
      appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(bool);
      appFieldSize = sizeof(bool);
      break;

    case dbField::tpInt1:
      appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(int1);
      appFieldSize = sizeof(int1);
      break;

    case dbField::tpInt2:
      appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(int2);
      appFieldSize = sizeof(int2);
      break;

    case dbField::tpInt4:
      appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(int4);
      appFieldSize = sizeof(int4);
      break;

    case dbField::tpInt8:
      appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(int8);
      appFieldSize = sizeof(db_int8);
      break;

    case dbField::tpReal4:
      appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(real4);
      appFieldSize = sizeof(real4);
      break;

    case dbField::tpReal8:
      appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(real8);
      appFieldSize = sizeof(real8);
      break;

    case dbField::tpString:
      appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(string);
      appFieldSize = sizeof(char *);
      break;

    case dbField::tpRawBinary:
      appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(rawbinary);
      appFieldSize = field->size;
      break;

    case dbField::tpReference:
      appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(reference);
      appFieldSize = sizeof(dbAnyReference);
      break;

    case dbField::tpArray:
      appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(array);
      appFieldSize = sizeof(_AlignArray);
      break;

    default:
      appAlignedFieldSize = 1;
      appFieldSize = 0;
    }

    fd->appOffs = appSize = DOALIGN(appSize, appAlignedFieldSize);
    appSize += fd->appSize = appFieldSize;

    if ((fd->hashTable = field->hashTable) != 0)
    {
      fd->nextHashedField = hashedFields;
      hashedFields = fd;
    }

    if ((fd->tTree = field->tTree) != 0)
    {
      fd->nextIndexedField = indexedFields;
      indexedFields = fd;
    }

    fd->fieldNo = nFields++;
    fd->defTable = this;
    fd->refTable = NULL;
    fd->refTableName = NULL;

    if (field->hashTable != 0)
    {
      fd->indexType |= HASHED;
    }

    if (field->tTree != 0)
    {
      fd->indexType |= INDEXED;
    }

    if (field->tableName.size > 1)
    {
      fd->refTableName = (char*)field + field->tableName.offs;

      dbSymbolTable::add
        (fd->refTableName, tkn_ident, true);
    }

    fd->inverseRefName = NULL;

    if (field->inverse.size > 1)
    {
      fd->nextInverseField = inverseFields;
      inverseFields = fd;
      fd->inverseRefName = (char*)field + field->inverse.offs;

      dbSymbolTable::add
        (fd->inverseRefName, tkn_ident, true);
    }

    fd->attr = (attr & dbFieldDescriptor::ComponentOfArray) | dbFieldDescriptor::OneToOneMapping;

    *nextFieldLink = fd;
    nextFieldLink = &fd->nextField;

    if (prefixLen == 0)
    {
      nColumns += 1;
    }

    if (components == NULL)
    {
      components = fd;
    }
    else
    {
      fd->next = components;
      fd->prev = components->prev;
      components->prev->next = fd;
      components->prev = fd;
    }

    if (fd->type == dbField::tpArray || fd->type == dbField::tpString)
    {
      attr |= dbFieldDescriptor::HasArrayComponents;
      fd->attr |= dbFieldDescriptor::ComponentOfArray;
      fd->alignment = 4;
    }

    if (fd->type == dbField::tpArray || fd->type == dbField::tpStructure)
    {
      int saveAppSize = appSize;

      if (fd->type == dbField::tpArray)
      {
        appSize = 0;
      }

      fd->components =
        buildFieldsList(table, longName, strlen(longName), fd->attr);

      if (fd->type == dbField::tpArray)
      {
        appSize = saveAppSize;
      }

      attr |= fd->attr & dbFieldDescriptor::HasArrayComponents;
      field = (dbField*)((char*)table + table->fields.offs) + nFields;

      if (fd->type == dbField::tpStructure)
      {
        size_t alignment = 1;
        dbFieldDescriptor* component = fd->components;

        do
        {
          if (component->alignment > alignment)
          {
            alignment = component->alignment;
          }
        }
        while ((component = component->next) != fd->components);

        fd->alignment = alignment;
      }
      else
      {
        if (fd->components->type == dbField::tpString)
        {
          fd->arrayAllocator = &dbArray<char*>::arrayAllocator;
          fd->attr &= ~dbFieldDescriptor::OneToOneMapping;
        }
        else
        {
          fd->arrayAllocator = &dbAnyArray::arrayAllocator;
        }
      }
    }
    else
    {
      if (fd->type == dbField::tpString)
      {
        fd->components = new dbFieldDescriptor("[]");
        fd->components->type = fd->components->appType = dbField::tpInt1;
        fd->components->dbsSize = fd->components->appSize = 1;
        fd->components->alignment = 1;
      }

      field += 1;
    }
  }

  return components;
}


size_t dbTableDescriptor::totalNamesLength()
{
  dbFieldDescriptor* fd;
  size_t len = strlen(name) + 1;

  for (fd = firstField; fd != NULL; fd = fd->nextField)
  {
    if (fd->name != NULL)
    {
      len += strlen(fd->longName) + 3;

      if (fd->inverseRefName != NULL)
      {
        len += strlen(fd->inverseRefName);
      }

      if (fd->refTable != NULL)
      {
        len += strlen(fd->refTable->name);
      }
    }
  }

  return len;
}


dbTableDescriptor* dbTableDescriptor::clone()
{
  return new dbTableDescriptor(name,
                               DETACHED_TABLE,
                               appSize,
                               describeComponentsFunc,
                               this);
}

dbTableDescriptor::~dbTableDescriptor()
{
  if (cloneOf == NULL)
  {
    dbTableDescriptor **tpp;

    for (tpp = &chain; *tpp != this; tpp = &(*tpp)->next)

      ;
    *tpp = next;
  }

  dbFieldDescriptor* last = columns->prev;

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

    if (last == columns)
    {
      break;
    }

    last = prev;
  }

  dbFieldDescriptor *field, *nextField;

  for (field = firstField; field != NULL; field = nextField)
  {
    nextField = field->nextField;
    delete field;
  }
}


void dbTableDescriptor::cleanup()
{
  dbTableDescriptor* next, *desc;

  for (desc = chain; desc != NULL; desc = next)
  {
    next = desc->next;

    if (!desc->isStatic)
    {
      delete desc;
    }
  }
}


void dbTableDescriptor::storeInDatabase(dbTable* table)
{
  int offs = sizeof(dbTable) + sizeof(dbField)*nFields;
  table->name.offs = offs;
  table->name.size = strlen(name)+1;
  strcpy((char*)table + offs, name);
  offs += table->name.size;
  table->fields.offs = sizeof(dbTable);
  table->fields.size = nFields;
  table->nRows = 0;
  table->nColumns = nColumns;
  table->fixedSize = fixedSize;
  table->firstRow = 0;
  table->lastRow = 0;
#ifdef AUTOINCREMENT_SUPPORT

  table->count = autoincrementCount;
#endif

  dbFieldDescriptor* fd;
  dbField* field = (dbField*)((char*)table + table->fields.offs);
  offs -= sizeof(dbTable);

  for (fd = firstField; fd != NULL; fd = fd->nextField)
  {
    field->name.offs = offs;
    field->name.size = strlen(fd->longName) + 1;
    strcpy((char*)field + offs, fd->longName);
    offs += field->name.size;
    field->tableName.offs = offs;

    if (fd->refTable != NULL)
    {
      field->tableName.size = strlen(fd->refTable->name) + 1;
      strcpy((char*)field + offs, fd->refTable->name);
    }
    else
    {
      field->tableName.size = 1;
      *((char*)field + offs) = '\0';
    }

    offs += field->tableName.size;

    field->inverse.offs = offs;

    if (fd->inverseRefName != NULL)
    {
      field->inverse.size = strlen(fd->inverseRefName) + 1;
      strcpy((char*)field + offs, fd->inverseRefName);
    }
    else
    {
      field->inverse.size = 1;
      *((char*)field + offs) = '\0';
    }

    offs += field->inverse.size;

    field->tTree = fd->tTree;
    field->hashTable = fd->hashTable;
    field->type = fd->type;
    field->size = fd->dbsSize;
    field->offset = fd->dbsOffs;
    field += 1;
    offs -= sizeof(dbField);
  }
}

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

void  dbAnyMethodTrampoline::operator delete(void* p EXTRA_DEBUG_NEW_PARAMS)
{
  dbFree(p);
}

dbAnyMethodTrampoline::~dbAnyMethodTrampoline()
{}

⌨️ 快捷键说明

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