/** * Apply the column delta on the rollback segment to the given tuple */ void TileGroup::ApplyRollbackSegment(char *rb_seg, const oid_t &tuple_slot_id) { auto seg_col_count = storage::RollbackSegmentPool::GetColCount(rb_seg); auto table_schema = GetAbstractTable()->GetSchema(); for (size_t idx = 0; idx < seg_col_count; ++idx) { auto col_id = storage::RollbackSegmentPool::GetIdOffsetPair(rb_seg, idx)->col_id; Value col_value = storage::RollbackSegmentPool::GetValue(rb_seg, table_schema, idx); // Get target tile auto tile_id = GetTileIdFromColumnId(col_id); PL_ASSERT(tile_id < GetTileCount()); storage::Tile *tile = GetTile(tile_id); PL_ASSERT(tile); // Get tile schema auto &tile_schema = tile_schemas[tile_id]; // Get a tuple wrapper char *tile_tuple_location = tile->GetTupleLocation(tuple_slot_id); PL_ASSERT(tile_tuple_location); storage::Tuple tile_tuple(&tile_schema, tile_tuple_location); // Write the value to tuple auto tile_col_idx = GetTileColumnId(col_id); tile_tuple.SetValue(tile_col_idx, col_value, tile->GetPool()); } }
storage::TileGroup *DataTable::TransformTileGroup( const oid_t &tile_group_offset, const double &theta) { // First, check if the tile group is in this table if (tile_group_offset >= tile_groups_.GetSize()) { LOG_ERROR("Tile group offset not found in table : %u ", tile_group_offset); return nullptr; } auto tile_group_id = tile_groups_.FindValid(tile_group_offset, invalid_tile_group_id); // Get orig tile group from catalog auto &catalog_manager = catalog::Manager::GetInstance(); auto tile_group = catalog_manager.GetTileGroup(tile_group_id); auto diff = tile_group->GetSchemaDifference(default_partition_); // Check threshold for transformation if (diff < theta) { return nullptr; } LOG_TRACE("Transforming tile group : %u", tile_group_offset); // Get the schema for the new transformed tile group auto new_schema = TransformTileGroupSchema(tile_group.get(), default_partition_); // Allocate space for the transformed tile group std::shared_ptr<storage::TileGroup> new_tile_group( TileGroupFactory::GetTileGroup( tile_group->GetDatabaseId(), tile_group->GetTableId(), tile_group->GetTileGroupId(), tile_group->GetAbstractTable(), new_schema, default_partition_, tile_group->GetAllocatedTupleCount())); // Set the transformed tile group column-at-a-time SetTransformedTileGroup(tile_group.get(), new_tile_group.get()); // Set the location of the new tile group // and clean up the orig tile group catalog_manager.AddTileGroup(tile_group_id, new_tile_group); return new_tile_group.get(); }
// Multiple GC thread share the same recycle map void TransactionLevelGCManager::AddToRecycleMap(std::shared_ptr<GarbageContext> garbage_ctx) { for (auto &entry : *(garbage_ctx->gc_set_.get())) { auto &manager = catalog::Manager::GetInstance(); auto tile_group = manager.GetTileGroup(entry.first); // During the resetting, a table may deconstruct because of the DROP TABLE request if (tile_group == nullptr) { return; } PL_ASSERT(tile_group != nullptr); storage::DataTable *table = dynamic_cast<storage::DataTable *>(tile_group->GetAbstractTable()); PL_ASSERT(table != nullptr); oid_t table_id = table->GetOid(); for (auto &element : entry.second) { // as this transaction has been committed, we should reclaim older versions. ItemPointer location(entry.first, element.first); // If the tuple being reset no longer exists, just skip it if (ResetTuple(location) == false) { continue; } // if the entry for table_id exists. PL_ASSERT(recycle_queue_map_.find(table_id) != recycle_queue_map_.end()); recycle_queue_map_[table_id]->Enqueue(location); } } }
// 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); } }