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

Implemented NewLinkedHashSetConstIterator

Implemented NewLinkedHashSetConstIterator, const iterator for
NewLinkedHashSet.
Also added test for it.

Change-Id: I84299d866e0cdb94ac2fbf2c31362a22779e0184
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2086376
Commit-Queue: Bartek Nowierski <bartekn@chromium.org>
Commit-Queue: Kei Nakashima <keinakashima@google.com>
Auto-Submit: Kei Nakashima <keinakashima@google.com>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarYuki Shiino <yukishiino@chromium.org>
Reviewed-by: default avatarBartek Nowierski <bartekn@chromium.org>
Cr-Commit-Position: refs/heads/master@{#747098}
parent 8e250aed
......@@ -132,7 +132,7 @@ bool FontDataCache::PurgeLeastRecentlyUsed(int count) {
auto end = inactive_font_data_.end();
auto it = inactive_font_data_.begin();
for (int i = 0; i < count && it != end; ++it, ++i) {
scoped_refptr<SimpleFontData>& font_data = *it.Get();
scoped_refptr<SimpleFontData>& font_data = *it;
cache_.erase(&(font_data->PlatformData()));
// We should not delete SimpleFontData here because deletion can modify
// m_inactiveFontData. See http://trac.webkit.org/changeset/44011
......
......@@ -1024,6 +1024,9 @@ inline void swap(LinkedHashSetNode<T>& a, LinkedHashSetNode<T>& b) {
// TODO(keinakashima): replace existing LinkedHashSet with NewLinkedHashSet
// after completion
template <typename NewLinkedHashSet>
class NewLinkedHashSetConstIterator;
template <typename ValueArg>
class NewLinkedHashSetNode {
USING_FAST_MALLOC(NewLinkedHashSetNode);
......@@ -1147,6 +1150,8 @@ class NewLinkedHashSet {
using Map = HashMap<Value, wtf_size_t>;
public:
friend class NewLinkedHashSetConstIterator<NewLinkedHashSet>;
using const_iterator = NewLinkedHashSetConstIterator<NewLinkedHashSet>;
// TODO(keinakashima): add security check
struct AddResult final {
STACK_ALLOCATED();
......@@ -1173,7 +1178,9 @@ class NewLinkedHashSet {
wtf_size_t size() const { return value_to_index_.size(); }
bool IsEmpty() const { return value_to_index_.IsEmpty(); }
// TODO(keinakashima): implement iterators
const_iterator begin() const { return MakeConstIterator(UsedFirstIndex()); }
const_iterator end() const { return MakeConstIterator(anchor_index_); }
// TODO(keinakashima): implement reverse const iterator
const Value& front() const;
void RemoveFirst();
......@@ -1212,6 +1219,10 @@ class NewLinkedHashSet {
return free_head_index_;
}
const_iterator MakeConstIterator(wtf_size_t index) const {
return const_iterator(index, this);
}
// Inserts new value before given position to a linked list in vector
// Returns a pointer to the stored value
template <typename IncomingValueType>
......@@ -1228,6 +1239,63 @@ class NewLinkedHashSet {
static constexpr wtf_size_t anchor_index_ = 0;
};
// TODO(keinakashima): add modification check
// TODO(keinakashima): implement DCHECK that prevents mutations while iterating
template <typename NewLinkedHashSetType>
class NewLinkedHashSetConstIterator {
private:
using Node = typename NewLinkedHashSetType::Node;
using ReferenceType = const typename NewLinkedHashSetType::Value&;
using PointerType = const typename NewLinkedHashSetType::Value*;
protected:
NewLinkedHashSetConstIterator(wtf_size_t index,
const NewLinkedHashSetType* container)
: index_(index), container_(container) {}
public:
ReferenceType operator*() const { return *Get(); }
PointerType operator->() const { return Get(); }
NewLinkedHashSetConstIterator& operator++() {
DCHECK(0 <= index_ && index_ < container_->nodes_.size());
index_ = container_->nodes_[index_].GetNextIndexForUsedNode();
return *this;
}
NewLinkedHashSetConstIterator& operator--() {
DCHECK(0 <= index_ && index_ < container_->nodes_.size());
index_ = container_->nodes_[index_].GetPrevIndexForUsedNode();
return *this;
}
NewLinkedHashSetConstIterator operator++(int) = delete;
NewLinkedHashSetConstIterator operator--(int) = delete;
bool operator==(const NewLinkedHashSetConstIterator& other) {
DCHECK_EQ(container_, other.container_);
return index_ == other.index_;
}
bool operator!=(const NewLinkedHashSetConstIterator& other) {
return !(*this == other);
}
protected:
PointerType Get() const {
DCHECK(0 <= index_ && index_ < container_->nodes_.size());
const Node& node = container_->nodes_[index_];
return &node.GetValueForUsedNode();
}
private:
wtf_size_t index_;
const NewLinkedHashSetType* container_;
template <typename T>
friend class NewLinkedHashSet;
};
template <typename T>
NewLinkedHashSet<T>::NewLinkedHashSet() {
// TODO(keinakashima): add assertion when considering GC
......
......@@ -33,6 +33,45 @@ TEST(NewLinkedHashSetTest, Construct) {
EXPECT_EQ(test.size(), 0u);
}
TEST(NewLinkedHashSetTest, Iterator) {
using Set = NewLinkedHashSet<int>;
Set set;
EXPECT_TRUE(set.begin() == set.end());
set.insert(1);
Set::const_iterator it = set.begin();
EXPECT_EQ(*it, 1);
++it;
EXPECT_TRUE(it == set.end());
set.insert(2);
set.insert(3);
it = set.begin();
EXPECT_EQ(*it, 1);
++it;
EXPECT_EQ(*it, 2);
++it;
EXPECT_EQ(*it, 3);
++it;
EXPECT_TRUE(it == set.end());
--it;
EXPECT_EQ(*it, 3);
--it;
EXPECT_EQ(*it, 2);
--it;
EXPECT_EQ(*it, 1);
EXPECT_TRUE(it == set.begin());
EXPECT_TRUE(it != set.end());
int i = 1;
for (auto it : set) {
EXPECT_EQ(it, i);
i++;
}
}
TEST(NewLinkedHashSetTest, InsertAndEraseForInteger) {
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