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

Added a function |MoveTo| to VectorBackedLinkedList

|MoveTo| moves the target node before the node with the given iterator in a linked list. This operation is executed by just updating indices of related nodes.

Change-Id: I49fef39956717d878a505a0431d5d25b32c90bdf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2094837Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarYuki Shiino <yukishiino@chromium.org>
Commit-Queue: Kei Nakashima <keinakashima@google.com>
Cr-Commit-Position: refs/heads/master@{#748145}
parent 6a094647
......@@ -54,8 +54,8 @@ class VectorBackedLinkedListNode {
VectorBackedLinkedListNode& operator=(VectorBackedLinkedListNode&& other) =
default;
wtf_size_t prev_index_ = 0;
wtf_size_t next_index_ = 0;
wtf_size_t prev_index_ = kNotFound;
wtf_size_t next_index_ = kNotFound;
ValueType value_ = HashTraits<ValueType>::EmptyValue();
};
......@@ -113,7 +113,7 @@ class VectorBackedLinkedList {
const Value& back() const { return nodes_[UsedLastIndex()].value_; }
template <typename IncomingValueType>
iterator insert(const_iterator, IncomingValueType&&);
iterator insert(const_iterator position, IncomingValueType&& value);
template <typename IncomingValueType>
void push_front(IncomingValueType&& value) {
......@@ -125,6 +125,10 @@ class VectorBackedLinkedList {
insert(cend(), std::forward<IncomingValueType>(value));
}
// Moves |target| right before |new_position| in a linked list. This operation
// is executed by just updating indices of related nodes.
void MoveTo(const_iterator target, const_iterator new_position);
private:
bool IsFreeListEmpty() const { return free_head_index_ == anchor_index_; }
......@@ -150,6 +154,8 @@ class VectorBackedLinkedList {
bool IsAnchor(wtf_size_t index) const { return index == anchor_index_; }
void Unlink(const Node&);
Vector<Node> nodes_;
static constexpr wtf_size_t anchor_index_ = 0;
// Anchor is not included in the free list, but it serves as the list's
......@@ -403,6 +409,33 @@ typename VectorBackedLinkedList<T>::iterator VectorBackedLinkedList<T>::insert(
return iterator(new_entry_index, this);
}
template <typename T>
void VectorBackedLinkedList<T>::MoveTo(const_iterator target,
const_iterator new_position) {
wtf_size_t target_index = target.GetIndex();
Node& target_node = nodes_[target_index];
Unlink(target_node);
wtf_size_t new_position_index = new_position.GetIndex();
wtf_size_t prev_index = nodes_[new_position_index].prev_index_;
nodes_[prev_index].next_index_ = target_index;
nodes_[new_position_index].prev_index_ = target_index;
target_node.prev_index_ = prev_index;
target_node.next_index_ = new_position_index;
}
template <typename T>
void VectorBackedLinkedList<T>::Unlink(const Node& node) {
wtf_size_t prev_index = node.prev_index_;
wtf_size_t next_index = node.next_index_;
Node& prev_node = nodes_[prev_index];
Node& next_node = nodes_[next_index];
prev_node.next_index_ = next_index;
next_node.prev_index_ = prev_index;
}
} // namespace WTF
using WTF::VectorBackedLinkedList;
......
......@@ -72,6 +72,44 @@ TEST(VectorBackedLinkedList, PushBack) {
}
}
TEST(VectorBackedLinkedList, MoveTo) {
using List = VectorBackedLinkedList<int>;
List list;
list.push_back(1);
list.push_back(2);
list.push_back(3);
List::iterator target = list.begin();
list.MoveTo(target, list.end()); // {2, 3, 1}
List::iterator it = list.begin();
EXPECT_EQ(*it, 2);
++it;
EXPECT_EQ(*it, 3);
++it;
EXPECT_EQ(*it, 1);
--it;
target = it;
list.MoveTo(target, list.begin()); // {3, 2, 1}
it = list.begin();
EXPECT_EQ(*it, 3);
++it;
EXPECT_EQ(*it, 2);
++it;
EXPECT_EQ(*it, 1);
target = it;
list.MoveTo(target, --it); // {3, 1, 2}
it = list.begin();
EXPECT_EQ(*it, 3);
++it;
EXPECT_EQ(*it, 1);
++it;
EXPECT_EQ(*it, 2);
}
TEST(VectorBackedLinkedList, Iterator) {
using List = VectorBackedLinkedList<int>;
List list;
......
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