Jlm
IntrusiveHashTests.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2014 Helge Bahmann <hcb@chaoticmind.net>
3  * See COPYING for terms of redistribution.
4  */
5 
6 #include <gtest/gtest.h>
7 
9 
10 struct MyItem
11 {
12  MyItem(int k, int v)
13  : key(k),
14  value(v)
15  {}
16 
17  int key;
18  int value;
19 
20  struct
21  {
24  } hash_chain{ nullptr, nullptr };
25 };
26 
27 struct MyAccessor
28 {
29  int
30  get_key(const MyItem * item) const noexcept
31  {
32  return item->key;
33  }
34 
35  MyItem *
36  get_prev(const MyItem * item) const noexcept
37  {
38  return item->hash_chain.prev;
39  }
40 
41  MyItem *
42  get_next(const MyItem * item) const noexcept
43  {
44  return item->hash_chain.next;
45  }
46 
47  void
48  set_prev(MyItem * item, MyItem * prev) const noexcept
49  {
50  item->hash_chain.prev = prev;
51  }
52 
53  void
54  set_next(MyItem * item, MyItem * next) const noexcept
55  {
56  item->hash_chain.next = next;
57  }
58 };
59 
61 
63 {
64  MyStringItem(const std::string & k, const std::string & v)
65  : key(k),
66  value(v)
67  {}
68 
69  std::string key{};
70  std::string value{};
72 
74  std::string,
79 };
80 
82 
83 TEST(IntrusiveHashTests, test_int_hash)
84 {
85  my_hash m;
86 
87  EXPECT_EQ(m.find(42), m.end());
88 
89  MyItem i1 = { 42, 0 };
90  m.insert(&i1);
91  EXPECT_EQ(&*m.find(42), &i1);
92 
93  MyItem i2 = { 10, 0 };
94  m.insert(&i2);
95 
96  m.erase(&i1);
97  EXPECT_EQ(m.find(42), m.end());
98  m.insert(&i1);
99  EXPECT_EQ(&*m.find(42), &i1);
100 
101  int seen_i1 = 0, seen_i2 = 0;
102  for (const MyItem & i : m)
103  {
104  EXPECT_TRUE((&i == &i1) || (&i == &i2));
105  if (&i == &i1)
106  {
107  ++seen_i1;
108  }
109  if (&i == &i2)
110  {
111  ++seen_i2;
112  }
113  }
114  EXPECT_EQ(seen_i1, 1);
115  EXPECT_EQ(seen_i2, 1);
116 }
117 
118 TEST(IntrusiveHashTests, test_str_hash)
119 {
120  my_strhash m;
121 
122  EXPECT_EQ(m.find("42"), m.end());
123 
124  MyStringItem i1 = { "42", "0" };
125  m.insert(&i1);
126  EXPECT_EQ(&*m.find("42"), &i1);
127 
128  MyStringItem i2 = { "10", "0" };
129  m.insert(&i2);
130 
131  m.erase(&i1);
132  EXPECT_EQ(m.find("42"), m.end());
133  m.insert(&i1);
134  EXPECT_EQ(&*m.find("42"), &i1);
135 
136  int seen_i1 = 0, seen_i2 = 0;
137  for (const MyStringItem & i : m)
138  {
139  EXPECT_TRUE((&i == &i1) || (&i == &i2));
140  if (&i == &i1)
141  {
142  ++seen_i1;
143  }
144  if (&i == &i2)
145  {
146  ++seen_i2;
147  }
148  }
149  EXPECT_EQ(seen_i1, 1);
150  EXPECT_EQ(seen_i2, 1);
151 }
jlm::util::IntrusiveHash< int, MyItem, MyAccessor > my_hash
TEST(IntrusiveHashTests, test_int_hash)
jlm::util::IntrusiveHash< std::string, MyStringItem, MyStringItem::hash_accessor > my_strhash
Iterator end() noexcept
Iterator insert(ElementType *element)
void erase(ElementType *element) noexcept
Iterator find(const KeyType &key) noexcept
int get_key(const MyItem *item) const noexcept
void set_prev(MyItem *item, MyItem *prev) const noexcept
MyItem * get_next(const MyItem *item) const noexcept
void set_next(MyItem *item, MyItem *next) const noexcept
MyItem * get_prev(const MyItem *item) const noexcept
MyItem(int k, int v)
MyItem * prev
MyItem * next
MyStringItem(const std::string &k, const std::string &v)
jlm::util::IntrusiveHashAccessor< std::string, MyStringItem, &MyStringItem::key, &MyStringItem::hash_chain > hash_accessor
jlm::util::IntrusiveHashAnchor< MyStringItem > hash_chain