66//
77// Identification: src/codegen/deleter.cpp
88//
9- // Copyright (c) 2015-2017 , Carnegie Mellon University Database Group
9+ // Copyright (c) 2015-2018 , Carnegie Mellon University Database Group
1010//
1111// ===----------------------------------------------------------------------===//
1212
1313#include " codegen/deleter.h"
14+
1415#include " codegen/transaction_runtime.h"
1516#include " concurrency/transaction_manager_factory.h"
1617#include " storage/data_table.h"
1718
1819namespace peloton {
1920namespace codegen {
2021
21- void Deleter::Init (storage::DataTable *table,
22- executor::ExecutorContext *executor_context) {
22+ Deleter::Deleter (storage::DataTable *table,
23+ executor::ExecutorContext *executor_context)
24+ : table_(table), executor_context_(executor_context) {
2325 PELOTON_ASSERT (table != nullptr && executor_context != nullptr );
24- table_ = table;
25- executor_context_ = executor_context;
26+ }
27+
28+ void Deleter::Init (Deleter &deleter, storage::DataTable *table,
29+ executor::ExecutorContext *executor_context) {
30+ new (&deleter) Deleter (table, executor_context);
2631}
2732
2833void Deleter::Delete (uint32_t tile_group_id, uint32_t tuple_offset) {
29- PELOTON_ASSERT (table_ != nullptr && executor_context_ != nullptr );
3034 LOG_TRACE (" Deleting tuple <%u, %u> from table '%s' (db ID: %u, table ID: %u)" ,
3135 tile_group_id, tuple_offset, table_->GetName ().c_str (),
3236 table_->GetDatabaseOid (), table_->GetOid ());
@@ -36,23 +40,73 @@ void Deleter::Delete(uint32_t tile_group_id, uint32_t tuple_offset) {
3640 auto *tile_group_header = tile_group->GetHeader ();
3741
3842 auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance ();
39- auto is_owner = TransactionRuntime::IsOwner (*txn, tile_group_header,
40- tuple_offset);
41- bool acquired_ownership = false ;
42- if (is_owner == false ) {
43- acquired_ownership = TransactionRuntime::AcquireOwnership (
44- *txn, tile_group_header, tuple_offset);
45- if (!acquired_ownership)
46- return ;
43+
44+ bool is_owner = txn_manager.IsOwner (txn, tile_group_header, tuple_offset);
45+ bool is_written = txn_manager.IsWritten (txn, tile_group_header, tuple_offset);
46+
47+ ItemPointer old_location{tile_group_id, tuple_offset};
48+
49+ // Did the current transaction create this version we're deleting? If so, we
50+ // can perform the deletion without inserting a new empty version.
51+
52+ if (is_owner && is_written) {
53+ LOG_TRACE (" The current transaction is the owner of the tuple" );
54+ txn_manager.PerformDelete (txn, old_location);
55+ executor_context_->num_processed ++;
56+ return ;
4757 }
4858
59+ // We didn't create this version. In order to perform the delete, we need to
60+ // acquire ownership of the version. Let's check if we can do so.
61+
62+ bool is_ownable =
63+ is_owner || txn_manager.IsOwnable (txn, tile_group_header, tuple_offset);
64+ if (!is_ownable) {
65+ // Version is not own-able. The transaction should be aborted as we cannot
66+ // update the latest version.
67+ LOG_TRACE (" Tuple [%u-%u] isn't own-able. Failing transaction." ,
68+ tile_group_id, tuple_offset);
69+ txn_manager.SetTransactionResult (txn, ResultType::FAILURE);
70+ return ;
71+ }
72+
73+ // Version is own-able. Let's grab ownership of the version.
74+
75+ bool acquired_ownership =
76+ is_owner ||
77+ txn_manager.AcquireOwnership (txn, tile_group_header, tuple_offset);
78+ if (!acquired_ownership) {
79+ LOG_TRACE (
80+ " Failed acquiring ownership of tuple [%u-%u]. Failing transaction." ,
81+ tile_group_id, tuple_offset);
82+ txn_manager.SetTransactionResult (txn, ResultType::FAILURE);
83+ return ;
84+ }
85+
86+ // We've acquired ownership of the latest version, and it isn't locked by any
87+ // other threads. Now, let's insert an empty version.
88+
4989 ItemPointer new_location = table_->InsertEmptyVersion ();
90+
91+ // Insertion into the table may fail. PerformDelete() should not be called if
92+ // the insertion fails. At this point, we've acquired a write lock on the
93+ // version, but since it is not in the write set (since we haven't yet put it
94+ // into the write set), the acquired lock can't be released when the
95+ // transaction is aborted. The YieldOwnership() function helps us release the
96+ // acquired write lock.
97+
5098 if (new_location.IsNull ()) {
51- TransactionRuntime::YieldOwnership (*txn, tile_group_header, tuple_offset);
99+ LOG_TRACE (" Failed to insert new tuple. Failing transaction." );
100+ if (!is_owner) {
101+ // If ownership was acquired, we release it here, thus releasing the
102+ // write lock.
103+ txn_manager.YieldOwnership (txn, tile_group_header, tuple_offset);
104+ }
105+ txn_manager.SetTransactionResult (txn, ResultType::FAILURE);
52106 return ;
53107 }
54108
55- ItemPointer old_location (tile_group_id, tuple_offset);
109+ // All is well
56110 txn_manager.PerformDelete (txn, old_location, new_location);
57111 executor_context_->num_processed ++;
58112}
0 commit comments