Ejemplo n.º 1
0
std::set<oid_t> DataTable::GetIndexAttrs(const oid_t &index_offset) const {
  PL_ASSERT(index_offset < GetIndexCount());

  auto index_attrs = indexes_columns_.at(index_offset);

  return index_attrs;
}
Ejemplo n.º 2
0
bool DataTable::InsertInSecondaryIndexes(const storage::Tuple *tuple,
                                         ItemPointer location) {
  int index_count = GetIndexCount();

  // (A) Check existence for primary/unique indexes
  // FIXME Since this is NOT protected by a lock, concurrent insert may happen.
  for (int index_itr = index_count - 1; index_itr >= 0; --index_itr) {
    auto index = GetIndex(index_itr);
    auto index_schema = index->GetKeySchema();
    auto indexed_columns = index_schema->GetIndexedColumns();
    std::unique_ptr<storage::Tuple> key(new storage::Tuple(index_schema, true));
    key->SetFromTuple(tuple, indexed_columns, index->GetPool());

    switch (index->GetIndexType()) {
      case INDEX_CONSTRAINT_TYPE_PRIMARY_KEY:
        break;
      case INDEX_CONSTRAINT_TYPE_UNIQUE: {
        // if in this index there has been a visible or uncommitted
        // <key, location> pair, this constraint is violated
        index->InsertEntry(key.get(), location);
      } break;

      case INDEX_CONSTRAINT_TYPE_DEFAULT:
      default:
        index->InsertEntry(key.get(), location);
        break;
    }
    LOG_TRACE("Index constraint check on %s passed.", index->GetName().c_str());
  }
  return true;
}
Ejemplo n.º 3
0
bool DataTable::InsertInSecondaryIndexes(const AbstractTuple *tuple,
                                         const TargetList *targets_ptr,
                                         ItemPointer *index_entry_ptr) {
  int index_count = GetIndexCount();
  // Transaform the target list into a hash set
  // when attempting to perform insertion to a secondary index,
  // we must check whether the updated column is a secondary index column.
  // insertion happens only if the updated column is a secondary index column.
  std::unordered_set<oid_t> targets_set;
  for (auto target : *targets_ptr) {
    targets_set.insert(target.first);
  }

  // Check existence for primary/unique indexes
  // Since this is NOT protected by a lock, concurrent insert may happen.
  for (int index_itr = index_count - 1; index_itr >= 0; --index_itr) {
    auto index = GetIndex(index_itr);
    auto index_schema = index->GetKeySchema();
    auto indexed_columns = index_schema->GetIndexedColumns();

    if (index->GetIndexType() == INDEX_CONSTRAINT_TYPE_PRIMARY_KEY) {
      continue;
    }

    // Check if we need to update the secondary index
    bool updated = false;
    for (auto col : indexed_columns) {
      if (targets_set.find(col) != targets_set.end()) {
        updated = true;
        break;
      }
    }

    // If attributes on key are not updated, skip the index update
    if (updated == false) {
      continue;
    }

    // Key attributes are updated, insert a new entry in all secondary index
    std::unique_ptr<storage::Tuple> key(new storage::Tuple(index_schema, true));

    key->SetFromTuple(tuple, indexed_columns, index->GetPool());

    switch (index->GetIndexType()) {
      case INDEX_CONSTRAINT_TYPE_PRIMARY_KEY:
        break;
      case INDEX_CONSTRAINT_TYPE_UNIQUE:
        break;
      case INDEX_CONSTRAINT_TYPE_DEFAULT:
      default:
        index->InsertEntry(key.get(), index_entry_ptr);
        break;
    }
    LOG_TRACE("Index constraint check on %s passed.", index->GetName().c_str());
  }
  return true;
}
Ejemplo n.º 4
0
VOID D3DXMeshIndexEnumer::SetIndex( UINT uWhichIndex, DWORD dwIndex )
{
	_ASSERTE(uWhichIndex < GetIndexCount());
	BYTE* pCurIndex = m_pBuffer + m_dwNumBytePerIndex * uWhichIndex;
	if(Is32Bit())
		*reinterpret_cast<DWORD*>(pCurIndex) = dwIndex;
	else
		*reinterpret_cast<WORD*>(pCurIndex) = (WORD)dwIndex;
}
Ejemplo n.º 5
0
void BackendStatsContext::Reset() {
  txn_latencies_.Reset();

  for (auto& database_item : database_metrics_) {
    database_item.second->Reset();
  }
  for (auto& table_item : table_metrics_) {
    table_item.second->Reset();
  }
  for (auto id : index_ids_) {
    std::shared_ptr<IndexMetric> index_metric;
    index_metrics_.Find(id, index_metric);
    index_metric->Reset();
  }

  oid_t num_databases = catalog::Catalog::GetInstance()->GetDatabaseCount();
  for (oid_t i = 0; i < num_databases; ++i) {
    auto database = catalog::Catalog::GetInstance()->GetDatabaseWithOffset(i);
    oid_t database_id = database->GetOid();

    // Reset database metrics
    if (database_metrics_.find(database_id) == database_metrics_.end()) {
      database_metrics_[database_id] = std::unique_ptr<DatabaseMetric>(
          new DatabaseMetric{DATABASE_METRIC, database_id});
    }

    // Reset table metrics
    oid_t num_tables = database->GetTableCount();
    for (oid_t j = 0; j < num_tables; ++j) {
      auto table = database->GetTable(j);
      oid_t table_id = table->GetOid();

      if (table_metrics_.find(table_id) == table_metrics_.end()) {
        table_metrics_[table_id] = std::unique_ptr<TableMetric>(
            new TableMetric{TABLE_METRIC, database_id, table_id});
      }

      // Reset indexes metrics
      oid_t num_indexes = table->GetIndexCount();
      for (oid_t k = 0; k < num_indexes; ++k) {
        auto index = table->GetIndex(k);
        oid_t index_id = index->GetOid();
        if (index_metrics_.Contains(index_id) == false) {
          std::shared_ptr<IndexMetric> index_metric(
              new IndexMetric{INDEX_METRIC, database_id, table_id, index_id});
          index_metrics_.Insert(index_id, index_metric);
          index_ids_.insert(index_id);
        }
      }
    }
  }
}
Ejemplo n.º 6
0
DWORD D3DXMeshIndexEnumer::GetIndex( UINT uWhichIndex )
{
	_ASSERTE(uWhichIndex < GetIndexCount());
	BYTE* pCurIndex = m_pBuffer + m_dwNumBytePerIndex * uWhichIndex;
	if (4 == m_dwNumBytePerIndex)
	{
		return *reinterpret_cast<DWORD*>(pCurIndex);
	}
	else
	{
		return *reinterpret_cast<WORD*>(pCurIndex);
	}
}
Ejemplo n.º 7
0
void Database::UpdateStatsWithOid(const oid_t table_oid) const {
  LOG_INFO("Update table(%lu)'s stats in Database(%lu)", table_oid,
           database_oid);

  auto table = GetTableWithOid(table_oid);
  bridge::Bridge::SetNumberOfTuples(table_oid, table->GetNumberOfTuples());

  for (oid_t index_offset = 0; index_offset < table->GetIndexCount();
      index_offset++) {
    auto index = table->GetIndex(index_offset);
    bridge::Bridge::SetNumberOfTuples(index->GetOid(),
                                      index->GetNumberOfTuples());
  }
}
Ejemplo n.º 8
0
// insert tuple into a table that is without index.
ItemPointer DataTable::InsertTuple(const storage::Tuple *tuple) {
  ItemPointer location = GetEmptyTupleSlot(tuple);
  if (location.block == INVALID_OID) {
    LOG_TRACE("Failed to get tuple slot.");
    return INVALID_ITEMPOINTER;
  }

  LOG_TRACE("Location: %u, %u", location.block, location.offset);

  UNUSED_ATTRIBUTE auto index_count = GetIndexCount();
  PL_ASSERT(index_count == 0);
  // Increase the table's number of tuples by 1
  IncreaseTupleCount(1);
  return location;
}
void Terrain::Draw(ID3D11DeviceContext* context, CXMMATRIX vp)
{
	context->IASetInputLayout(Vertex::GetTerrainVertLayout());
	context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

	//XMMATRIX wvp = mHero.GetWorld()* mCam->GetView() * proj;
	XMMATRIX world = XMMatrixIdentity();
	XMMATRIX wvp = world * vp;

	mEffect->SetPerObjectParams(world, MathHelper::InverseTranspose(world),
		wvp, mDiffuseMaps[0], mDiffuseMaps[1],
		mDiffuseMaps[2], mDiffuseMaps[3], mBlendMap);

	mEffect->Draw(context, mVB, mIB, GetIndexCount());
}
Ejemplo n.º 10
0
void VertexArrayBuffer::RenderRange(IndicesRange const & range)
{
  if (!(m_staticBuffers.empty() && m_dynamicBuffers.empty()) && GetIndexCount() > 0)
  {
    ASSERT(m_program != nullptr, ("Somebody not call Build. It's very bad. Very very bad"));
    /// if OES_vertex_array_object is supported than all bindings already saved in VAO
    /// and we need only bind VAO. In Bind method have ASSERT("bind already called")
    if (GLExtensionsList::Instance().IsSupported(GLExtensionsList::VertexArrayObject))
      Bind();
    else
      BindStaticBuffers();

    BindDynamicBuffers();
    GetIndexBuffer()->Bind();
    GLFunctions::glDrawElements(dp::IndexStorage::SizeOfIndex(), range.m_idxCount, range.m_idxStart);
  }
}
Ejemplo n.º 11
0
ItemPointer DataTable::InsertTuple(const storage::Tuple *tuple,
                                   concurrency::Transaction *transaction,
                                   ItemPointer **index_entry_ptr) {
  // the upper layer may not pass a index_entry_ptr (default value: nullptr)
  // into the function.
  // in this case, we have to create a temp_ptr to hold the content.
  ItemPointer *temp_ptr = nullptr;

  if (index_entry_ptr == nullptr) {
    index_entry_ptr = &temp_ptr;
  }

  ItemPointer location = GetEmptyTupleSlot(tuple);
  if (location.block == INVALID_OID) {
    LOG_TRACE("Failed to get tuple slot.");
    return INVALID_ITEMPOINTER;
  }

  LOG_TRACE("Location: %u, %u", location.block, location.offset);

  auto index_count = GetIndexCount();
  if (index_count == 0) {
    // Increase the table's number of tuples by 1
    IncreaseTupleCount(1);
    return location;
  }
  // Index checks and updates
  if (InsertInIndexes(tuple, location, transaction, index_entry_ptr) == false) {
    LOG_TRACE("Index constraint violated");
    return INVALID_ITEMPOINTER;
  }

  // ForeignKey checks
  if (CheckForeignKeyConstraints(tuple) == false) {
    LOG_TRACE("ForeignKey constraint violated");
    return INVALID_ITEMPOINTER;
  }

  PL_ASSERT((*index_entry_ptr)->block == location.block &&
            (*index_entry_ptr)->offset == location.offset);

  // Increase the table's number of tuples by 1
  IncreaseTupleCount(1);

  return location;
}
Ejemplo n.º 12
0
/**
 * @brief Insert a tuple into all indexes. If index is primary/unique,
 * check visibility of existing
 * index entries.
 * @warning This still doesn't guarantee serializability.
 *
 * @returns True on success, false if a visible entry exists (in case of
 *primary/unique).
 */
bool DataTable::InsertInIndexes(const storage::Tuple *tuple,
                                ItemPointer location) {
  int index_count = GetIndexCount();
  auto &transaction_manager =
      concurrency::TransactionManagerFactory::GetInstance();

  std::function<bool(const ItemPointer &)> fn =
      std::bind(&concurrency::TransactionManager::IsOccupied,
                &transaction_manager, std::placeholders::_1);

  // (A) Check existence for primary/unique indexes
  // FIXME Since this is NOT protected by a lock, concurrent insert may happen.
  for (int index_itr = index_count - 1; index_itr >= 0; --index_itr) {
    auto index = GetIndex(index_itr);
    auto index_schema = index->GetKeySchema();
    auto indexed_columns = index_schema->GetIndexedColumns();
    std::unique_ptr<storage::Tuple> key(new storage::Tuple(index_schema, true));
    key->SetFromTuple(tuple, indexed_columns, index->GetPool());

    switch (index->GetIndexType()) {
      case INDEX_CONSTRAINT_TYPE_PRIMARY_KEY:
      case INDEX_CONSTRAINT_TYPE_UNIQUE: {
        // TODO: get unique tuple from primary index.
        // if in this index there has been a visible or uncommitted
        // <key, location> pair, this constraint is violated
        if (index->CondInsertEntry(key.get(), location, fn) == false) {
          return false;
        }

      } break;

      case INDEX_CONSTRAINT_TYPE_DEFAULT:
      default:
        index->InsertEntry(key.get(), location);
        break;
    }
    LOG_TRACE("Index constraint check on %s passed.", index->GetName().c_str());
  }

  return true;
}
void PlaneModelClass::RenderBuffers(ID3D11DeviceContext* deviceContext)
{
	unsigned int stride;
	unsigned int offset;

	// Set vertex buffer stride and offset.
	stride = sizeof(VertexNorm); 
	offset = 0;
    
	// Set the vertex buffer to active in the input assembler so it can be rendered.
	deviceContext->IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &offset);

    // Set the index buffer to active in the input assembler so it can be rendered.
	deviceContext->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R32_UINT, 0);

    // Set the type of primitive that should be rendered from this vertex buffer, in this case triangles.
	deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

	// Render indexed primitives
	deviceContext->DrawIndexed(GetIndexCount(), 0, 0);

	return;
}
Ejemplo n.º 14
0
//--------------------------------------------------------------------------------
void GeometryDX11::LoadToBuffers( ID3D11Device* pDevice )
{
	// Check the size of the assembled vertices
	CalculateVertexSize();

	// Load the vertex buffer first by calculating the required size
	unsigned int vertices_length = GetVertexSize() * GetVertexCount();

	char* pBytes = new char[vertices_length];

	for ( int j = 0; j < m_iVertexCount; j++ )
	{
		int iElemOffset = 0;
		for ( int i = 0; i < m_vElements.count(); i++ )
		{
			memcpy( pBytes + j * m_iVertexSize + iElemOffset, m_vElements[i]->GetPtr(j), m_vElements[i]->SizeInBytes() );
			iElemOffset += m_vElements[i]->SizeInBytes();
		}
	}


	D3D11_SUBRESOURCE_DATA data;
	data.pSysMem = reinterpret_cast<void*>( pBytes );
	data.SysMemPitch = 0;
	data.SysMemSlicePitch = 0;

	D3D11_BUFFER_DESC vbuffer;
	vbuffer.ByteWidth = vertices_length;
    vbuffer.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    vbuffer.MiscFlags = 0;
    vbuffer.StructureByteStride = 0;
	vbuffer.Usage = D3D11_USAGE_IMMUTABLE;
	vbuffer.CPUAccessFlags = 0;
    vbuffer.StructureByteStride = 0;

	pDevice->CreateBuffer( &vbuffer, &data, &m_pVertexBuffer );

	delete [] pBytes; 
	// TODO: add error checking here!

	
	// Load the index buffer by calculating the required size
	// based on the number of indices.

	data.pSysMem = reinterpret_cast<void*>( &m_vIndices[0] );
	data.SysMemPitch = 0;
	data.SysMemSlicePitch = 0;
	
	D3D11_BUFFER_DESC ibuffer;

	ibuffer.ByteWidth = sizeof( unsigned int ) * GetIndexCount();
    ibuffer.BindFlags = D3D11_BIND_INDEX_BUFFER;
    ibuffer.MiscFlags = 0;
    ibuffer.StructureByteStride = 0;
	ibuffer.Usage = D3D11_USAGE_IMMUTABLE;
	ibuffer.CPUAccessFlags = 0;
    ibuffer.StructureByteStride = 0;

	pDevice->CreateBuffer( &ibuffer, &data, &m_pIndexBuffer );
	//m_iIB = RendererDX11::Get()->CreateIndexBuffer( &ibuffer, &data );
}
Ejemplo n.º 15
0
 /// \brief
 ///   Returns the number of surfaces in this mesh.
 inline int GetCollisionSurfaceCount() const
 {
   return GetIndexCount() / 3;
 }
Ejemplo n.º 16
0
TEST_F(CreateIndexTests, CreatingIndex) {
  LOG_INFO("Bootstrapping...");
  auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
  auto txn = txn_manager.BeginTransaction();
  catalog::Catalog::GetInstance()->CreateDatabase(DEFAULT_DB_NAME, txn);
  txn_manager.CommitTransaction(txn);
  LOG_INFO("Bootstrapping completed!");

  std::unique_ptr<optimizer::AbstractOptimizer> optimizer;
  optimizer.reset(new optimizer::Optimizer);

  auto &traffic_cop = tcop::TrafficCop::GetInstance();
  traffic_cop.SetTaskCallback(TestingSQLUtil::UtilTestTaskCallback,
                              &TestingSQLUtil::counter_);

  // Create a table first
  txn = txn_manager.BeginTransaction();
  traffic_cop.SetTcopTxnState(txn);
  LOG_INFO("Creating table");
  LOG_INFO(
      "Query: CREATE TABLE department_table(dept_id INT PRIMARY KEY,student_id "
      "INT, dept_name TEXT);");
  std::unique_ptr<Statement> statement;
  statement.reset(new Statement("CREATE",
                                "CREATE TABLE department_table(dept_id INT "
                                "PRIMARY KEY, student_id INT, dept_name "
                                "TEXT);"));

  auto &peloton_parser = parser::PostgresParser::GetInstance();

  LOG_INFO("Building parse tree...");
  auto create_stmt = peloton_parser.BuildParseTree(
      "CREATE TABLE department_table(dept_id INT PRIMARY KEY, student_id INT, "
      "dept_name TEXT);");
  LOG_INFO("Building parse tree completed!");

  LOG_INFO("Binding parse tree...");
  auto parse_tree = create_stmt->GetStatement(0);
  auto bind_node_visitor = binder::BindNodeVisitor(txn, DEFAULT_DB_NAME);
  bind_node_visitor.BindNameToNode(parse_tree);
  LOG_INFO("Binding parse tree completed!");

  LOG_INFO("Building plan tree...");
  statement->SetPlanTree(optimizer->BuildPelotonPlanTree(create_stmt, txn));
  LOG_INFO("Building plan tree completed!");

  std::vector<type::Value> params;
  std::vector<ResultValue> result;
  LOG_INFO("Executing plan...\n%s",
           planner::PlanUtil::GetInfo(statement->GetPlanTree().get()).c_str());
  std::vector<int> result_format;
  result_format = std::vector<int>(statement->GetTupleDescriptor().size(), 0);

  TestingSQLUtil::counter_.store(1);
  executor::ExecutionResult status = traffic_cop.ExecuteHelper(
      statement->GetPlanTree(), params, result, result_format);

  if (traffic_cop.GetQueuing()) {
    TestingSQLUtil::ContinueAfterComplete();
    traffic_cop.ExecuteStatementPlanGetResult();
    status = traffic_cop.p_status_;
    traffic_cop.SetQueuing(false);
  }

  LOG_INFO("Statement executed. Result: %s",
           ResultTypeToString(status.m_result).c_str());
  LOG_INFO("Table Created");
  traffic_cop.CommitQueryHelper();

  txn = txn_manager.BeginTransaction();
  // Inserting a tuple end-to-end
  traffic_cop.SetTcopTxnState(txn);
  LOG_INFO("Inserting a tuple...");
  LOG_INFO(
      "Query: INSERT INTO department_table(dept_id,student_id ,dept_name) "
      "VALUES (1,52,'hello_1');");
  statement.reset(new Statement("INSERT",
                                "INSERT INTO department_table(dept_id, "
                                "student_id, dept_name) VALUES "
                                "(1,52,'hello_1');"));

  LOG_INFO("Building parse tree...");
  auto insert_stmt = peloton_parser.BuildParseTree(
      "INSERT INTO department_table(dept_id,student_id,dept_name) VALUES "
      "(1,52,'hello_1');");
  LOG_INFO("Building parse tree completed!");

  LOG_INFO("Binding parse tree...");
  parse_tree = insert_stmt->GetStatement(0);
  bind_node_visitor = binder::BindNodeVisitor(txn, DEFAULT_DB_NAME);
  bind_node_visitor.BindNameToNode(parse_tree);
  LOG_INFO("Binding parse tree completed!");

  LOG_INFO("Building plan tree...");
  statement->SetPlanTree(optimizer->BuildPelotonPlanTree(insert_stmt, txn));
  LOG_INFO("Building plan tree completed!\n%s",
           planner::PlanUtil::GetInfo(statement->GetPlanTree().get()).c_str());

  LOG_INFO("Executing plan...");
  result_format = std::vector<int>(statement->GetTupleDescriptor().size(), 0);

  TestingSQLUtil::counter_.store(1);
  status = traffic_cop.ExecuteHelper(statement->GetPlanTree(), params, result,
                                     result_format);

  if (traffic_cop.GetQueuing()) {
    TestingSQLUtil::ContinueAfterComplete();
    traffic_cop.ExecuteStatementPlanGetResult();
    status = traffic_cop.p_status_;
    traffic_cop.SetQueuing(false);
  }
  LOG_INFO("Statement executed. Result: %s",
           ResultTypeToString(status.m_result).c_str());
  LOG_INFO("Tuple inserted!");
  traffic_cop.CommitQueryHelper();

  // Now Updating end-to-end
  txn = txn_manager.BeginTransaction();
  traffic_cop.SetTcopTxnState(txn);
  LOG_INFO("Creating and Index");
  LOG_INFO("Query: CREATE INDEX saif ON department_table (student_id);");
  statement.reset(new Statement(
      "CREATE", "CREATE INDEX saif ON department_table (student_id);"));

  LOG_INFO("Building parse tree...");
  auto update_stmt = peloton_parser.BuildParseTree(
      "CREATE INDEX saif ON department_table (student_id);");
  LOG_INFO("Building parse tree completed!");

  LOG_INFO("Binding parse tree...");
  parse_tree = update_stmt->GetStatement(0);
  bind_node_visitor = binder::BindNodeVisitor(txn, DEFAULT_DB_NAME);
  bind_node_visitor.BindNameToNode(parse_tree);
  LOG_INFO("Binding parse tree completed!");

  LOG_INFO("Building plan tree...");
  statement->SetPlanTree(optimizer->BuildPelotonPlanTree(update_stmt, txn));
  LOG_INFO("Building plan tree completed!\n%s",
           planner::PlanUtil::GetInfo(statement->GetPlanTree().get()).c_str());

  LOG_INFO("Executing plan...");
  result_format = std::vector<int>(statement->GetTupleDescriptor().size(), 0);

  TestingSQLUtil::counter_.store(1);
  status = traffic_cop.ExecuteHelper(statement->GetPlanTree(), params, result,
                                     result_format);

  if (traffic_cop.GetQueuing()) {
    TestingSQLUtil::ContinueAfterComplete();
    traffic_cop.ExecuteStatementPlanGetResult();
    status = traffic_cop.p_status_;
    traffic_cop.SetQueuing(false);
  }
  LOG_INFO("Statement executed. Result: %s",
           ResultTypeToString(status.m_result).c_str());
  LOG_INFO("INDEX CREATED!");
  traffic_cop.CommitQueryHelper();

  txn = txn_manager.BeginTransaction();
  auto target_table_ = catalog::Catalog::GetInstance()->GetTableWithName(
      DEFAULT_DB_NAME, DEFUALT_SCHEMA_NAME, "department_table", txn);
  // Expected 2 , Primary key index + created index
  EXPECT_EQ(target_table_->GetIndexCount(), 2);

  // free the database just created
  catalog::Catalog::GetInstance()->DropDatabaseWithName(DEFAULT_DB_NAME, txn);
  txn_manager.CommitTransaction(txn);
}
Ejemplo n.º 17
0
UInt PointMesh::GetPointCount() const
{
    if ( m_pIB == NULL )
        return GetVertexCount();
    return GetIndexCount();
}
Ejemplo n.º 18
0
/**
 * @brief Insert a tuple into all indexes. If index is primary/unique,
 * check visibility of existing
 * index entries.
 * @warning This still doesn't guarantee serializability.
 *
 * @returns True on success, false if a visible entry exists (in case of
 *primary/unique).
 */
bool DataTable::InsertInIndexes(const storage::Tuple *tuple,
                                ItemPointer location,
                                concurrency::Transaction *transaction,
                                ItemPointer **index_entry_ptr) {

  int index_count = GetIndexCount();

  size_t active_indirection_array_id = number_of_tuples_ % ACTIVE_INDIRECTION_ARRAY_COUNT;

  size_t indirection_offset = INVALID_INDIRECTION_OFFSET;
  
  while (true) {
    auto active_indirection_array = active_indirection_arrays_[active_indirection_array_id];
    indirection_offset = active_indirection_array->AllocateIndirection();

    if (indirection_offset != INVALID_INDIRECTION_OFFSET) {
      *index_entry_ptr = active_indirection_array->GetIndirectionByOffset(indirection_offset);
      break;
    }
  }

  (*index_entry_ptr)->block = location.block;
  (*index_entry_ptr)->offset = location.offset;

  if (indirection_offset == INDIRECTION_ARRAY_MAX_SIZE - 1) {
    AddDefaultIndirectionArray(active_indirection_array_id);
  }

  auto &transaction_manager =
      concurrency::TransactionManagerFactory::GetInstance();

  std::function<bool(const void *)> fn =
      std::bind(&concurrency::TransactionManager::IsOccupied,
                &transaction_manager, transaction, std::placeholders::_1);

  // Since this is NOT protected by a lock, concurrent insert may happen.
  bool res = true;
  int success_count = 0;

  for (int index_itr = index_count - 1; index_itr >= 0; --index_itr) {
    auto index = GetIndex(index_itr);
    auto index_schema = index->GetKeySchema();
    auto indexed_columns = index_schema->GetIndexedColumns();
    std::unique_ptr<storage::Tuple> key(new storage::Tuple(index_schema, true));
    key->SetFromTuple(tuple, indexed_columns, index->GetPool());

    switch (index->GetIndexType()) {
      case INDEX_CONSTRAINT_TYPE_PRIMARY_KEY: {
        // get unique tuple from primary index.
        // if in this index there has been a visible or uncommitted
        // <key, location> pair, this constraint is violated
        res = index->CondInsertEntry(key.get(), *index_entry_ptr, fn);
      } break;
      case INDEX_CONSTRAINT_TYPE_UNIQUE: {
        // get unique tuple from primary index.
        // if in this index there has been a visible or uncommitted
        // <key, location> pair, this constraint is violated
        // res = index->CondInsertEntry(key.get(), *index_entry_ptr, fn);
      } break;

      case INDEX_CONSTRAINT_TYPE_DEFAULT:
      default:
        index->InsertEntry(key.get(), *index_entry_ptr);
        break;
    }

    // Handle failure
    if (res == false) {
      // If some of the indexes have been inserted,
      // the pointer has a chance to be dereferenced by readers and it cannot be deleted
      *index_entry_ptr = nullptr;
      return false;
    } else {
      success_count += 1;
    }
    LOG_TRACE("Index constraint check on %s passed.", index->GetName().c_str());
  }

  return true;
}
Ejemplo n.º 19
0
UInt LineListMesh::GetLineCount() const
{
    if ( m_pIB == NULL )
        return ( GetVertexCount() >> 1 );
    return ( GetIndexCount() >> 1 );
}
Ejemplo n.º 20
0
UInt LineStripMesh::GetLineCount() const
{
    if ( m_pIB == NULL )
        return ( GetVertexCount() - 1 );
    return ( GetIndexCount() - 1 );
}
Ejemplo n.º 21
0
UInt TriangleListMesh::GetTriangleCount() const
{
    if ( m_pIB == NULL )
        return ( GetVertexCount() / 3 );
    return ( GetIndexCount() / 3 );
}
Ejemplo n.º 22
0
UInt TriangleStripMesh::GetTriangleCount() const
{
    if ( m_pIB == NULL )
        return ( GetVertexCount() - 2 );
    return ( GetIndexCount() - 2 );
}
Ejemplo n.º 23
0
    void ModelDefinition::Serialize(Serializer &serializer) const
    {
        BasicSerializer intermediarySerializer;


        /////////////////////////////////////
        // Bones

        intermediarySerializer.Write(static_cast<uint32_t>(m_bones.count));
        
        // Local information.
        for (size_t iBone = 0; iBone < m_bones.count; ++iBone)
        {
            auto bone = m_bones[iBone];
            assert(bone != nullptr);
            {
                // Name.
                intermediarySerializer.WriteString(bone->GetName());

                // Relative transformation.
                intermediarySerializer.Write(bone->GetPosition());
                intermediarySerializer.Write(bone->GetRotation());
                intermediarySerializer.Write(bone->GetScale());

                // 4x4 offset matrix.
                intermediarySerializer.Write(bone->GetOffsetMatrix());
            }
        }

        // Parents. -1 for bones without parents.
        for (size_t iBone = 0; iBone < m_bones.count; ++iBone)
        {
            auto bone = m_bones[iBone];
            assert(bone != nullptr);
            {
                auto parentBone = bone->GetParent();
                if (parentBone != nullptr)
                {
                    size_t parentBoneIndex;
                    if (!this->FindBoneIndex(parentBone, parentBoneIndex))
                    {
                        assert(false);
                    }
                    
                    intermediarySerializer.Write(static_cast<uint32_t>(parentBoneIndex));
                }
                else
                {
                    intermediarySerializer.Write(static_cast<uint32_t>(-1));
                }
            }
        }

        Serialization::ChunkHeader header;
        header.id          = Serialization::ChunkID_Model_Bones;
        header.version     = 1;
        header.sizeInBytes = intermediarySerializer.GetBufferSizeInBytes();
        serializer.Write(header);
        serializer.Write(intermediarySerializer.GetBuffer(), header.sizeInBytes);



        /////////////////////////////////////
        // Meshes
        //
        // Vertex data is always saved in P3T2N3T3B3 format. Bones are referenced using an integer to index into the list of bones defined above.

        intermediarySerializer.Clear();
        intermediarySerializer.Write(static_cast<uint32_t>(this->meshes.count));

        for (size_t iMesh = 0; iMesh < this->meshes.count; ++iMesh)
        {
            // Name.
            intermediarySerializer.WriteString(this->meshes[iMesh].name);


            // Material.
            intermediarySerializer.WriteString(this->meshes[iMesh].material->GetDefinition().relativePath);


            // Vertices.
            auto vertexArray = this->meshes[iMesh].geometry;
            assert(vertexArray != nullptr);
            {
                // Vertex Format.
                vertexArray->GetFormat().Serialize(intermediarySerializer);


                // Vertices.
                intermediarySerializer.Write(static_cast<uint32_t>(vertexArray->GetVertexCount()));

                if (vertexArray->GetVertexCount() > 0)
                {
                    intermediarySerializer.Write(vertexArray->GetVertexDataPtr(), vertexArray->GetFormat().GetSizeInBytes() * vertexArray->GetVertexCount());
                }


                // Indices.
                intermediarySerializer.Write(static_cast<uint32_t>(vertexArray->GetIndexCount()));

                if (vertexArray->GetIndexCount() > 0)
                {
                    intermediarySerializer.Write(vertexArray->GetIndexDataPtr(), sizeof(uint32_t) * vertexArray->GetIndexCount());
                }


                // Skinning Vertex Attributes.
                if (this->meshes[iMesh].skinningVertexAttributes != nullptr)
                {
                    intermediarySerializer.Write(static_cast<uint32_t>(vertexArray->GetVertexCount()));

                    if (vertexArray->GetVertexCount() > 0)
                    {
                        uint32_t totalBoneWeights = 0;


                        // Bone Counts.
                        for (size_t iVertex = 0; iVertex < vertexArray->GetVertexCount(); ++iVertex)
                        {
                            uint16_t count = static_cast<uint16_t>(this->meshes[iMesh].skinningVertexAttributes[iVertex].bones.count);
                            intermediarySerializer.Write(count);

                            totalBoneWeights += count;
                        }

                            
                        // Bone/Weight Pairs.
                        intermediarySerializer.Write(totalBoneWeights);

                        for (size_t iVertex = 0; iVertex < vertexArray->GetVertexCount(); ++iVertex)
                        {
                            auto &bones = this->meshes[iMesh].skinningVertexAttributes[iVertex].bones;
                            {
                                for (size_t iBone = 0; iBone < bones.count; ++iBone)
                                {
                                    auto &bone = bones[iBone];

                                    intermediarySerializer.Write(static_cast<uint32_t>(bone.boneIndex));
                                    intermediarySerializer.Write(static_cast<float   >(bone.weight));
                                }
                            }
                        }
                    }
                }
                else
                {
                    intermediarySerializer.Write(static_cast<uint32_t>(0));
                }


                // Default uniforms.
                this->meshes[iMesh].defaultUniforms.Serialize(intermediarySerializer);
            }
        }

        header.id          = Serialization::ChunkID_Model_Meshes;
        header.version     = 1;
        header.sizeInBytes = intermediarySerializer.GetBufferSizeInBytes();
        serializer.Write(header);
        serializer.Write(intermediarySerializer.GetBuffer(), header.sizeInBytes);



        /////////////////////////////////////
        // Animation

        intermediarySerializer.Clear();
        intermediarySerializer.Write(static_cast<uint32_t>(m_animation.GetKeyFrameCount()));

        for (uint32_t iKeyFrame = 0; iKeyFrame < m_animation.GetKeyFrameCount(); ++iKeyFrame)
        {
            // Time.
            intermediarySerializer.Write(static_cast<float>(m_animation.GetKeyFrameTimeByIndex(iKeyFrame)));
            
            
            // Channels.
            intermediarySerializer.Write(static_cast<uint32_t>(this->animationChannelBones.count));

            for (size_t iChannel = 0; iChannel < this->animationChannelBones.count; ++iChannel)
            {
                auto channel = this->animationChannelBones.buffer[iChannel]->value;
                auto bone    = this->animationChannelBones.buffer[iChannel]->key;

                assert(channel != nullptr);
                assert(bone    != nullptr);
                {
                    // Bone Index.
                    size_t boneIndex;
                    this->FindBoneIndex(bone, boneIndex);

                    intermediarySerializer.Write(static_cast<uint32_t>(boneIndex));


                    // Bone Transformation.
                    glm::vec3 position;
                    glm::quat rotation;
                    glm::vec3 scale;

                    auto key = static_cast<TransformAnimationKey*>(channel->GetKey(iKeyFrame));
                    if (key != nullptr)
                    {
                        position = key->position;
                        rotation = key->rotation;
                        scale    = key->scale;
                    }
                    else
                    {
                        // We should never actually get here, but for completeness we'll just write identities.
                        position = bone->GetPosition();
                        rotation = bone->GetRotation();
                        scale    = bone->GetScale();
                    }

                    intermediarySerializer.Write(position);
                    intermediarySerializer.Write(rotation);
                    intermediarySerializer.Write(scale);
                }
            }
        }

        intermediarySerializer.Write(this->animationAABBPadding);


        header.id          = Serialization::ChunkID_Model_Animation;
        header.version     = 1;
        header.sizeInBytes = intermediarySerializer.GetBufferSizeInBytes();
        serializer.Write(header);
        serializer.Write(intermediarySerializer.GetBuffer(), header.sizeInBytes);



        /////////////////////////////////////
        // Animation Segments

        intermediarySerializer.Clear();
        intermediarySerializer.Write(static_cast<uint32_t>(m_animation.GetNamedSegmentCount()));

        for (size_t iSegment = 0; iSegment < m_animation.GetNamedSegmentCount(); ++iSegment)
        {
            auto segment = m_animation.GetNamedSegmentByIndex(iSegment);
            assert(segment != nullptr);
            {
                intermediarySerializer.WriteString(segment->name);
                intermediarySerializer.Write(static_cast<uint32_t>(segment->startKeyFrame));
                intermediarySerializer.Write(static_cast<uint32_t>(segment->endKeyFrame));
            }
        }

        header.id          = Serialization::ChunkID_Model_AnimationSegments;
        header.version     = 1;
        header.sizeInBytes = intermediarySerializer.GetBufferSizeInBytes();
        serializer.Write(header);
        serializer.Write(intermediarySerializer.GetBuffer(), header.sizeInBytes);



        /////////////////////////////////////
        // Animation Sequences

        /*
        intermediarySerializer.Clear();
        intermediarySerializer.Write(static_cast<uint32_t>(this->animationSequences.count));

        for (size_t iSequence = 0; iSequence < this->animationSequences.count; ++iSequence)
        {
        }

        header.id          = Serialization::ChunkID_Model_AnimationSequences;
        header.version     = 1;
        header.sizeInBytes = intermediarySerializer.GetBufferSizeInBytes();
        serializer.Write(header);
        serializer.Write(intermediarySerializer.GetBuffer(), header.sizeInBytes);
        */


        /////////////////////////////////////
        // Convex Hulls

        intermediarySerializer.Clear();
        intermediarySerializer.Write(static_cast<uint32_t>(m_convexHulls.count));

        Vector<uint32_t> vertexCounts(m_convexHulls.count);
        Vector<uint32_t> indexCounts( m_convexHulls.count);
        Vector<float>    vertices;
        Vector<uint32_t> indices;

        for (size_t iConvexHull = 0; iConvexHull < m_convexHulls.count; ++iConvexHull)
        {
            auto convexHull = m_convexHulls[iConvexHull];
            assert(convexHull != nullptr);
            {
                uint32_t vertexCount = static_cast<uint32_t>(convexHull->GetVertexCount());
                uint32_t indexCount  = static_cast<uint32_t>(convexHull->GetIndexCount());

                vertexCounts.PushBack(vertexCount);
                indexCounts.PushBack( indexCount);

                for (uint32_t iVertex = 0; iVertex < vertexCount; ++iVertex)
                {
                    vertices.PushBack(convexHull->GetVertices()[iVertex * 3 + 0]);
                    vertices.PushBack(convexHull->GetVertices()[iVertex * 3 + 1]);
                    vertices.PushBack(convexHull->GetVertices()[iVertex * 3 + 2]);
                }

                for (uint32_t iIndex = 0; iIndex < indexCount; ++iIndex)
                {
                    indices.PushBack(convexHull->GetIndices()[iIndex]);
                }
            }
        }

        intermediarySerializer.Write(vertexCounts.buffer, vertexCounts.count * 4);
        intermediarySerializer.Write(indexCounts.buffer,  indexCounts.count  * 4);

        intermediarySerializer.Write(static_cast<uint32_t>(vertices.count));
        intermediarySerializer.Write(static_cast<uint32_t>(indices.count));

        intermediarySerializer.Write(vertices.buffer, vertices.count * 4);
        intermediarySerializer.Write(indices.buffer,  indices.count  * 4);

        intermediarySerializer.Write(this->convexHullBuildSettings);


        header.id          = Serialization::ChunkID_Model_ConvexHulls;
        header.version     = 1;
        header.sizeInBytes = intermediarySerializer.GetBufferSizeInBytes();
        serializer.Write(header);
        serializer.Write(intermediarySerializer.GetBuffer(), header.sizeInBytes);



        /////////////////////////////////////
        // Null Chunk

        header.id          = Serialization::ChunkID_Null;
        header.version     = 1;
        header.sizeInBytes = 0;
        serializer.Write(header);
    }