-
Notifications
You must be signed in to change notification settings - Fork 619
RWSet performance fixes, LockFreeArray performance fixes and tests #1401
Changes from 14 commits
a9847aa
96431ee
a8b1b0c
76e0998
e8e5de7
58aa8c0
344c914
8afd1b7
6779ba7
07d75b3
c37e6ef
2aed22b
ac0a760
ad0381d
2db074c
d5583f0
30fddc2
21253c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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,101 +78,67 @@ 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()); | ||
| gc_set_ = std::make_shared<GCSet>(); | ||
| gc_object_set_ = std::make_shared<GCObjectSet>(); | ||
|
|
||
| on_commit_triggers_.reset(); | ||
| } | ||
|
|
||
| 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; | ||
| } | ||
| return rw_type; | ||
| return RWType::INVALID; | ||
| } | ||
|
|
||
| void TransactionContext::RecordRead(const ItemPointer &location) { | ||
|
|
||
| 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); | ||
| 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; | ||
| } | ||
| rw_set_.insert(rw_set_it, std::make_pair(location, RWType::READ)); | ||
| rw_set_[location] = RWType::READ; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So we have still two lookups here, one in line 99 and one in line 103. Is it even possible to do this with a single lookup? No, because some other thread could have changed the RW set between these to lines?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As best as I can tell, based on our current semantics we can't get away from two lookups on Read, or Delete. |
||
| } | ||
|
|
||
| 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_.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_.find(location) == rw_set_.end() || | ||
| (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()) { | ||
| RWType rw_type = rw_set_it->second; | ||
| if (rw_type == RWType::READ || rw_type == RWType::READ_OWN) { | ||
| is_written_ = true; | ||
| if (rw_set_it->second == RWType::READ || rw_set_it->second == RWType::READ_OWN) { | ||
| 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)); | ||
| return; | ||
| } | ||
| 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_.find(location) == rw_set_.end()); | ||
| rw_set_[location] = RWType::INSERT; | ||
| } | ||
|
|
||
| bool TransactionContext::RecordDelete(const ItemPointer &location) { | ||
| 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); | ||
| 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; | ||
| } | ||
| if (rw_set_it != rw_set_.end() && rw_set_it->second == RWType::INSERT) { | ||
| rw_set_it->second = RWType::INS_DEL; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am just wondering - what does happen, if the value of
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suspect it's a race that isn't handled in the current semantics of our RWSet. The hope is that we'll eventually get rid of the INS_DEL type anyway when we stop reusing tuple slots. |
||
| return true; | ||
| } else { | ||
| rw_set_.insert(rw_set_it, std::make_pair(location, RWType::DELETE)); | ||
| rw_set_[location] = RWType::DELETE; | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a little unsure about removing the
is_written_andinsert_count_. These variables can be used to make Commits and Aborts faster. If you figure out that theis_written_is false, you can take an entirely different code path and treat it like aREAD_ONLYtransaction.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's effectively what @lmwnshn is doing in #1402.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is okay if we get rid of
insert_count_but we should definitely useis_written_. It will help with multi statement transactions that are not explicitly set to read only.