Skip to content
This repository was archived by the owner on Sep 27, 2019. It is now read-only.

Commit 7df6cb6

Browse files
authored
Merge pull request #1337 from pmenon/fix-delete-1336
Fix for #1336
2 parents d68ab71 + bff435f commit 7df6cb6

File tree

2 files changed

+76
-22
lines changed

2 files changed

+76
-22
lines changed

src/codegen/deleter.cpp

Lines changed: 70 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,31 @@
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

1819
namespace peloton {
1920
namespace 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

2833
void 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
}

src/include/codegen/deleter.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,20 @@ namespace codegen {
3838
// class is initialized once (through Init()) outside the main loop.
3939
class Deleter {
4040
public:
41+
// Constructor
42+
Deleter(storage::DataTable *table,
43+
executor::ExecutorContext *executor_context);
44+
4145
// Initializer this deleter instance using the provided transaction and table.
4246
// All tuples to be deleted occur within the provided transaction are from
4347
// the provided table
44-
void Init(storage::DataTable *table,
45-
executor::ExecutorContext *executor_context);
48+
static void Init(Deleter &deleter, storage::DataTable *table,
49+
executor::ExecutorContext *executor_context);
4650

4751
// Delete the tuple within the provided tile group ID (unique) at the provided
4852
// offset from the start of the tile group.
4953
void Delete(uint32_t tile_group_id, uint32_t tuple_offset);
5054

51-
private:
52-
// Can't construct
53-
Deleter() : table_(nullptr), executor_context_(nullptr) {}
54-
5555
private:
5656
// The table the tuples are deleted from
5757
storage::DataTable *table_;

0 commit comments

Comments
 (0)