示例#1
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;
}
示例#2
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;
}
示例#3
0
const std::string Index::GetInfo() const {
  std::stringstream os;

  os << "\t-----------------------------------------------------------\n";

  os << "\tINDEX\n";

  os << GetTypeName() << "\t(" << GetName() << ")";
  os << (HasUniqueKeys() ? " UNIQUE " : " NON-UNIQUE") << "\n";

  os << "\tValue schema : " << *(GetKeySchema());

  os << "\t-----------------------------------------------------------\n";

  return os.str();
}
示例#4
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;
}
// delete a tuple from all its indexes it belongs to.
void TransactionLevelGCManager::DeleteTupleFromIndexes(ItemPointer *indirection) {
  // do nothing if indirection is null
  if (indirection == nullptr){
    return;
  }
  LOG_TRACE("Deleting indirection %p from index", indirection);
  
  ItemPointer location = *indirection;

  auto &manager = catalog::Manager::GetInstance();
  auto tile_group = manager.GetTileGroup(location.block);

  PL_ASSERT(tile_group != nullptr);

  storage::DataTable *table =
    dynamic_cast<storage::DataTable *>(tile_group->GetAbstractTable());
  PL_ASSERT(table != nullptr);

  // construct the expired version.
  expression::ContainerTuple<storage::TileGroup> expired_tuple(tile_group.get(), location.offset);

  // unlink the version from all the indexes.
  for (size_t idx = 0; idx < table->GetIndexCount(); ++idx) {
    auto index = table->GetIndex(idx);
    auto index_schema = index->GetKeySchema();
    auto indexed_columns = index_schema->GetIndexedColumns();

    // build key.
    std::unique_ptr<storage::Tuple> key(
      new storage::Tuple(index_schema, true));
    key->SetFromTuple(&expired_tuple, indexed_columns, index->GetPool());

    index->DeleteEntry(key.get(), indirection);

  }
}
示例#6
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;
}
示例#7
0
oid_t IndexMetadata::GetColumnCount() const {
  return GetKeySchema()->GetColumnCount();
}