void GCManager::AddToRecycleMap(TupleMetadata tuple_metadata) { // If the tuple being reset no longer exists, just skip it if (ResetTuple(tuple_metadata) == false) return; // Add to the recycle map std::shared_ptr<LockfreeQueue<TupleMetadata>> recycle_queue; // if the entry for table_id exists. if (recycle_queue_map_.find(tuple_metadata.table_id, recycle_queue) == true) { // if the entry for tuple_metadata.table_id exists. recycle_queue->Dequeue(tuple_metadata); } else { // if the entry for tuple_metadata.table_id does not exist. recycle_queue.reset( new LockfreeQueue<TupleMetadata>(MAX_QUEUE_LENGTH)); bool ret = recycle_queue_map_.insert(tuple_metadata.table_id, recycle_queue); if (ret == true) { recycle_queue->Dequeue(tuple_metadata); } else { recycle_queue_map_.find(tuple_metadata.table_id, recycle_queue); recycle_queue->Dequeue(tuple_metadata); } } }
// 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); } } }