Commit f7f9bcfb authored by Kei Nakashima's avatar Kei Nakashima Committed by Commit Bot

Added InsertBefore to NewLinkedHashSet

Implemented |NewLinkedHashSet::InsertBefore| and added test for it.

Change-Id: I653902201706e107403308e594356b6bb899db91
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2106702
Commit-Queue: Bartek Nowierski <bartekn@chromium.org>
Reviewed-by: default avatarYuki Shiino <yukishiino@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarBartek Nowierski <bartekn@chromium.org>
Cr-Commit-Position: refs/heads/master@{#750921}
parent 83dccf5d
......@@ -1092,10 +1092,15 @@ class NewLinkedHashSet {
const_iterator find(ValuePeekInType) const;
bool Contains(ValuePeekInType) const;
// TODO(keinakahsima): implement functions related to insert
template <typename IncomingValueType>
AddResult insert(IncomingValueType&&);
// If |value| already exists in the set, nothing happens.
// If |before_value| doesn't exist in the set, appends |value|.
template <typename IncomingValueType>
AddResult InsertBefore(ValuePeekInType before_value,
IncomingValueType&& value);
template <typename IncomingValueType>
AddResult AppendOrMoveToLast(IncomingValueType&&);
......@@ -1111,11 +1116,17 @@ class NewLinkedHashSet {
value_to_index_.clear();
list_.clear();
}
// TODO(keinakashima): implement Trace
private:
enum class MoveType {
kMoveIfValueExists,
kDontMove,
};
template <typename IncomingValueType>
AddResult InsertOrMoveBefore(const_iterator, IncomingValueType&&);
AddResult InsertOrMoveBefore(const_iterator, IncomingValueType&&, MoveType);
HashMap<Value, wtf_size_t> value_to_index_;
VectorBackedLinkedList<Value> list_;
......@@ -1174,32 +1185,34 @@ template <typename T>
template <typename IncomingValueType>
typename NewLinkedHashSet<T>::AddResult NewLinkedHashSet<T>::insert(
IncomingValueType&& value) {
typename Map::AddResult result = value_to_index_.insert(value, kNotFound);
if (result.is_new_entry) {
const_iterator stored_position_iterator =
list_.insert(list_.end(), std::forward<IncomingValueType>(value));
result.stored_value->value = stored_position_iterator.GetIndex();
return AddResult(stored_position_iterator.Get(), true);
}
return InsertOrMoveBefore(end(), std::forward<IncomingValueType>(value),
MoveType::kDontMove);
}
wtf_size_t index = result.stored_value->value;
const_iterator stored_position_iterator = list_.MakeConstIterator(index);
return AddResult(stored_position_iterator.Get(), false);
template <typename T>
template <typename IncomingValueType>
typename NewLinkedHashSet<T>::AddResult NewLinkedHashSet<T>::InsertBefore(
ValuePeekInType before_value,
IncomingValueType&& value) {
return InsertOrMoveBefore(find(before_value),
std::forward<IncomingValueType>(value),
MoveType::kDontMove);
}
template <typename T>
template <typename IncomingValueType>
typename NewLinkedHashSet<T>::AddResult NewLinkedHashSet<T>::AppendOrMoveToLast(
IncomingValueType&& value) {
return InsertOrMoveBefore(end(), std::forward<IncomingValueType>(value));
return InsertOrMoveBefore(end(), std::forward<IncomingValueType>(value),
MoveType::kMoveIfValueExists);
}
template <typename T>
template <typename IncomingValueType>
typename NewLinkedHashSet<T>::AddResult
NewLinkedHashSet<T>::PrependOrMoveToFirst(IncomingValueType&& value) {
return InsertOrMoveBefore(begin(), std::forward<IncomingValueType>(value));
return InsertOrMoveBefore(begin(), std::forward<IncomingValueType>(value),
MoveType::kMoveIfValueExists);
}
template <typename T>
......@@ -1231,7 +1244,8 @@ template <typename T>
template <typename IncomingValueType>
typename NewLinkedHashSet<T>::AddResult NewLinkedHashSet<T>::InsertOrMoveBefore(
const_iterator position,
IncomingValueType&& value) {
IncomingValueType&& value,
MoveType type) {
typename Map::AddResult result = value_to_index_.insert(value, kNotFound);
if (result.is_new_entry) {
......@@ -1243,6 +1257,9 @@ typename NewLinkedHashSet<T>::AddResult NewLinkedHashSet<T>::InsertOrMoveBefore(
const_iterator stored_position_iterator =
list_.MakeConstIterator(result.stored_value->value);
if (type == MoveType::kDontMove)
return AddResult(stored_position_iterator.Get(), false);
const_iterator moved_position_iterator =
list_.MoveTo(stored_position_iterator, position);
return AddResult(moved_position_iterator.Get(), false);
......
......@@ -115,6 +115,30 @@ TEST(NewLinkedHashSetTest, Insert) {
EXPECT_TRUE(it == set.end());
}
TEST(NewLinkedHashSetTest, InsertBefore) {
using Set = NewLinkedHashSet<int>;
Set set;
set.InsertBefore(1, 1);
set.InsertBefore(10, 3);
set.InsertBefore(3, 2);
set.InsertBefore(10, 5);
set.InsertBefore(5, 4);
Set::const_iterator it = set.begin();
EXPECT_EQ(*it, 1);
++it;
EXPECT_EQ(*it, 2);
++it;
EXPECT_EQ(*it, 3);
++it;
EXPECT_EQ(*it, 4);
++it;
EXPECT_EQ(*it, 5);
++it;
EXPECT_TRUE(it == set.end());
}
TEST(NewLinkedHashSetTest, AppendOrMoveToLast) {
using Set = NewLinkedHashSet<int>;
Set set;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment