blob: 394f4d1cc9bc23577ef3cacf6140170179139ec3 [file] [log] [blame]
HYuana9b85752014-02-26 02:32:30 -06001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shia6de4292016-07-12 02:08:10 +00003 * Copyright (c) 2014-2016, Regents of the University of California,
Spyridon Mastorakisd0381c02015-02-19 10:29:41 -08004 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070010 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Alexander Afanasyev28d586a2014-07-10 20:10:54 -070024 */
HYuana9b85752014-02-26 02:32:30 -060025
26#include "table/name-tree.hpp"
Junxiao Shi60607c72014-11-26 22:40:36 -070027
Junxiao Shid9ee45c2014-02-27 15:38:11 -070028#include "tests/test-common.hpp"
HYuana9b85752014-02-26 02:32:30 -060029
30namespace nfd {
Junxiao Shi2570f3e2016-07-27 02:48:29 +000031namespace name_tree {
Junxiao Shid9ee45c2014-02-27 15:38:11 -070032namespace tests {
HYuana9b85752014-02-26 02:32:30 -060033
Junxiao Shi2570f3e2016-07-27 02:48:29 +000034using namespace nfd::tests;
HYuana9b85752014-02-26 02:32:30 -060035
Junxiao Shi2570f3e2016-07-27 02:48:29 +000036BOOST_AUTO_TEST_SUITE(Table)
37BOOST_FIXTURE_TEST_SUITE(TestNameTree, BaseFixture)
HYuana9b85752014-02-26 02:32:30 -060038
Haowei Yuanf52dac72014-03-24 23:35:03 -050039BOOST_AUTO_TEST_CASE(Hash)
40{
41 Name root("/");
42 root.wireEncode();
Junxiao Shi2570f3e2016-07-27 02:48:29 +000043 size_t hashValue = computeHash(root);
44 BOOST_CHECK_EQUAL(hashValue, 0);
Haowei Yuanf52dac72014-03-24 23:35:03 -050045
46 Name prefix("/nohello/world/ndn/research");
47 prefix.wireEncode();
Junxiao Shi2570f3e2016-07-27 02:48:29 +000048 std::vector<size_t> hashSet = computeHashSet(prefix);
Haowei Yuanf52dac72014-03-24 23:35:03 -050049 BOOST_CHECK_EQUAL(hashSet.size(), prefix.size() + 1);
50}
51
Junxiao Shi2570f3e2016-07-27 02:48:29 +000052BOOST_AUTO_TEST_CASE(NameTreeEntry)
HYuana9b85752014-02-26 02:32:30 -060053{
54 Name prefix("ndn:/named-data/research/abc/def/ghi");
55
Junxiao Shi2570f3e2016-07-27 02:48:29 +000056 auto npe = make_shared<Entry>(prefix);
Junxiao Shiefceadc2014-03-09 18:52:57 -070057 BOOST_CHECK_EQUAL(npe->getPrefix(), prefix);
HYuana9b85752014-02-26 02:32:30 -060058
59 // examine all the get methods
60
Haowei Yuanf52dac72014-03-24 23:35:03 -050061 size_t hash = npe->getHash();
Junxiao Shi2570f3e2016-07-27 02:48:29 +000062 BOOST_CHECK_EQUAL(hash, 0);
HYuana9b85752014-02-26 02:32:30 -060063
Junxiao Shi2570f3e2016-07-27 02:48:29 +000064 shared_ptr<Entry> parent = npe->getParent();
65 BOOST_CHECK(parent == nullptr);
HYuana9b85752014-02-26 02:32:30 -060066
Junxiao Shi2570f3e2016-07-27 02:48:29 +000067 std::vector<shared_ptr<Entry>>& childList = npe->getChildren();
68 BOOST_CHECK_EQUAL(childList.size(), 0);
HYuana9b85752014-02-26 02:32:30 -060069
Junxiao Shia6de4292016-07-12 02:08:10 +000070 fib::Entry* fib = npe->getFibEntry();
71 BOOST_CHECK(fib == nullptr);
HYuana9b85752014-02-26 02:32:30 -060072
Junxiao Shi2570f3e2016-07-27 02:48:29 +000073 const std::vector<shared_ptr<pit::Entry>>& pitList = npe->getPitEntries();
74 BOOST_CHECK_EQUAL(pitList.size(), 0);
HYuana9b85752014-02-26 02:32:30 -060075
Haowei Yuane1079fc2014-03-08 14:41:25 -060076 // examine all the set method
HYuana9b85752014-02-26 02:32:30 -060077
Junxiao Shi2570f3e2016-07-27 02:48:29 +000078 npe->setHash(12345);
79 BOOST_CHECK_EQUAL(npe->getHash(), 12345);
HYuana9b85752014-02-26 02:32:30 -060080
81 Name parentName("ndn:/named-data/research/abc/def");
Junxiao Shi2570f3e2016-07-27 02:48:29 +000082 parent = make_shared<Entry>(parentName);
Junxiao Shiefceadc2014-03-09 18:52:57 -070083 npe->setParent(parent);
84 BOOST_CHECK_EQUAL(npe->getParent(), parent);
HYuana9b85752014-02-26 02:32:30 -060085
Haowei Yuane1079fc2014-03-08 14:41:25 -060086 // Insert FIB
HYuana9b85752014-02-26 02:32:30 -060087
Junxiao Shia6de4292016-07-12 02:08:10 +000088 npe->setFibEntry(make_unique<fib::Entry>(prefix));
89 BOOST_REQUIRE(npe->getFibEntry() != nullptr);
90 BOOST_CHECK_EQUAL(npe->getFibEntry()->getPrefix(), prefix);
Haowei Yuane1079fc2014-03-08 14:41:25 -060091
Junxiao Shia6de4292016-07-12 02:08:10 +000092 npe->setFibEntry(nullptr);
93 BOOST_CHECK(npe->getFibEntry() == nullptr);
HYuana9b85752014-02-26 02:32:30 -060094
95 // Insert a PIT
96
Junxiao Shi2570f3e2016-07-27 02:48:29 +000097 auto pitEntry = make_shared<pit::Entry>(*makeInterest(prefix));
98 auto pitEntry2 = make_shared<pit::Entry>(*makeInterest(parentName));
HYuana9b85752014-02-26 02:32:30 -060099
Alexander Afanasyev28d586a2014-07-10 20:10:54 -0700100 npe->insertPitEntry(pitEntry);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700101 BOOST_CHECK_EQUAL(npe->getPitEntries().size(), 1);
HYuana9b85752014-02-26 02:32:30 -0600102
Alexander Afanasyev28d586a2014-07-10 20:10:54 -0700103 npe->insertPitEntry(pitEntry2);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700104 BOOST_CHECK_EQUAL(npe->getPitEntries().size(), 2);
HYuana9b85752014-02-26 02:32:30 -0600105
Alexander Afanasyev28d586a2014-07-10 20:10:54 -0700106 npe->erasePitEntry(pitEntry);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700107 BOOST_CHECK_EQUAL(npe->getPitEntries().size(), 1);
HYuana9b85752014-02-26 02:32:30 -0600108
Alexander Afanasyev28d586a2014-07-10 20:10:54 -0700109 npe->erasePitEntry(pitEntry2);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700110 BOOST_CHECK_EQUAL(npe->getPitEntries().size(), 0);
HYuana9b85752014-02-26 02:32:30 -0600111}
112
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700113BOOST_AUTO_TEST_CASE(Basic)
HYuana9b85752014-02-26 02:32:30 -0600114{
115 size_t nBuckets = 16;
116 NameTree nt(nBuckets);
117
118 BOOST_CHECK_EQUAL(nt.size(), 0);
Haowei Yuane1079fc2014-03-08 14:41:25 -0600119 BOOST_CHECK_EQUAL(nt.getNBuckets(), nBuckets);
HYuana9b85752014-02-26 02:32:30 -0600120
Haowei Yuane1079fc2014-03-08 14:41:25 -0600121 Name nameABC("ndn:/a/b/c");
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000122 shared_ptr<Entry> npeABC = nt.lookup(nameABC);
HYuana9b85752014-02-26 02:32:30 -0600123 BOOST_CHECK_EQUAL(nt.size(), 4);
Haowei Yuane1079fc2014-03-08 14:41:25 -0600124
125 Name nameABD("/a/b/d");
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000126 shared_ptr<Entry> npeABD = nt.lookup(nameABD);
HYuana9b85752014-02-26 02:32:30 -0600127 BOOST_CHECK_EQUAL(nt.size(), 5);
128
Haowei Yuane1079fc2014-03-08 14:41:25 -0600129 Name nameAE("/a/e/");
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000130 shared_ptr<Entry> npeAE = nt.lookup(nameAE);
HYuana9b85752014-02-26 02:32:30 -0600131 BOOST_CHECK_EQUAL(nt.size(), 6);
132
Haowei Yuane1079fc2014-03-08 14:41:25 -0600133 Name nameF("/f");
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000134 shared_ptr<Entry> npeF = nt.lookup(nameF);
HYuana9b85752014-02-26 02:32:30 -0600135 BOOST_CHECK_EQUAL(nt.size(), 7);
136
Haowei Yuane1079fc2014-03-08 14:41:25 -0600137 // validate lookup() and findExactMatch()
HYuana9b85752014-02-26 02:32:30 -0600138
139 Name nameAB ("/a/b");
140 BOOST_CHECK_EQUAL(npeABC->getParent(), nt.findExactMatch(nameAB));
141 BOOST_CHECK_EQUAL(npeABD->getParent(), nt.findExactMatch(nameAB));
142
143 Name nameA ("/a");
144 BOOST_CHECK_EQUAL(npeAE->getParent(), nt.findExactMatch(nameA));
145
146 Name nameRoot ("/");
147 BOOST_CHECK_EQUAL(npeF->getParent(), nt.findExactMatch(nameRoot));
148 BOOST_CHECK_EQUAL(nt.size(), 7);
149
Haowei Yuane1079fc2014-03-08 14:41:25 -0600150 Name name0("/does/not/exist");
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000151 shared_ptr<Entry> npe0 = nt.findExactMatch(name0);
152 BOOST_CHECK(npe0 == nullptr);
HYuana9b85752014-02-26 02:32:30 -0600153
154
155 // Longest Prefix Matching
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000156 shared_ptr<Entry> temp;
HYuana9b85752014-02-26 02:32:30 -0600157 Name nameABCLPM("/a/b/c/def/asdf/nlf");
158 temp = nt.findLongestPrefixMatch(nameABCLPM);
159 BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameABC));
160
161 Name nameABDLPM("/a/b/d/def/asdf/nlf");
162 temp = nt.findLongestPrefixMatch(nameABDLPM);
163 BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameABD));
164
165 Name nameABLPM("/a/b/hello/world");
166 temp = nt.findLongestPrefixMatch(nameABLPM);
167 BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameAB));
168
169 Name nameAELPM("/a/e/hello/world");
170 temp = nt.findLongestPrefixMatch(nameAELPM);
171 BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameAE));
172
173 Name nameALPM("/a/hello/world");
174 temp = nt.findLongestPrefixMatch(nameALPM);
175 BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameA));
176
177 Name nameFLPM("/f/hello/world");
178 temp = nt.findLongestPrefixMatch(nameFLPM);
179 BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameF));
180
181 Name nameRootLPM("/does_not_exist");
182 temp = nt.findLongestPrefixMatch(nameRootLPM);
183 BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameRoot));
184
HYuana9b85752014-02-26 02:32:30 -0600185 bool eraseResult = false;
186 temp = nt.findExactMatch(nameABC);
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000187 if (temp != nullptr)
188 eraseResult = nt.eraseEntryIfEmpty(temp);
HYuana9b85752014-02-26 02:32:30 -0600189 BOOST_CHECK_EQUAL(nt.size(), 6);
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000190 BOOST_CHECK(nt.findExactMatch(nameABC) == nullptr);
HYuana9b85752014-02-26 02:32:30 -0600191 BOOST_CHECK_EQUAL(eraseResult, true);
192
193 eraseResult = false;
194 temp = nt.findExactMatch(nameABCLPM);
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000195 if (temp != nullptr)
196 eraseResult = nt.eraseEntryIfEmpty(temp);
197 BOOST_CHECK(temp == nullptr);
HYuana9b85752014-02-26 02:32:30 -0600198 BOOST_CHECK_EQUAL(nt.size(), 6);
199 BOOST_CHECK_EQUAL(eraseResult, false);
200
201 // nt.dump(std::cout);
202
203 nt.lookup(nameABC);
204 BOOST_CHECK_EQUAL(nt.size(), 7);
205
206 eraseResult = false;
207 temp = nt.findExactMatch(nameABC);
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000208 if (temp != nullptr)
209 eraseResult = nt.eraseEntryIfEmpty(temp);
HYuana9b85752014-02-26 02:32:30 -0600210 BOOST_CHECK_EQUAL(nt.size(), 6);
211 BOOST_CHECK_EQUAL(eraseResult, true);
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000212 BOOST_CHECK(nt.findExactMatch(nameABC) == nullptr);
HYuana9b85752014-02-26 02:32:30 -0600213
HYuana9b85752014-02-26 02:32:30 -0600214 BOOST_CHECK_EQUAL(nt.getNBuckets(), 16);
215
Haowei Yuane1079fc2014-03-08 14:41:25 -0600216 // should resize now
HYuana9b85752014-02-26 02:32:30 -0600217 Name nameABCD("a/b/c/d");
218 nt.lookup(nameABCD);
219 Name nameABCDE("a/b/c/d/e");
220 nt.lookup(nameABCDE);
221 BOOST_CHECK_EQUAL(nt.size(), 9);
222 BOOST_CHECK_EQUAL(nt.getNBuckets(), 32);
223
Haowei Yuane1079fc2014-03-08 14:41:25 -0600224 // try to erase /a/b/c, should return false
HYuana9b85752014-02-26 02:32:30 -0600225 temp = nt.findExactMatch(nameABC);
226 BOOST_CHECK_EQUAL(temp->getPrefix(), nameABC);
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000227 eraseResult = nt.eraseEntryIfEmpty(temp);
HYuana9b85752014-02-26 02:32:30 -0600228 BOOST_CHECK_EQUAL(eraseResult, false);
229 temp = nt.findExactMatch(nameABC);
230 BOOST_CHECK_EQUAL(temp->getPrefix(), nameABC);
231
232 temp = nt.findExactMatch(nameABD);
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000233 if (temp != nullptr)
234 nt.eraseEntryIfEmpty(temp);
HYuana9b85752014-02-26 02:32:30 -0600235 BOOST_CHECK_EQUAL(nt.size(), 8);
Haowei Yuane1079fc2014-03-08 14:41:25 -0600236}
HYuana9b85752014-02-26 02:32:30 -0600237
Junxiao Shi60607c72014-11-26 22:40:36 -0700238/** \brief verify a NameTree enumeration contains expected entries
239 *
240 * Example:
241 * \code{.cpp}
242 * auto& enumerable = ...;
243 * EnumerationVerifier(enumerable)
244 * .expect("/A")
245 * .expect("/B")
246 * .end();
247 * // enumerable must have /A /B and nothing else to pass the test.
248 * \endcode
249 */
250class EnumerationVerifier : noncopyable
Haowei Yuane1079fc2014-03-08 14:41:25 -0600251{
Junxiao Shi60607c72014-11-26 22:40:36 -0700252public:
253 template<typename Enumerable>
254 EnumerationVerifier(Enumerable&& enumerable)
255 {
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000256 for (const Entry& entry : enumerable) {
Junxiao Shi60607c72014-11-26 22:40:36 -0700257 const Name& name = entry.getPrefix();
258 BOOST_CHECK_MESSAGE(m_names.insert(name).second, "duplicate Name " << name);
259 }
260 }
HYuana9b85752014-02-26 02:32:30 -0600261
Junxiao Shi60607c72014-11-26 22:40:36 -0700262 EnumerationVerifier&
263 expect(const Name& name)
264 {
265 BOOST_CHECK_MESSAGE(m_names.erase(name) == 1, "missing Name " << name);
266 return *this;
267 }
Haowei Yuane1079fc2014-03-08 14:41:25 -0600268
Junxiao Shi60607c72014-11-26 22:40:36 -0700269 void
270 end()
271 {
Alexander Afanasyeve84044e2015-02-26 21:52:18 -0800272 BOOST_CHECK(m_names.empty());
Junxiao Shi60607c72014-11-26 22:40:36 -0700273 }
274
275private:
276 std::unordered_set<Name> m_names;
277};
278
279class EnumerationFixture : public BaseFixture
280{
281protected:
282 EnumerationFixture()
283 : nt(N_BUCKETS)
284 {
285 BOOST_CHECK_EQUAL(nt.size(), 0);
286 BOOST_CHECK_EQUAL(nt.getNBuckets(), N_BUCKETS);
287 }
288
289 void
290 insertAbAc()
291 {
292 nt.lookup("/a/b");
293 nt.lookup("/a/c");
294 BOOST_CHECK_EQUAL(nt.size(), 4);
295 // /, /a, /a/b, /a/c
296 }
297
298 void
299 insertAb1Ab2Ac1Ac2()
300 {
301 nt.lookup("/a/b/1");
302 nt.lookup("/a/b/2");
303 nt.lookup("/a/c/1");
304 nt.lookup("/a/c/2");
305 BOOST_CHECK_EQUAL(nt.size(), 8);
306 // /, /a, /a/b, /a/b/1, /a/b/2, /a/c, /a/c/1, /a/c/2
307 }
308
309protected:
310 static const size_t N_BUCKETS = 16;
311 NameTree nt;
312};
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000313
Junxiao Shi60607c72014-11-26 22:40:36 -0700314const size_t EnumerationFixture::N_BUCKETS;
315
316BOOST_FIXTURE_TEST_CASE(IteratorFullEnumerate, EnumerationFixture)
317{
318 nt.lookup("/a/b/c");
Haowei Yuane1079fc2014-03-08 14:41:25 -0600319 BOOST_CHECK_EQUAL(nt.size(), 4);
320
Junxiao Shi60607c72014-11-26 22:40:36 -0700321 nt.lookup("/a/b/d");
Haowei Yuane1079fc2014-03-08 14:41:25 -0600322 BOOST_CHECK_EQUAL(nt.size(), 5);
323
Junxiao Shi60607c72014-11-26 22:40:36 -0700324 nt.lookup("/a/e");
Haowei Yuane1079fc2014-03-08 14:41:25 -0600325 BOOST_CHECK_EQUAL(nt.size(), 6);
326
Junxiao Shi60607c72014-11-26 22:40:36 -0700327 nt.lookup("/f");
Haowei Yuane1079fc2014-03-08 14:41:25 -0600328 BOOST_CHECK_EQUAL(nt.size(), 7);
329
Junxiao Shi60607c72014-11-26 22:40:36 -0700330 nt.lookup("/");
Haowei Yuane1079fc2014-03-08 14:41:25 -0600331 BOOST_CHECK_EQUAL(nt.size(), 7);
332
Junxiao Shi60607c72014-11-26 22:40:36 -0700333 auto&& enumerable = nt.fullEnumerate();
334 EnumerationVerifier(enumerable)
335 .expect("/")
336 .expect("/a")
337 .expect("/a/b")
338 .expect("/a/b/c")
339 .expect("/a/b/d")
340 .expect("/a/e")
341 .expect("/f")
342 .end();
Haowei Yuane1079fc2014-03-08 14:41:25 -0600343}
344
Junxiao Shi60607c72014-11-26 22:40:36 -0700345BOOST_FIXTURE_TEST_SUITE(IteratorPartialEnumerate, EnumerationFixture)
Haowei Yuane1079fc2014-03-08 14:41:25 -0600346
Junxiao Shi60607c72014-11-26 22:40:36 -0700347BOOST_AUTO_TEST_CASE(Empty)
Haowei Yuane1079fc2014-03-08 14:41:25 -0600348{
Junxiao Shi60607c72014-11-26 22:40:36 -0700349 auto&& enumerable = nt.partialEnumerate("/a");
350
351 EnumerationVerifier(enumerable)
352 .end();
Haowei Yuane1079fc2014-03-08 14:41:25 -0600353}
354
Junxiao Shi60607c72014-11-26 22:40:36 -0700355BOOST_AUTO_TEST_CASE(NotIn)
Haowei Yuane1079fc2014-03-08 14:41:25 -0600356{
Junxiao Shi60607c72014-11-26 22:40:36 -0700357 this->insertAbAc();
Haowei Yuane1079fc2014-03-08 14:41:25 -0600358
359 // Enumerate on some name that is not in nameTree
Junxiao Shi60607c72014-11-26 22:40:36 -0700360 Name name0("/0");
361 auto&& enumerable = nt.partialEnumerate("/0");
362
363 EnumerationVerifier(enumerable)
364 .end();
365}
366
367BOOST_AUTO_TEST_CASE(OnlyA)
368{
369 this->insertAbAc();
Haowei Yuane1079fc2014-03-08 14:41:25 -0600370
371 // Accept "root" nameA only
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000372 auto&& enumerable = nt.partialEnumerate("/a", [] (const Entry& entry) {
Junxiao Shi60607c72014-11-26 22:40:36 -0700373 return std::make_pair(entry.getPrefix() == "/a", true);
374 });
375
376 EnumerationVerifier(enumerable)
377 .expect("/a")
378 .end();
379}
380
381BOOST_AUTO_TEST_CASE(ExceptA)
382{
383 this->insertAbAc();
Haowei Yuane1079fc2014-03-08 14:41:25 -0600384
385 // Accept anything except "root" nameA
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000386 auto&& enumerable = nt.partialEnumerate("/a", [] (const Entry& entry) {
Junxiao Shi60607c72014-11-26 22:40:36 -0700387 return std::make_pair(entry.getPrefix() != "/a", true);
388 });
Haowei Yuane1079fc2014-03-08 14:41:25 -0600389
Junxiao Shi60607c72014-11-26 22:40:36 -0700390 EnumerationVerifier(enumerable)
391 .expect("/a/b")
392 .expect("/a/c")
393 .end();
394}
Haowei Yuane1079fc2014-03-08 14:41:25 -0600395
Junxiao Shi60607c72014-11-26 22:40:36 -0700396BOOST_AUTO_TEST_CASE(NoNameANoSubTreeAB)
397{
398 this->insertAb1Ab2Ac1Ac2();
Haowei Yuane1079fc2014-03-08 14:41:25 -0600399
400 // No NameA
401 // No SubTree from NameAB
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000402 auto&& enumerable = nt.partialEnumerate("/a", [] (const Entry& entry) {
Junxiao Shi60607c72014-11-26 22:40:36 -0700403 return std::make_pair(entry.getPrefix() != "/a", entry.getPrefix() != "/a/b");
404 });
Haowei Yuane1079fc2014-03-08 14:41:25 -0600405
Junxiao Shi60607c72014-11-26 22:40:36 -0700406 EnumerationVerifier(enumerable)
407 .expect("/a/b")
408 .expect("/a/c")
409 .expect("/a/c/1")
410 .expect("/a/c/2")
411 .end();
412}
Haowei Yuane1079fc2014-03-08 14:41:25 -0600413
Junxiao Shi60607c72014-11-26 22:40:36 -0700414BOOST_AUTO_TEST_CASE(NoNameANoSubTreeAC)
415{
416 this->insertAb1Ab2Ac1Ac2();
Haowei Yuane1079fc2014-03-08 14:41:25 -0600417
418 // No NameA
419 // No SubTree from NameAC
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000420 auto&& enumerable = nt.partialEnumerate("/a", [] (const Entry& entry) {
Junxiao Shi60607c72014-11-26 22:40:36 -0700421 return std::make_pair(entry.getPrefix() != "/a", entry.getPrefix() != "/a/c");
422 });
Haowei Yuane1079fc2014-03-08 14:41:25 -0600423
Junxiao Shi60607c72014-11-26 22:40:36 -0700424 EnumerationVerifier(enumerable)
425 .expect("/a/b")
426 .expect("/a/b/1")
427 .expect("/a/b/2")
428 .expect("/a/c")
429 .end();
430}
Haowei Yuane1079fc2014-03-08 14:41:25 -0600431
Junxiao Shi60607c72014-11-26 22:40:36 -0700432BOOST_AUTO_TEST_CASE(NoSubTreeA)
433{
434 this->insertAb1Ab2Ac1Ac2();
Haowei Yuane1079fc2014-03-08 14:41:25 -0600435
436 // No Subtree from NameA
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000437 auto&& enumerable = nt.partialEnumerate("/a", [] (const Entry& entry) {
Junxiao Shi60607c72014-11-26 22:40:36 -0700438 return std::make_pair(true, entry.getPrefix() != "/a");
439 });
Haowei Yuane1079fc2014-03-08 14:41:25 -0600440
Junxiao Shi60607c72014-11-26 22:40:36 -0700441 EnumerationVerifier(enumerable)
442 .expect("/a")
443 .end();
444}
Haowei Yuane1079fc2014-03-08 14:41:25 -0600445
Junxiao Shi60607c72014-11-26 22:40:36 -0700446BOOST_AUTO_TEST_CASE(Example)
447{
Haowei Yuane1079fc2014-03-08 14:41:25 -0600448 // Example
449 // /
450 // /A
451 // /A/B x
452 // /A/B/C
453 // /A/D x
454 // /E
455 // /F
456
Junxiao Shi60607c72014-11-26 22:40:36 -0700457 nt.lookup("/A");
458 nt.lookup("/A/B");
459 nt.lookup("/A/B/C");
460 nt.lookup("/A/D");
461 nt.lookup("/E");
462 nt.lookup("/F");
Haowei Yuane1079fc2014-03-08 14:41:25 -0600463
Junxiao Shi60607c72014-11-26 22:40:36 -0700464 auto&& enumerable = nt.partialEnumerate("/A",
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000465 [] (const Entry& entry) -> std::pair<bool, bool> {
Junxiao Shi60607c72014-11-26 22:40:36 -0700466 bool visitEntry = false;
467 bool visitChildren = false;
Haowei Yuane1079fc2014-03-08 14:41:25 -0600468
Junxiao Shi60607c72014-11-26 22:40:36 -0700469 Name name = entry.getPrefix();
Haowei Yuane1079fc2014-03-08 14:41:25 -0600470
Junxiao Shi60607c72014-11-26 22:40:36 -0700471 if (name == "/" || name == "/A/B" || name == "/A/B/C" || name == "/A/D") {
472 visitEntry = true;
473 }
Haowei Yuane1079fc2014-03-08 14:41:25 -0600474
Junxiao Shi60607c72014-11-26 22:40:36 -0700475 if (name == "/" || name == "/A" || name == "/F") {
476 visitChildren = true;
477 }
Haowei Yuane1079fc2014-03-08 14:41:25 -0600478
Junxiao Shi60607c72014-11-26 22:40:36 -0700479 return {visitEntry, visitChildren};
480 });
Haowei Yuane1079fc2014-03-08 14:41:25 -0600481
Junxiao Shi60607c72014-11-26 22:40:36 -0700482 EnumerationVerifier(enumerable)
483 .expect("/A/B")
484 .expect("/A/D")
485 .end();
Haowei Yuane1079fc2014-03-08 14:41:25 -0600486}
487
Junxiao Shi60607c72014-11-26 22:40:36 -0700488BOOST_AUTO_TEST_SUITE_END()
Haowei Yuane1079fc2014-03-08 14:41:25 -0600489
Junxiao Shi60607c72014-11-26 22:40:36 -0700490BOOST_FIXTURE_TEST_CASE(IteratorFindAllMatches, EnumerationFixture)
Haowei Yuane1079fc2014-03-08 14:41:25 -0600491{
Junxiao Shi60607c72014-11-26 22:40:36 -0700492 nt.lookup("/a/b/c/d/e/f");
493 nt.lookup("/a/a/c");
494 nt.lookup("/a/a/d/1");
495 nt.lookup("/a/a/d/2");
Haowei Yuane1079fc2014-03-08 14:41:25 -0600496 BOOST_CHECK_EQUAL(nt.size(), 12);
497
Junxiao Shi60607c72014-11-26 22:40:36 -0700498 auto&& allMatches = nt.findAllMatches("/a/b/c/d/e");
Haowei Yuane1079fc2014-03-08 14:41:25 -0600499
Junxiao Shi60607c72014-11-26 22:40:36 -0700500 EnumerationVerifier(allMatches)
501 .expect("/")
502 .expect("/a")
503 .expect("/a/b")
504 .expect("/a/b/c")
505 .expect("/a/b/c/d")
506 .expect("/a/b/c/d/e")
507 .end();
HYuana9b85752014-02-26 02:32:30 -0600508}
509
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700510BOOST_AUTO_TEST_CASE(HashTableResizeShrink)
Haowei Yuanf52dac72014-03-24 23:35:03 -0500511{
512 size_t nBuckets = 16;
513 NameTree nameTree(nBuckets);
514
515 Name prefix("/a/b/c/d/e/f/g/h"); // requires 9 buckets
516
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000517 shared_ptr<Entry> entry = nameTree.lookup(prefix);
Haowei Yuanf52dac72014-03-24 23:35:03 -0500518 BOOST_CHECK_EQUAL(nameTree.size(), 9);
519 BOOST_CHECK_EQUAL(nameTree.getNBuckets(), 32);
520
521 nameTree.eraseEntryIfEmpty(entry);
522 BOOST_CHECK_EQUAL(nameTree.size(), 0);
523 BOOST_CHECK_EQUAL(nameTree.getNBuckets(), 16);
524}
525
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700526// .lookup should not invalidate iterator
527BOOST_AUTO_TEST_CASE(SurvivedIteratorAfterLookup)
528{
529 NameTree nt;
530 nt.lookup("/A/B/C");
531 nt.lookup("/E");
532
533 Name nameB("/A/B");
534 std::set<Name> seenNames;
535 for (NameTree::const_iterator it = nt.begin(); it != nt.end(); ++it) {
536 BOOST_CHECK(seenNames.insert(it->getPrefix()).second);
537 if (it->getPrefix() == nameB) {
538 nt.lookup("/D");
539 }
540 }
541
542 BOOST_CHECK_EQUAL(seenNames.count("/"), 1);
543 BOOST_CHECK_EQUAL(seenNames.count("/A"), 1);
544 BOOST_CHECK_EQUAL(seenNames.count("/A/B"), 1);
545 BOOST_CHECK_EQUAL(seenNames.count("/A/B/C"), 1);
546 BOOST_CHECK_EQUAL(seenNames.count("/E"), 1);
547
548 seenNames.erase("/D"); // /D may or may not appear
549 BOOST_CHECK(seenNames.size() == 5);
550}
551
552// .eraseEntryIfEmpty should not invalidate iterator
553BOOST_AUTO_TEST_CASE(SurvivedIteratorAfterErase)
554{
555 NameTree nt;
556 nt.lookup("/A/B/C");
557 nt.lookup("/A/D/E");
558 nt.lookup("/A/F/G");
559 nt.lookup("/H");
560
561 Name nameD("/A/D");
562 std::set<Name> seenNames;
563 for (NameTree::const_iterator it = nt.begin(); it != nt.end(); ++it) {
564 BOOST_CHECK(seenNames.insert(it->getPrefix()).second);
565 if (it->getPrefix() == nameD) {
566 nt.eraseEntryIfEmpty(nt.findExactMatch("/A/F/G")); // /A/F/G and /A/F are erased
567 }
568 }
569
570 BOOST_CHECK_EQUAL(seenNames.count("/"), 1);
571 BOOST_CHECK_EQUAL(seenNames.count("/A"), 1);
572 BOOST_CHECK_EQUAL(seenNames.count("/A/B"), 1);
573 BOOST_CHECK_EQUAL(seenNames.count("/A/B/C"), 1);
574 BOOST_CHECK_EQUAL(seenNames.count("/A/D"), 1);
575 BOOST_CHECK_EQUAL(seenNames.count("/A/D/E"), 1);
576 BOOST_CHECK_EQUAL(seenNames.count("/H"), 1);
577
578 seenNames.erase("/A/F"); // /A/F may or may not appear
579 seenNames.erase("/A/F/G"); // /A/F/G may or may not appear
580 BOOST_CHECK(seenNames.size() == 7);
581}
582
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000583BOOST_AUTO_TEST_SUITE_END() // TestNameTree
584BOOST_AUTO_TEST_SUITE_END() // Table
HYuana9b85752014-02-26 02:32:30 -0600585
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700586} // namespace tests
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000587} // namespace name_tree
HYuana9b85752014-02-26 02:32:30 -0600588} // namespace nfd