tint/utils: Add Generation() to Hashmap and Hashset.
Useful for knowing if you have to look up an entry again since the last lookup. Change-Id: Ib0374627ef5cd7fcff7fa2d9e72b4214260b2df3 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/100901 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Dan Sinclair <dsinclair@chromium.org> Commit-Queue: Ben Clayton <bclayton@chromium.org>
This commit is contained in:
parent
4d67a883b6
commit
4e0335c5af
|
@ -288,6 +288,9 @@ class Hashmap {
|
||||||
/// @returns the number of entries in the map.
|
/// @returns the number of entries in the map.
|
||||||
size_t Count() const { return set_.Count(); }
|
size_t Count() const { return set_.Count(); }
|
||||||
|
|
||||||
|
/// @returns a monotonic counter which is incremented whenever the map is mutated.
|
||||||
|
size_t Generation() const { return set_.Generation(); }
|
||||||
|
|
||||||
/// @returns true if the map contains no entries.
|
/// @returns true if the map contains no entries.
|
||||||
bool IsEmpty() const { return set_.IsEmpty(); }
|
bool IsEmpty() const { return set_.IsEmpty(); }
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,27 @@ TEST(Hashmap, ReplaceRemove) {
|
||||||
EXPECT_FALSE(map.Contains("world"));
|
EXPECT_FALSE(map.Contains("world"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Hashmap, Generation) {
|
||||||
|
Hashmap<int, std::string, 8> map;
|
||||||
|
EXPECT_EQ(map.Generation(), 0u);
|
||||||
|
map.Add(1, "one");
|
||||||
|
EXPECT_EQ(map.Generation(), 1u);
|
||||||
|
map.Add(1, "uno");
|
||||||
|
EXPECT_EQ(map.Generation(), 1u);
|
||||||
|
map.Replace(1, "une");
|
||||||
|
EXPECT_EQ(map.Generation(), 2u);
|
||||||
|
map.Add(2, "dos");
|
||||||
|
EXPECT_EQ(map.Generation(), 3u);
|
||||||
|
map.Remove(1);
|
||||||
|
EXPECT_EQ(map.Generation(), 4u);
|
||||||
|
map.Clear();
|
||||||
|
EXPECT_EQ(map.Generation(), 5u);
|
||||||
|
map.Find(2);
|
||||||
|
EXPECT_EQ(map.Generation(), 5u);
|
||||||
|
map.Get(2);
|
||||||
|
EXPECT_EQ(map.Generation(), 5u);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(Hashmap, Iterator) {
|
TEST(Hashmap, Iterator) {
|
||||||
using Map = Hashmap<int, std::string, 8>;
|
using Map = Hashmap<int, std::string, 8>;
|
||||||
using KV = typename Map::KeyValue;
|
using KV = typename Map::KeyValue;
|
||||||
|
|
|
@ -73,7 +73,8 @@ class Hashset {
|
||||||
static constexpr size_t kMinSlots = std::max<size_t>(kNumFixedSlots, 4);
|
static constexpr size_t kMinSlots = std::max<size_t>(kNumFixedSlots, 4);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Iterator for entries in the set
|
/// Iterator for entries in the set.
|
||||||
|
/// Iterators are invalidated if the set is modified.
|
||||||
class Iterator {
|
class Iterator {
|
||||||
public:
|
public:
|
||||||
/// @returns the value pointed to by this iterator
|
/// @returns the value pointed to by this iterator
|
||||||
|
@ -152,6 +153,7 @@ class Hashset {
|
||||||
slots_.Clear(); // Destructs all entries
|
slots_.Clear(); // Destructs all entries
|
||||||
slots_.Resize(kMinSlots);
|
slots_.Resize(kMinSlots);
|
||||||
count_ = 0;
|
count_ = 0;
|
||||||
|
generation_++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Result of Add()
|
/// Result of Add()
|
||||||
|
@ -219,6 +221,7 @@ class Hashset {
|
||||||
|
|
||||||
// Entry was removed.
|
// Entry was removed.
|
||||||
count_--;
|
count_--;
|
||||||
|
generation_++;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -299,6 +302,9 @@ class Hashset {
|
||||||
/// @returns true if the set contains no entries.
|
/// @returns true if the set contains no entries.
|
||||||
bool IsEmpty() const { return count_ == 0; }
|
bool IsEmpty() const { return count_ == 0; }
|
||||||
|
|
||||||
|
/// @returns a monotonic counter which is incremented whenever the set is mutated.
|
||||||
|
size_t Generation() const { return generation_; }
|
||||||
|
|
||||||
/// @returns an iterator to the start of the set.
|
/// @returns an iterator to the start of the set.
|
||||||
Iterator begin() const { return Iterator{slots_.begin(), slots_.end()}; }
|
Iterator begin() const { return Iterator{slots_.begin(), slots_.end()}; }
|
||||||
|
|
||||||
|
@ -351,6 +357,7 @@ class Hashset {
|
||||||
slot.hash = hash.value;
|
slot.hash = hash.value;
|
||||||
slot.distance = distance;
|
slot.distance = distance;
|
||||||
count_++;
|
count_++;
|
||||||
|
generation_++;
|
||||||
result = AddResult{AddAction::kAdded, &slot.value.value()};
|
result = AddResult{AddAction::kAdded, &slot.value.value()};
|
||||||
return Action::kStop;
|
return Action::kStop;
|
||||||
}
|
}
|
||||||
|
@ -361,6 +368,7 @@ class Hashset {
|
||||||
// Slot is equal to value. Replace or preserve?
|
// Slot is equal to value. Replace or preserve?
|
||||||
if constexpr (MODE == PutMode::kReplace) {
|
if constexpr (MODE == PutMode::kReplace) {
|
||||||
slot.value = std::forward<V>(value);
|
slot.value = std::forward<V>(value);
|
||||||
|
generation_++;
|
||||||
result = AddResult{AddAction::kReplaced, &slot.value.value()};
|
result = AddResult{AddAction::kReplaced, &slot.value.value()};
|
||||||
} else {
|
} else {
|
||||||
result = AddResult{AddAction::kKeptExisting, &slot.value.value()};
|
result = AddResult{AddAction::kKeptExisting, &slot.value.value()};
|
||||||
|
@ -380,6 +388,7 @@ class Hashset {
|
||||||
InsertShuffle(Wrap(index + 1), std::move(evicted));
|
InsertShuffle(Wrap(index + 1), std::move(evicted));
|
||||||
|
|
||||||
count_++;
|
count_++;
|
||||||
|
generation_++;
|
||||||
result = AddResult{AddAction::kAdded, &slot.value.value()};
|
result = AddResult{AddAction::kAdded, &slot.value.value()};
|
||||||
|
|
||||||
return Action::kStop;
|
return Action::kStop;
|
||||||
|
@ -502,6 +511,9 @@ class Hashset {
|
||||||
|
|
||||||
/// The number of entries in the set.
|
/// The number of entries in the set.
|
||||||
size_t count_ = 0;
|
size_t count_ = 0;
|
||||||
|
|
||||||
|
/// Counter that's incremented with each modification to the set.
|
||||||
|
size_t generation_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tint::utils
|
} // namespace tint::utils
|
||||||
|
|
|
@ -67,6 +67,27 @@ TEST(Hashset, AddMany) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Hashset, Generation) {
|
||||||
|
Hashset<int, 8> set;
|
||||||
|
EXPECT_EQ(set.Generation(), 0u);
|
||||||
|
set.Add(1);
|
||||||
|
EXPECT_EQ(set.Generation(), 1u);
|
||||||
|
set.Add(1);
|
||||||
|
EXPECT_EQ(set.Generation(), 1u);
|
||||||
|
set.Replace(1);
|
||||||
|
EXPECT_EQ(set.Generation(), 2u);
|
||||||
|
set.Add(2);
|
||||||
|
EXPECT_EQ(set.Generation(), 3u);
|
||||||
|
set.Remove(1);
|
||||||
|
EXPECT_EQ(set.Generation(), 4u);
|
||||||
|
set.Clear();
|
||||||
|
EXPECT_EQ(set.Generation(), 5u);
|
||||||
|
set.Find(2);
|
||||||
|
EXPECT_EQ(set.Generation(), 5u);
|
||||||
|
set.Get(2);
|
||||||
|
EXPECT_EQ(set.Generation(), 5u);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(Hashset, Iterator) {
|
TEST(Hashset, Iterator) {
|
||||||
Hashset<std::string, 8> set;
|
Hashset<std::string, 8> set;
|
||||||
set.Add("one");
|
set.Add("one");
|
||||||
|
|
Loading…
Reference in New Issue