From 8e084a53f2b75ec2fefd2583b6c79462cdd23ae5 Mon Sep 17 00:00:00 2001 From: mbutrovich Date: Fri, 1 Jun 2018 23:30:59 -0400 Subject: [PATCH 01/16] Refactor of transaction_context to reduce lookups. --- src/concurrency/transaction_context.cpp | 91 +++++-------------- src/include/concurrency/transaction_context.h | 7 +- 2 files changed, 24 insertions(+), 74 deletions(-) diff --git a/src/concurrency/transaction_context.cpp b/src/concurrency/transaction_context.cpp index d3972b94f05..4fb6b7e2abd 100644 --- a/src/concurrency/transaction_context.cpp +++ b/src/concurrency/transaction_context.cpp @@ -80,10 +80,6 @@ void TransactionContext::Init(const size_t thread_id, isolation_level_ = isolation; - is_written_ = false; - - insert_count_ = 0; - gc_set_.reset(new GCSet()); gc_object_set_.reset(new GCObjectSet()); @@ -93,89 +89,48 @@ void TransactionContext::Init(const size_t thread_id, RWType TransactionContext::GetRWType(const ItemPointer &location) { RWType rw_type = RWType::INVALID; - auto rw_set_it = rw_set_.find(location); + const auto rw_set_it = rw_set_.find(location); if (rw_set_it != rw_set_.end()) { - return rw_set_it->second; + rw_type = rw_set_it->second; } return rw_type; } void TransactionContext::RecordRead(const ItemPointer &location) { + PELOTON_ASSERT(rw_set_.count(location) == 0 || + (rw_set_[location] != RWType::DELETE && rw_set_[location] != RWType::INS_DEL)); - auto rw_set_it = rw_set_.find(location); - if (rw_set_it != rw_set_.end()) { - UNUSED_ATTRIBUTE RWType rw_type = rw_set_it->second; - PELOTON_ASSERT(rw_type != RWType::DELETE && rw_type != RWType::INS_DEL); - return; + if (rw_set_.count(location) == 0) { + rw_set_[location] = RWType::READ; } - rw_set_.insert(rw_set_it, std::make_pair(location, RWType::READ)); } void TransactionContext::RecordReadOwn(const ItemPointer &location) { - auto rw_set_it = rw_set_.find(location); - if (rw_set_it != rw_set_.end()) { - RWType rw_type = rw_set_it->second; - PELOTON_ASSERT(rw_type != RWType::DELETE && rw_type != RWType::INS_DEL); - if (rw_type == RWType::READ) { - rw_set_it->second = RWType::READ_OWN; - } - } else { - rw_set_.insert(rw_set_it, std::make_pair(location, RWType::READ_OWN)); - } + PELOTON_ASSERT(rw_set_.count(location) == 0 || + (rw_set_[location] != RWType::DELETE && rw_set_[location] != RWType::INS_DEL)); + rw_set_[location] = RWType::READ_OWN; } void TransactionContext::RecordUpdate(const ItemPointer &location) { - auto rw_set_it = rw_set_.find(location); - if (rw_set_it != rw_set_.end()) { - RWType rw_type = rw_set_it->second; - if (rw_type == RWType::READ || rw_type == RWType::READ_OWN) { - is_written_ = true; - rw_set_it->second = RWType::UPDATE; - } else if (rw_type == RWType::UPDATE || rw_type == RWType::INSERT) { - return; - } else { - // DELETE or INS_DELETE - PELOTON_ASSERT(false); - } - } else { - rw_set_.insert(rw_set_it, std::make_pair(location, RWType::UPDATE)); - } + PELOTON_ASSERT(rw_set_.count(location) == 0 || + (rw_set_[location] != RWType::DELETE && rw_set_[location] != RWType::INS_DEL)); + rw_set_[location] = RWType::UPDATE; } void TransactionContext::RecordInsert(const ItemPointer &location) { - auto rw_set_it = rw_set_.find(location); - if (rw_set_it != rw_set_.end()) { - PELOTON_ASSERT(false); - return; - } - rw_set_.insert(rw_set_it, std::make_pair(location, RWType::INSERT)); - ++insert_count_; + PELOTON_ASSERT(rw_set_.count(location) == 0); + rw_set_[location] = RWType::INSERT; } -bool TransactionContext::RecordDelete(const ItemPointer &location) { - auto rw_set_it = rw_set_.find(location); - if (rw_set_it != rw_set_.end()) { - RWType rw_type = rw_set_it->second; - - if (rw_type == RWType::READ || rw_type == RWType::READ_OWN) { - rw_set_it->second = RWType::DELETE; - is_written_ = true; - return false; - } else if (rw_type == RWType::UPDATE) { - rw_set_it->second = RWType::DELETE; - return false; - } else if (rw_type == RWType::INSERT) { - rw_set_it->second = RWType::INS_DEL; - --insert_count_; - return true; - } else { - // DELETE and INS_DEL - PELOTON_ASSERT(false); - return false; - } - } else { - rw_set_.insert(rw_set_it, std::make_pair(location, RWType::DELETE)); - return false; +void TransactionContext::RecordDelete(const ItemPointer &location) { + PELOTON_ASSERT(rw_set_.count(location) == 0 || + (rw_set_[location] != RWType::DELETE && rw_set_[location] != RWType::INS_DEL)); + if (rw_set_[location] == RWType::INSERT) { + rw_set_[location] = RWType::INS_DEL; + } + else { + // READ, READ_OWN, UPDATE + rw_set_[location] = RWType::DELETE; } } diff --git a/src/include/concurrency/transaction_context.h b/src/include/concurrency/transaction_context.h index dbd717c1031..65ecb2b6a9b 100644 --- a/src/include/concurrency/transaction_context.h +++ b/src/include/concurrency/transaction_context.h @@ -171,10 +171,8 @@ class TransactionContext : public Printable { * @brief Delete the record. * * @param[in] The logical physical location of the record - * - * @return Return true if we detect INS_DEL. */ - bool RecordDelete(const ItemPointer &); + void RecordDelete(const ItemPointer &); RWType GetRWType(const ItemPointer &); @@ -337,9 +335,6 @@ class TransactionContext : public Printable { /** result of the transaction */ ResultType result_ = ResultType::SUCCESS; - bool is_written_; - size_t insert_count_; - IsolationLevelType isolation_level_; std::unique_ptr on_commit_triggers_; From 642f380001320902ebeef8d68f52926ed9db3c15 Mon Sep 17 00:00:00 2001 From: mbutrovich Date: Mon, 4 Jun 2018 13:04:49 -0400 Subject: [PATCH 02/16] Change FindValid to Find in DataTable. --- src/storage/data_table.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storage/data_table.cpp b/src/storage/data_table.cpp index 3660fcc2f79..9fad8f519c0 100644 --- a/src/storage/data_table.cpp +++ b/src/storage/data_table.cpp @@ -1002,7 +1002,7 @@ std::shared_ptr DataTable::GetTileGroup( PELOTON_ASSERT(tile_group_offset < GetTileGroupCount()); auto tile_group_id = - tile_groups_.FindValid(tile_group_offset, invalid_tile_group_id); + tile_groups_.Find(tile_group_offset); return GetTileGroupById(tile_group_id); } From e8454dc1be821350ffc89e4d5c926cedbe25a1c4 Mon Sep 17 00:00:00 2001 From: mbutrovich Date: Tue, 5 Jun 2018 14:34:07 -0400 Subject: [PATCH 03/16] Try not to look up TileGroupHeader in Abort and Commit as much. --- .../timestamp_ordering_transaction_manager.cpp | 17 +++++++++++++++-- src/concurrency/transaction_context.cpp | 12 ++++-------- src/include/concurrency/transaction_context.h | 2 +- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/concurrency/timestamp_ordering_transaction_manager.cpp b/src/concurrency/timestamp_ordering_transaction_manager.cpp index eb92b2398cb..1770b01c588 100644 --- a/src/concurrency/timestamp_ordering_transaction_manager.cpp +++ b/src/concurrency/timestamp_ordering_transaction_manager.cpp @@ -655,12 +655,18 @@ ResultType TimestampOrderingTransactionManager::CommitTransaction( // TODO (Pooja): This might be inefficient since we will have to get the // tile_group_header for each entry. Check if this needs to be consolidated + + oid_t last_tile_group_id = INVALID_OID; + storage::TileGroupHeader *tile_group_header = nullptr; + for (const auto &tuple_entry : rw_set) { ItemPointer item_ptr = tuple_entry.first; oid_t tile_group_id = item_ptr.block; oid_t tuple_slot = item_ptr.offset; - auto tile_group_header = storage_manager->GetTileGroup(tile_group_id)->GetHeader(); + if (tile_group_id != last_tile_group_id) { + tile_group_header = storage_manager->GetTileGroup(tile_group_id)->GetHeader(); + } if (tuple_entry.second == RWType::READ_OWN) { // A read operation has acquired ownership but hasn't done any further @@ -807,11 +813,18 @@ ResultType TimestampOrderingTransactionManager::AbortTransaction( // Iterate through each item pointer in the read write set // TODO (Pooja): This might be inefficient since we will have to get the // tile_group_header for each entry. Check if this needs to be consolidated + + oid_t last_tile_group_id = INVALID_OID; + storage::TileGroupHeader *tile_group_header = nullptr; + for (const auto &tuple_entry : rw_set) { ItemPointer item_ptr = tuple_entry.first; oid_t tile_group_id = item_ptr.block; oid_t tuple_slot = item_ptr.offset; - auto tile_group_header = storage_manager->GetTileGroup(tile_group_id)->GetHeader(); + + if (tile_group_id != last_tile_group_id) { + tile_group_header = storage_manager->GetTileGroup(tile_group_id)->GetHeader(); + } if (tuple_entry.second == RWType::READ_OWN) { // A read operation has acquired ownership but hasn't done any further diff --git a/src/concurrency/transaction_context.cpp b/src/concurrency/transaction_context.cpp index 4fb6b7e2abd..87b5dc3f3de 100644 --- a/src/concurrency/transaction_context.cpp +++ b/src/concurrency/transaction_context.cpp @@ -61,8 +61,6 @@ TransactionContext::TransactionContext(const size_t thread_id, Init(thread_id, isolation, read_id, commit_id); } -TransactionContext::~TransactionContext() {} - void TransactionContext::Init(const size_t thread_id, const IsolationLevelType isolation, const cid_t &read_id, const cid_t &commit_id) { @@ -80,20 +78,18 @@ void TransactionContext::Init(const size_t thread_id, isolation_level_ = isolation; - gc_set_.reset(new GCSet()); - gc_object_set_.reset(new GCObjectSet()); + gc_set_ = std::make_shared(); + gc_object_set_ = std::make_shared(); on_commit_triggers_.reset(); } RWType TransactionContext::GetRWType(const ItemPointer &location) { - RWType rw_type = RWType::INVALID; - const auto rw_set_it = rw_set_.find(location); if (rw_set_it != rw_set_.end()) { - rw_type = rw_set_it->second; + return rw_set_it->second; } - return rw_type; + return RWType::INVALID; } void TransactionContext::RecordRead(const ItemPointer &location) { diff --git a/src/include/concurrency/transaction_context.h b/src/include/concurrency/transaction_context.h index 65ecb2b6a9b..e54a4135ba9 100644 --- a/src/include/concurrency/transaction_context.h +++ b/src/include/concurrency/transaction_context.h @@ -53,7 +53,7 @@ class TransactionContext : public Printable { /** * @brief Destroys the object. */ - ~TransactionContext(); + ~TransactionContext() = default; private: void Init(const size_t thread_id, const IsolationLevelType isolation, From 6732df18459296afcaf6f6995a0bbeaeb36e7206 Mon Sep 17 00:00:00 2001 From: mbutrovich Date: Wed, 6 Jun 2018 11:15:29 -0400 Subject: [PATCH 04/16] Change LockFreeArray::FindValid from O(n) to O(1). --- src/common/container/lock_free_array.cpp | 27 ++++++++++-------------- src/concurrency/transaction_context.cpp | 7 +++--- src/storage/data_table.cpp | 2 +- 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/common/container/lock_free_array.cpp b/src/common/container/lock_free_array.cpp index cde4466f213..537a1ad9d4e 100644 --- a/src/common/container/lock_free_array.cpp +++ b/src/common/container/lock_free_array.cpp @@ -73,23 +73,18 @@ ValueType LOCK_FREE_ARRAY_TYPE::FindValid( const std::size_t &offset, const ValueType &invalid_value) const { LOG_TRACE("Find Valid at %lu", offset); - std::size_t valid_array_itr = 0; - std::size_t array_itr; - auto lock_free_array_offset = lock_free_array.size(); - for (array_itr = 0; array_itr < lock_free_array_offset; array_itr++) { - auto value = lock_free_array.at(array_itr); - if (value != invalid_value) { - // Check offset - if (valid_array_itr == offset) { - return value; - } - - // Update valid value count - valid_array_itr++; - } + ValueType value = invalid_value; + if ((lock_free_array.size() > offset)) { + value = lock_free_array.at(offset); + } else { + return invalid_value; + } + + if (value != invalid_value) + return value; + else { + return invalid_value; } - - return invalid_value; } template diff --git a/src/concurrency/transaction_context.cpp b/src/concurrency/transaction_context.cpp index 87b5dc3f3de..a02f1091721 100644 --- a/src/concurrency/transaction_context.cpp +++ b/src/concurrency/transaction_context.cpp @@ -95,10 +95,11 @@ RWType TransactionContext::GetRWType(const ItemPointer &location) { void TransactionContext::RecordRead(const ItemPointer &location) { PELOTON_ASSERT(rw_set_.count(location) == 0 || (rw_set_[location] != RWType::DELETE && rw_set_[location] != RWType::INS_DEL)); - - if (rw_set_.count(location) == 0) { - rw_set_[location] = RWType::READ; + auto rw_set_it = rw_set_.find(location); + if (rw_set_it != rw_set_.end()) { + return; } + rw_set_[location] = RWType::READ; } void TransactionContext::RecordReadOwn(const ItemPointer &location) { diff --git a/src/storage/data_table.cpp b/src/storage/data_table.cpp index 9fad8f519c0..3660fcc2f79 100644 --- a/src/storage/data_table.cpp +++ b/src/storage/data_table.cpp @@ -1002,7 +1002,7 @@ std::shared_ptr DataTable::GetTileGroup( PELOTON_ASSERT(tile_group_offset < GetTileGroupCount()); auto tile_group_id = - tile_groups_.Find(tile_group_offset); + tile_groups_.FindValid(tile_group_offset, invalid_tile_group_id); return GetTileGroupById(tile_group_id); } From d633c7704ce1ee1d46f0cc9d3c8060b462847a68 Mon Sep 17 00:00:00 2001 From: mbutrovich Date: Wed, 6 Jun 2018 11:57:30 -0400 Subject: [PATCH 05/16] Refactor. --- src/common/container/lock_free_array.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/common/container/lock_free_array.cpp b/src/common/container/lock_free_array.cpp index 537a1ad9d4e..e6972882bb1 100644 --- a/src/common/container/lock_free_array.cpp +++ b/src/common/container/lock_free_array.cpp @@ -76,15 +76,9 @@ ValueType LOCK_FREE_ARRAY_TYPE::FindValid( ValueType value = invalid_value; if ((lock_free_array.size() > offset)) { value = lock_free_array.at(offset); - } else { - return invalid_value; - } - - if (value != invalid_value) - return value; - else { - return invalid_value; } + + return value; } template From c352bec8c98e37b634187c44ca8fcea3151d06aa Mon Sep 17 00:00:00 2001 From: mbutrovich Date: Mon, 11 Jun 2018 14:27:48 -0400 Subject: [PATCH 06/16] Lock_free_array refactor, documentation, and added more tests. Refactor of RecordDelete to reduce lookups. --- src/common/container/lock_free_array.cpp | 23 ++-- src/concurrency/transaction_context.cpp | 6 +- .../common/container/lock_free_array.h | 80 ++++++++---- test/common/lock_free_array_test.cpp | 115 ++++++++++++++++-- 4 files changed, 178 insertions(+), 46 deletions(-) diff --git a/src/common/container/lock_free_array.cpp b/src/common/container/lock_free_array.cpp index e6972882bb1..7c60d7dc5dd 100644 --- a/src/common/container/lock_free_array.cpp +++ b/src/common/container/lock_free_array.cpp @@ -10,12 +10,10 @@ // //===----------------------------------------------------------------------===// -#include - #include "common/container/lock_free_array.h" +#include "common/internal_types.h" #include "common/logger.h" #include "common/macros.h" -#include "common/internal_types.h" namespace peloton { @@ -38,26 +36,23 @@ template LOCK_FREE_ARRAY_TYPE::~LockFreeArray() { lock_free_array.clear(); } template -bool LOCK_FREE_ARRAY_TYPE::Update(const std::size_t &offset, ValueType value) { +void LOCK_FREE_ARRAY_TYPE::Update(const std::size_t &offset, const ValueType &value) { LOG_TRACE("Update at %lu", offset); - PELOTON_ASSERT(lock_free_array.size() >= offset + 1); + PELOTON_ASSERT(lock_free_array.size() > offset); lock_free_array.at(offset) = value; - return true; } template -bool LOCK_FREE_ARRAY_TYPE::Append(ValueType value) { +void LOCK_FREE_ARRAY_TYPE::Append(const ValueType &value) { LOG_TRACE("Appended value."); lock_free_array.push_back(value); - return true; } template -bool LOCK_FREE_ARRAY_TYPE::Erase(const std::size_t &offset, +void LOCK_FREE_ARRAY_TYPE::Erase(const std::size_t &offset, const ValueType &invalid_value) { LOG_TRACE("Erase at %lu", offset); lock_free_array.at(offset) = invalid_value; - return true; } template @@ -88,10 +83,14 @@ template bool LOCK_FREE_ARRAY_TYPE::IsEmpty() const { return lock_free_array.empty(); } template -void LOCK_FREE_ARRAY_TYPE::Clear() { lock_free_array.clear(); } +void LOCK_FREE_ARRAY_TYPE::Clear() { + // Intel docs: To free internal arrays, call shrink_to_fit() after clear(). + lock_free_array.clear(); + lock_free_array.shrink_to_fit(); +} template -bool LOCK_FREE_ARRAY_TYPE::Contains(const ValueType &value) { +bool LOCK_FREE_ARRAY_TYPE::Contains(const ValueType &value) const { bool exists = false; for (std::size_t array_itr = 0; array_itr < lock_free_array.size(); diff --git a/src/concurrency/transaction_context.cpp b/src/concurrency/transaction_context.cpp index a02f1091721..e90210516fa 100644 --- a/src/concurrency/transaction_context.cpp +++ b/src/concurrency/transaction_context.cpp @@ -122,11 +122,11 @@ void TransactionContext::RecordInsert(const ItemPointer &location) { void TransactionContext::RecordDelete(const ItemPointer &location) { PELOTON_ASSERT(rw_set_.count(location) == 0 || (rw_set_[location] != RWType::DELETE && rw_set_[location] != RWType::INS_DEL)); - if (rw_set_[location] == RWType::INSERT) { - rw_set_[location] = RWType::INS_DEL; + auto rw_set_it = rw_set_.find(location); + if (rw_set_it != rw_set_.end() && rw_set_it->second == RWType::INSERT) { + rw_set_it->second = RWType::INS_DEL; } else { - // READ, READ_OWN, UPDATE rw_set_[location] = RWType::DELETE; } } diff --git a/src/include/common/container/lock_free_array.h b/src/include/common/container/lock_free_array.h index 10f25edc266..a0d79ad8be7 100644 --- a/src/include/common/container/lock_free_array.h +++ b/src/include/common/container/lock_free_array.h @@ -12,13 +12,6 @@ #pragma once #include "tbb/concurrent_vector.h" -#include "tbb/tbb_allocator.h" -#include -#include -#include -#include -#include -#include namespace peloton { @@ -35,33 +28,74 @@ class LockFreeArray { LockFreeArray(); ~LockFreeArray(); - // Update a item - bool Update(const std::size_t &offset, ValueType value); - - // Append an item - bool Append(ValueType value); - - // Get a item + /** + * Assigns the provided value to the provided offset. + * + * @param offset Element offset to update + * @param value Value to be assigned + */ + void Update(const std::size_t &offset, const ValueType &value); + + /** + * Appends an element to the end of the array + * + * @param value Value to be appended + */ + void Append(const ValueType &value); + + /** + * Returns the element at the offset + * + * @returns Element at offset + */ ValueType Find(const std::size_t &offset) const; - // Get a valid item + /** + * Returns the element at the offset, or invalid_value if + * the element does not exist. + * + * @param offset Element offset to access + * @param invalid_value Sentinel value to return if element + * does not exist or offset out of range + * @returns Element at offset or invalid_value + */ ValueType FindValid(const std::size_t &offset, const ValueType &invalid_value) const; - // Delete key from the lock_free_array - bool Erase(const std::size_t &offset, const ValueType &invalid_value); - - // Returns item count in the lock_free_array + /** + * Assigns the provided invalid_value to the provided offset. + * + * @param offset Element offset to update + * @param invalid_value Invalid value to be assigned + */ + void Erase(const std::size_t &offset, const ValueType &invalid_value); + + /** + * + * @return Number of elements in the underlying structure + */ size_t GetSize() const; - // Checks if the lock_free_array is empty + /** + * + * @return True if empty, false otherwise + */ bool IsEmpty() const; - // Clear all elements and reset them to default value + /** + * Resets the underlying data structure to have 0 elements + */ void Clear(); - // Exists ? - bool Contains(const ValueType &value); + /** + * + * Check the lock-free array for the provided value. + * O(n) time complexity. + * + * @param value value to search for + * @return True if element present, false otherwise + */ + bool Contains(const ValueType &value) const; private: // lock free array diff --git a/test/common/lock_free_array_test.cpp b/test/common/lock_free_array_test.cpp index c8b9f3cea68..6205a2dd258 100644 --- a/test/common/lock_free_array_test.cpp +++ b/test/common/lock_free_array_test.cpp @@ -34,8 +34,7 @@ TEST_F(LockFreeArrayTests, BasicTest) { size_t const element_count = 3; for (size_t element = 0; element < element_count; ++element ) { - auto status = array.Append(element); - EXPECT_TRUE(status); + array.Append(element); } auto array_size = array.GetSize(); @@ -55,8 +54,7 @@ TEST_F(LockFreeArrayTests, SharedPointerTest1) { size_t const element_count = 3; for (size_t element = 0; element < element_count; ++element ) { std::shared_ptr entry(new oid_t); - auto status = array.Append(entry); - EXPECT_TRUE(status); + array.Append(entry); } auto array_size = array.GetSize(); @@ -77,8 +75,7 @@ TEST_F(LockFreeArrayTests, SharedPointerTest2) { size_t const element_count = 10000; for (size_t element = 0; element < element_count; ++element ) { std::shared_ptr entry(new oid_t); - auto status = array.Append(entry); - EXPECT_TRUE(status); + array.Append(entry); } }); @@ -86,8 +83,7 @@ TEST_F(LockFreeArrayTests, SharedPointerTest2) { size_t const element_count = 10000; for (size_t element = 0; element < element_count; ++element ) { std::shared_ptr entry(new oid_t); - auto status = array.Append(entry); - EXPECT_TRUE(status); + array.Append(entry); } t0.join(); @@ -99,5 +95,108 @@ TEST_F(LockFreeArrayTests, SharedPointerTest2) { } } +TEST_F(LockFreeArrayTests, FindValidAndEraseTest) { + + typedef uint32_t value_type; + + { + LockFreeArray array; + + value_type invalid_value = 6288; + + size_t const element_count = 3; + for (size_t element = 0; element < element_count; ++element ) { + array.Append(element); + } + + // in range, valid + EXPECT_EQ(2, array.FindValid(2, invalid_value)); + + // out of range + EXPECT_EQ(invalid_value, array.FindValid(6, invalid_value)); + + array.Erase(2, invalid_value); + + // in range, erased + EXPECT_EQ(invalid_value, array.FindValid(2, invalid_value)); + } + +} + +TEST_F(LockFreeArrayTests, ClearAndIsEmptyTest) { + + typedef uint32_t value_type; + + { + LockFreeArray array; + + EXPECT_TRUE(array.IsEmpty()); + + size_t const element_count = 3; + for (size_t element = 0; element < element_count; ++element ) { + array.Append(element); + } + + EXPECT_TRUE(array.Contains(2)); + + EXPECT_FALSE(array.IsEmpty()); + + array.Clear(); + + EXPECT_TRUE(array.IsEmpty()); + + + EXPECT_FALSE(array.Contains(2)); + + } + +} + +TEST_F(LockFreeArrayTests, ContainsTest) { + + typedef uint32_t value_type; + + { + LockFreeArray array; + + EXPECT_FALSE(array.Contains(2)); + + size_t const element_count = 3; + for (size_t element = 0; element < element_count; ++element ) { + array.Append(element); + } + + EXPECT_TRUE(array.Contains(2)); + + array.Clear(); + + EXPECT_FALSE(array.Contains(2)); + + } + +} + +TEST_F(LockFreeArrayTests, UpdateTest) { + + typedef uint32_t value_type; + + { + LockFreeArray array; + + size_t const element_count = 3; + for (size_t element = 0; element < element_count; ++element ) { + array.Append(element); + } + + EXPECT_EQ(2, array.Find(2)); + + array.Update(2, 6288); + + EXPECT_EQ(6288, array.Find(2)); + + } + +} + } // namespace test } // namespace peloton From 2333d000d922ba02e97d93d93b10001ccc33c155 Mon Sep 17 00:00:00 2001 From: mbutrovich Date: Mon, 11 Jun 2018 14:30:12 -0400 Subject: [PATCH 07/16] Formatting. --- src/common/container/lock_free_array.cpp | 3 +- ...timestamp_ordering_transaction_manager.cpp | 6 ++-- src/concurrency/transaction_context.cpp | 15 ++++++---- test/common/lock_free_array_test.cpp | 28 ++++++------------- 4 files changed, 23 insertions(+), 29 deletions(-) diff --git a/src/common/container/lock_free_array.cpp b/src/common/container/lock_free_array.cpp index 7c60d7dc5dd..bceb0a093ba 100644 --- a/src/common/container/lock_free_array.cpp +++ b/src/common/container/lock_free_array.cpp @@ -36,7 +36,8 @@ template LOCK_FREE_ARRAY_TYPE::~LockFreeArray() { lock_free_array.clear(); } template -void LOCK_FREE_ARRAY_TYPE::Update(const std::size_t &offset, const ValueType &value) { +void LOCK_FREE_ARRAY_TYPE::Update(const std::size_t &offset, + const ValueType &value) { LOG_TRACE("Update at %lu", offset); PELOTON_ASSERT(lock_free_array.size() > offset); lock_free_array.at(offset) = value; diff --git a/src/concurrency/timestamp_ordering_transaction_manager.cpp b/src/concurrency/timestamp_ordering_transaction_manager.cpp index 1770b01c588..42d311f33b3 100644 --- a/src/concurrency/timestamp_ordering_transaction_manager.cpp +++ b/src/concurrency/timestamp_ordering_transaction_manager.cpp @@ -665,7 +665,8 @@ ResultType TimestampOrderingTransactionManager::CommitTransaction( oid_t tuple_slot = item_ptr.offset; if (tile_group_id != last_tile_group_id) { - tile_group_header = storage_manager->GetTileGroup(tile_group_id)->GetHeader(); + tile_group_header = + storage_manager->GetTileGroup(tile_group_id)->GetHeader(); } if (tuple_entry.second == RWType::READ_OWN) { @@ -823,7 +824,8 @@ ResultType TimestampOrderingTransactionManager::AbortTransaction( oid_t tuple_slot = item_ptr.offset; if (tile_group_id != last_tile_group_id) { - tile_group_header = storage_manager->GetTileGroup(tile_group_id)->GetHeader(); + tile_group_header = + storage_manager->GetTileGroup(tile_group_id)->GetHeader(); } if (tuple_entry.second == RWType::READ_OWN) { diff --git a/src/concurrency/transaction_context.cpp b/src/concurrency/transaction_context.cpp index e90210516fa..8ac674b958c 100644 --- a/src/concurrency/transaction_context.cpp +++ b/src/concurrency/transaction_context.cpp @@ -94,7 +94,8 @@ RWType TransactionContext::GetRWType(const ItemPointer &location) { void TransactionContext::RecordRead(const ItemPointer &location) { PELOTON_ASSERT(rw_set_.count(location) == 0 || - (rw_set_[location] != RWType::DELETE && rw_set_[location] != RWType::INS_DEL)); + (rw_set_[location] != RWType::DELETE && + rw_set_[location] != RWType::INS_DEL)); auto rw_set_it = rw_set_.find(location); if (rw_set_it != rw_set_.end()) { return; @@ -104,13 +105,15 @@ void TransactionContext::RecordRead(const ItemPointer &location) { void TransactionContext::RecordReadOwn(const ItemPointer &location) { PELOTON_ASSERT(rw_set_.count(location) == 0 || - (rw_set_[location] != RWType::DELETE && rw_set_[location] != RWType::INS_DEL)); + (rw_set_[location] != RWType::DELETE && + rw_set_[location] != RWType::INS_DEL)); rw_set_[location] = RWType::READ_OWN; } void TransactionContext::RecordUpdate(const ItemPointer &location) { PELOTON_ASSERT(rw_set_.count(location) == 0 || - (rw_set_[location] != RWType::DELETE && rw_set_[location] != RWType::INS_DEL)); + (rw_set_[location] != RWType::DELETE && + rw_set_[location] != RWType::INS_DEL)); rw_set_[location] = RWType::UPDATE; } @@ -121,12 +124,12 @@ void TransactionContext::RecordInsert(const ItemPointer &location) { void TransactionContext::RecordDelete(const ItemPointer &location) { PELOTON_ASSERT(rw_set_.count(location) == 0 || - (rw_set_[location] != RWType::DELETE && rw_set_[location] != RWType::INS_DEL)); + (rw_set_[location] != RWType::DELETE && + rw_set_[location] != RWType::INS_DEL)); auto rw_set_it = rw_set_.find(location); if (rw_set_it != rw_set_.end() && rw_set_it->second == RWType::INSERT) { rw_set_it->second = RWType::INS_DEL; - } - else { + } else { rw_set_[location] = RWType::DELETE; } } diff --git a/test/common/lock_free_array_test.cpp b/test/common/lock_free_array_test.cpp index 6205a2dd258..043ac65b9b3 100644 --- a/test/common/lock_free_array_test.cpp +++ b/test/common/lock_free_array_test.cpp @@ -96,8 +96,7 @@ TEST_F(LockFreeArrayTests, SharedPointerTest2) { } TEST_F(LockFreeArrayTests, FindValidAndEraseTest) { - - typedef uint32_t value_type; + typedef uint32_t value_type; { LockFreeArray array; @@ -105,7 +104,7 @@ TEST_F(LockFreeArrayTests, FindValidAndEraseTest) { value_type invalid_value = 6288; size_t const element_count = 3; - for (size_t element = 0; element < element_count; ++element ) { + for (size_t element = 0; element < element_count; ++element) { array.Append(element); } @@ -120,12 +119,10 @@ TEST_F(LockFreeArrayTests, FindValidAndEraseTest) { // in range, erased EXPECT_EQ(invalid_value, array.FindValid(2, invalid_value)); } - } TEST_F(LockFreeArrayTests, ClearAndIsEmptyTest) { - - typedef uint32_t value_type; + typedef uint32_t value_type; { LockFreeArray array; @@ -133,7 +130,7 @@ TEST_F(LockFreeArrayTests, ClearAndIsEmptyTest) { EXPECT_TRUE(array.IsEmpty()); size_t const element_count = 3; - for (size_t element = 0; element < element_count; ++element ) { + for (size_t element = 0; element < element_count; ++element) { array.Append(element); } @@ -145,16 +142,12 @@ TEST_F(LockFreeArrayTests, ClearAndIsEmptyTest) { EXPECT_TRUE(array.IsEmpty()); - EXPECT_FALSE(array.Contains(2)); - } - } TEST_F(LockFreeArrayTests, ContainsTest) { - - typedef uint32_t value_type; + typedef uint32_t value_type; { LockFreeArray array; @@ -162,7 +155,7 @@ TEST_F(LockFreeArrayTests, ContainsTest) { EXPECT_FALSE(array.Contains(2)); size_t const element_count = 3; - for (size_t element = 0; element < element_count; ++element ) { + for (size_t element = 0; element < element_count; ++element) { array.Append(element); } @@ -171,20 +164,17 @@ TEST_F(LockFreeArrayTests, ContainsTest) { array.Clear(); EXPECT_FALSE(array.Contains(2)); - } - } TEST_F(LockFreeArrayTests, UpdateTest) { - - typedef uint32_t value_type; + typedef uint32_t value_type; { LockFreeArray array; size_t const element_count = 3; - for (size_t element = 0; element < element_count; ++element ) { + for (size_t element = 0; element < element_count; ++element) { array.Append(element); } @@ -193,9 +183,7 @@ TEST_F(LockFreeArrayTests, UpdateTest) { array.Update(2, 6288); EXPECT_EQ(6288, array.Find(2)); - } - } } // namespace test From 57a3b9e66f16e90edb71dee9b4b40992d4898f59 Mon Sep 17 00:00:00 2001 From: mbutrovich Date: Mon, 11 Jun 2018 14:38:02 -0400 Subject: [PATCH 08/16] Fix the last_tile_group_id optimization in TOTM. --- src/concurrency/timestamp_ordering_transaction_manager.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/concurrency/timestamp_ordering_transaction_manager.cpp b/src/concurrency/timestamp_ordering_transaction_manager.cpp index 42d311f33b3..3c7655422c8 100644 --- a/src/concurrency/timestamp_ordering_transaction_manager.cpp +++ b/src/concurrency/timestamp_ordering_transaction_manager.cpp @@ -667,6 +667,7 @@ ResultType TimestampOrderingTransactionManager::CommitTransaction( if (tile_group_id != last_tile_group_id) { tile_group_header = storage_manager->GetTileGroup(tile_group_id)->GetHeader(); + last_tile_group_id = tile_group_id; } if (tuple_entry.second == RWType::READ_OWN) { @@ -826,6 +827,7 @@ ResultType TimestampOrderingTransactionManager::AbortTransaction( if (tile_group_id != last_tile_group_id) { tile_group_header = storage_manager->GetTileGroup(tile_group_id)->GetHeader(); + last_tile_group_id = tile_group_id; } if (tuple_entry.second == RWType::READ_OWN) { From 5c26c1bf85b0ab00f37081ec64edd12ff792a1e2 Mon Sep 17 00:00:00 2001 From: mbutrovich Date: Tue, 12 Jun 2018 10:06:59 -0400 Subject: [PATCH 09/16] Fix RecordUpdate based on PR feedback. --- src/concurrency/transaction_context.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/concurrency/transaction_context.cpp b/src/concurrency/transaction_context.cpp index 8ac674b958c..6d1f15882ac 100644 --- a/src/concurrency/transaction_context.cpp +++ b/src/concurrency/transaction_context.cpp @@ -114,7 +114,10 @@ void TransactionContext::RecordUpdate(const ItemPointer &location) { PELOTON_ASSERT(rw_set_.count(location) == 0 || (rw_set_[location] != RWType::DELETE && rw_set_[location] != RWType::INS_DEL)); - rw_set_[location] = RWType::UPDATE; + auto rw_set_it = rw_set_.find(location); + if (rw_set_it != rw_set_.end() && (rw_set_it->second == RWType::READ || rw_set_it->second == RWType::READ_OWN)) { + rw_set_it->second = RWType::UPDATE; + } } void TransactionContext::RecordInsert(const ItemPointer &location) { From 1a43ebff18859e88aebb376edb422a9d5ec6977b Mon Sep 17 00:00:00 2001 From: mbutrovich Date: Tue, 12 Jun 2018 10:07:37 -0400 Subject: [PATCH 10/16] Formatting. --- src/concurrency/transaction_context.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/concurrency/transaction_context.cpp b/src/concurrency/transaction_context.cpp index 6d1f15882ac..0edfe78c120 100644 --- a/src/concurrency/transaction_context.cpp +++ b/src/concurrency/transaction_context.cpp @@ -115,7 +115,8 @@ void TransactionContext::RecordUpdate(const ItemPointer &location) { (rw_set_[location] != RWType::DELETE && rw_set_[location] != RWType::INS_DEL)); auto rw_set_it = rw_set_.find(location); - if (rw_set_it != rw_set_.end() && (rw_set_it->second == RWType::READ || rw_set_it->second == RWType::READ_OWN)) { + if (rw_set_it != rw_set_.end() && (rw_set_it->second == RWType::READ || + rw_set_it->second == RWType::READ_OWN)) { rw_set_it->second = RWType::UPDATE; } } From 0cd4739ac95aa4d0a43b4425598d6b819ce8e0b7 Mon Sep 17 00:00:00 2001 From: mbutrovich Date: Tue, 12 Jun 2018 11:40:00 -0400 Subject: [PATCH 11/16] PR feedback changes. --- .../timestamp_ordering_transaction_manager.cpp | 5 ----- src/concurrency/transaction_context.cpp | 4 +++- src/include/concurrency/transaction_context.h | 3 ++- test/common/lock_free_array_test.cpp | 10 ++++------ 4 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/concurrency/timestamp_ordering_transaction_manager.cpp b/src/concurrency/timestamp_ordering_transaction_manager.cpp index 3c7655422c8..3de2620a275 100644 --- a/src/concurrency/timestamp_ordering_transaction_manager.cpp +++ b/src/concurrency/timestamp_ordering_transaction_manager.cpp @@ -653,9 +653,6 @@ ResultType TimestampOrderingTransactionManager::CommitTransaction( // 3. install a new tuple for insert operations. // Iterate through each item pointer in the read write set - // TODO (Pooja): This might be inefficient since we will have to get the - // tile_group_header for each entry. Check if this needs to be consolidated - oid_t last_tile_group_id = INVALID_OID; storage::TileGroupHeader *tile_group_header = nullptr; @@ -813,8 +810,6 @@ ResultType TimestampOrderingTransactionManager::AbortTransaction( } // Iterate through each item pointer in the read write set - // TODO (Pooja): This might be inefficient since we will have to get the - // tile_group_header for each entry. Check if this needs to be consolidated oid_t last_tile_group_id = INVALID_OID; storage::TileGroupHeader *tile_group_header = nullptr; diff --git a/src/concurrency/transaction_context.cpp b/src/concurrency/transaction_context.cpp index 0edfe78c120..fa9e7f84b3d 100644 --- a/src/concurrency/transaction_context.cpp +++ b/src/concurrency/transaction_context.cpp @@ -126,15 +126,17 @@ void TransactionContext::RecordInsert(const ItemPointer &location) { rw_set_[location] = RWType::INSERT; } -void TransactionContext::RecordDelete(const ItemPointer &location) { +bool TransactionContext::RecordDelete(const ItemPointer &location) { PELOTON_ASSERT(rw_set_.count(location) == 0 || (rw_set_[location] != RWType::DELETE && rw_set_[location] != RWType::INS_DEL)); auto rw_set_it = rw_set_.find(location); if (rw_set_it != rw_set_.end() && rw_set_it->second == RWType::INSERT) { rw_set_it->second = RWType::INS_DEL; + return true; } else { rw_set_[location] = RWType::DELETE; + return false; } } diff --git a/src/include/concurrency/transaction_context.h b/src/include/concurrency/transaction_context.h index e54a4135ba9..7414e828bbf 100644 --- a/src/include/concurrency/transaction_context.h +++ b/src/include/concurrency/transaction_context.h @@ -171,8 +171,9 @@ class TransactionContext : public Printable { * @brief Delete the record. * * @param[in] The logical physical location of the record + * @return true if INS_DEL, false if DELETE */ - void RecordDelete(const ItemPointer &); + bool RecordDelete(const ItemPointer &); RWType GetRWType(const ItemPointer &); diff --git a/test/common/lock_free_array_test.cpp b/test/common/lock_free_array_test.cpp index 043ac65b9b3..bc5f684943b 100644 --- a/test/common/lock_free_array_test.cpp +++ b/test/common/lock_free_array_test.cpp @@ -101,23 +101,21 @@ TEST_F(LockFreeArrayTests, FindValidAndEraseTest) { { LockFreeArray array; - value_type invalid_value = 6288; - size_t const element_count = 3; for (size_t element = 0; element < element_count; ++element) { array.Append(element); } // in range, valid - EXPECT_EQ(2, array.FindValid(2, invalid_value)); + EXPECT_EQ(2, array.FindValid(2, INVALID_OID)); // out of range - EXPECT_EQ(invalid_value, array.FindValid(6, invalid_value)); + EXPECT_EQ(INVALID_OID, array.FindValid(6, INVALID_OID)); - array.Erase(2, invalid_value); + array.Erase(2, INVALID_OID); // in range, erased - EXPECT_EQ(invalid_value, array.FindValid(2, invalid_value)); + EXPECT_EQ(INVALID_OID, array.FindValid(2, INVALID_OID)); } } From 358596ed02afe73831ad09d0af9157b2bbdd9d7b Mon Sep 17 00:00:00 2001 From: mbutrovich Date: Tue, 12 Jun 2018 11:41:54 -0400 Subject: [PATCH 12/16] More PR feedback changes. --- src/concurrency/transaction_context.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/concurrency/transaction_context.cpp b/src/concurrency/transaction_context.cpp index fa9e7f84b3d..329b31f0145 100644 --- a/src/concurrency/transaction_context.cpp +++ b/src/concurrency/transaction_context.cpp @@ -93,7 +93,7 @@ RWType TransactionContext::GetRWType(const ItemPointer &location) { } void TransactionContext::RecordRead(const ItemPointer &location) { - PELOTON_ASSERT(rw_set_.count(location) == 0 || + PELOTON_ASSERT(rw_set_.find(location) == rw_set_.end() || (rw_set_[location] != RWType::DELETE && rw_set_[location] != RWType::INS_DEL)); auto rw_set_it = rw_set_.find(location); @@ -104,14 +104,14 @@ void TransactionContext::RecordRead(const ItemPointer &location) { } void TransactionContext::RecordReadOwn(const ItemPointer &location) { - PELOTON_ASSERT(rw_set_.count(location) == 0 || + PELOTON_ASSERT(rw_set_.find(location) == rw_set_.end() || (rw_set_[location] != RWType::DELETE && rw_set_[location] != RWType::INS_DEL)); rw_set_[location] = RWType::READ_OWN; } void TransactionContext::RecordUpdate(const ItemPointer &location) { - PELOTON_ASSERT(rw_set_.count(location) == 0 || + PELOTON_ASSERT(rw_set_.find(location) == rw_set_.end() || (rw_set_[location] != RWType::DELETE && rw_set_[location] != RWType::INS_DEL)); auto rw_set_it = rw_set_.find(location); @@ -122,12 +122,12 @@ void TransactionContext::RecordUpdate(const ItemPointer &location) { } void TransactionContext::RecordInsert(const ItemPointer &location) { - PELOTON_ASSERT(rw_set_.count(location) == 0); + PELOTON_ASSERT(rw_set_.find(location) == rw_set_.end()); rw_set_[location] = RWType::INSERT; } bool TransactionContext::RecordDelete(const ItemPointer &location) { - PELOTON_ASSERT(rw_set_.count(location) == 0 || + PELOTON_ASSERT(rw_set_.find(location) == rw_set_.end() || (rw_set_[location] != RWType::DELETE && rw_set_[location] != RWType::INS_DEL)); auto rw_set_it = rw_set_.find(location); From a8eabd5588034c77a90942507f9e3ea77e06a04f Mon Sep 17 00:00:00 2001 From: mbutrovich Date: Tue, 12 Jun 2018 11:49:16 -0400 Subject: [PATCH 13/16] Slight logic change in RecordUpdate. --- src/concurrency/transaction_context.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/concurrency/transaction_context.cpp b/src/concurrency/transaction_context.cpp index 329b31f0145..16ab7422aa3 100644 --- a/src/concurrency/transaction_context.cpp +++ b/src/concurrency/transaction_context.cpp @@ -115,10 +115,13 @@ void TransactionContext::RecordUpdate(const ItemPointer &location) { (rw_set_[location] != RWType::DELETE && rw_set_[location] != RWType::INS_DEL)); auto rw_set_it = rw_set_.find(location); - if (rw_set_it != rw_set_.end() && (rw_set_it->second == RWType::READ || - rw_set_it->second == RWType::READ_OWN)) { - rw_set_it->second = RWType::UPDATE; + if (rw_set_it != rw_set_.end() { + if (rw_set_it->second == RWType::READ || rw_set_it->second == RWType::READ_OWN) { + rw_set_it->second = RWType::UPDATE; + } + return; } + rw_set_[location] = RWType::UPDATE; } void TransactionContext::RecordInsert(const ItemPointer &location) { From 439ace85f0c787c98960cbfa963b5d7147cfe81a Mon Sep 17 00:00:00 2001 From: mbutrovich Date: Tue, 12 Jun 2018 11:50:51 -0400 Subject: [PATCH 14/16] Fix typo. --- src/concurrency/transaction_context.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/concurrency/transaction_context.cpp b/src/concurrency/transaction_context.cpp index 16ab7422aa3..b4ff64faa2c 100644 --- a/src/concurrency/transaction_context.cpp +++ b/src/concurrency/transaction_context.cpp @@ -115,7 +115,7 @@ void TransactionContext::RecordUpdate(const ItemPointer &location) { (rw_set_[location] != RWType::DELETE && rw_set_[location] != RWType::INS_DEL)); auto rw_set_it = rw_set_.find(location); - if (rw_set_it != rw_set_.end() { + if (rw_set_it != rw_set_.end()) { if (rw_set_it->second == RWType::READ || rw_set_it->second == RWType::READ_OWN) { rw_set_it->second = RWType::UPDATE; } From 37d1c198c0c4db422d2b629eb74b53295bab947c Mon Sep 17 00:00:00 2001 From: mbutrovich Date: Wed, 13 Jun 2018 16:47:27 -0400 Subject: [PATCH 15/16] Added is_written_ flag back in for potential future optimizations. --- src/concurrency/transaction_context.cpp | 16 ++++++++++------ src/include/concurrency/transaction_context.h | 2 ++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/concurrency/transaction_context.cpp b/src/concurrency/transaction_context.cpp index b4ff64faa2c..e90e585b21f 100644 --- a/src/concurrency/transaction_context.cpp +++ b/src/concurrency/transaction_context.cpp @@ -76,6 +76,8 @@ void TransactionContext::Init(const size_t thread_id, thread_id_ = thread_id; + is_written_ = false; + isolation_level_ = isolation; gc_set_ = std::make_shared(); @@ -115,18 +117,18 @@ void TransactionContext::RecordUpdate(const ItemPointer &location) { (rw_set_[location] != RWType::DELETE && rw_set_[location] != RWType::INS_DEL)); auto rw_set_it = rw_set_.find(location); - if (rw_set_it != rw_set_.end()) { - if (rw_set_it->second == RWType::READ || rw_set_it->second == RWType::READ_OWN) { - rw_set_it->second = RWType::UPDATE; - } - return; + if (rw_set_it != rw_set_.end() && (rw_set_it->second == RWType::READ || + rw_set_it->second == RWType::READ_OWN)) { + rw_set_it->second = RWType::UPDATE; + is_written_ = true; } - rw_set_[location] = RWType::UPDATE; + PELOTON_ASSERT(is_written_); } void TransactionContext::RecordInsert(const ItemPointer &location) { PELOTON_ASSERT(rw_set_.find(location) == rw_set_.end()); rw_set_[location] = RWType::INSERT; + is_written_ = true; } bool TransactionContext::RecordDelete(const ItemPointer &location) { @@ -135,10 +137,12 @@ bool TransactionContext::RecordDelete(const ItemPointer &location) { rw_set_[location] != RWType::INS_DEL)); auto rw_set_it = rw_set_.find(location); if (rw_set_it != rw_set_.end() && rw_set_it->second == RWType::INSERT) { + PELOTON_ASSERT(is_written_); rw_set_it->second = RWType::INS_DEL; return true; } else { rw_set_[location] = RWType::DELETE; + is_written_ = true; return false; } } diff --git a/src/include/concurrency/transaction_context.h b/src/include/concurrency/transaction_context.h index 7414e828bbf..04419082825 100644 --- a/src/include/concurrency/transaction_context.h +++ b/src/include/concurrency/transaction_context.h @@ -338,6 +338,8 @@ class TransactionContext : public Printable { IsolationLevelType isolation_level_; + bool is_written_; + std::unique_ptr on_commit_triggers_; /** one default transaction is NOT 'read only' unless it is marked 'read only' explicitly*/ From 2f2dda09d31f45d2dfe52dc5a708efbc933061e6 Mon Sep 17 00:00:00 2001 From: mbutrovich Date: Wed, 13 Jun 2018 16:48:34 -0400 Subject: [PATCH 16/16] Formatting. --- src/concurrency/transaction_context.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/concurrency/transaction_context.cpp b/src/concurrency/transaction_context.cpp index e90e585b21f..498cc927e60 100644 --- a/src/concurrency/transaction_context.cpp +++ b/src/concurrency/transaction_context.cpp @@ -118,7 +118,7 @@ void TransactionContext::RecordUpdate(const ItemPointer &location) { rw_set_[location] != RWType::INS_DEL)); auto rw_set_it = rw_set_.find(location); if (rw_set_it != rw_set_.end() && (rw_set_it->second == RWType::READ || - rw_set_it->second == RWType::READ_OWN)) { + rw_set_it->second == RWType::READ_OWN)) { rw_set_it->second = RWType::UPDATE; is_written_ = true; }