6
6
//
7
7
// Identification: src/codegen/deleter.cpp
8
8
//
9
- // Copyright (c) 2015-2017 , Carnegie Mellon University Database Group
9
+ // Copyright (c) 2015-2018 , Carnegie Mellon University Database Group
10
10
//
11
11
// ===----------------------------------------------------------------------===//
12
12
13
13
#include " codegen/deleter.h"
14
+
14
15
#include " codegen/transaction_runtime.h"
15
16
#include " concurrency/transaction_manager_factory.h"
16
17
#include " storage/data_table.h"
17
18
18
19
namespace peloton {
19
20
namespace codegen {
20
21
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) {
23
25
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);
26
31
}
27
32
28
33
void Deleter::Delete (uint32_t tile_group_id, uint32_t tuple_offset) {
29
- PELOTON_ASSERT (table_ != nullptr && executor_context_ != nullptr );
30
34
LOG_TRACE (" Deleting tuple <%u, %u> from table '%s' (db ID: %u, table ID: %u)" ,
31
35
tile_group_id, tuple_offset, table_->GetName ().c_str (),
32
36
table_->GetDatabaseOid (), table_->GetOid ());
@@ -36,23 +40,73 @@ void Deleter::Delete(uint32_t tile_group_id, uint32_t tuple_offset) {
36
40
auto *tile_group_header = tile_group->GetHeader ();
37
41
38
42
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 ;
47
57
}
48
58
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
+
49
89
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
+
50
98
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);
52
106
return ;
53
107
}
54
108
55
- ItemPointer old_location (tile_group_id, tuple_offset);
109
+ // All is well
56
110
txn_manager.PerformDelete (txn, old_location, new_location);
57
111
executor_context_->num_processed ++;
58
112
}
0 commit comments