blob: e5e9089afb05197f18168155753309f8786acd0d [file] [log] [blame]
HYuana9b85752014-02-26 02:32:30 -06001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -07003 * Copyright (c) 2014 Regents of the University of California,
4 * 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 *
10 * This file is part of NFD (Named Data Networking Forwarding Daemon).
11 * See AUTHORS.md for complete list of NFD authors and contributors.
12 *
13 * NFD is free software: you can redistribute it and/or modify it under the terms
14 * of the GNU General Public License as published by the Free Software Foundation,
15 * either version 3 of the License, or (at your option) any later version.
16 *
17 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
18 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
19 * PURPOSE. See the GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along with
22 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
23 **/
HYuana9b85752014-02-26 02:32:30 -060024
25#include "table/name-tree.hpp"
Junxiao Shid9ee45c2014-02-27 15:38:11 -070026#include "tests/test-common.hpp"
HYuana9b85752014-02-26 02:32:30 -060027
28namespace nfd {
Junxiao Shid9ee45c2014-02-27 15:38:11 -070029namespace tests {
HYuana9b85752014-02-26 02:32:30 -060030
31using name_tree::Entry;
32
Junxiao Shid9ee45c2014-02-27 15:38:11 -070033BOOST_FIXTURE_TEST_SUITE(TableNameTree, BaseFixture)
HYuana9b85752014-02-26 02:32:30 -060034
Haowei Yuanf52dac72014-03-24 23:35:03 -050035BOOST_AUTO_TEST_CASE(Hash)
36{
37 Name root("/");
38 root.wireEncode();
39 size_t hashValue = name_tree::computeHash(root);
40 BOOST_CHECK_EQUAL(hashValue, static_cast<size_t>(0));
41
42 Name prefix("/nohello/world/ndn/research");
43 prefix.wireEncode();
44 std::vector<size_t> hashSet = name_tree::computeHashSet(prefix);
45 BOOST_CHECK_EQUAL(hashSet.size(), prefix.size() + 1);
46}
47
Junxiao Shid9ee45c2014-02-27 15:38:11 -070048BOOST_AUTO_TEST_CASE(Entry)
HYuana9b85752014-02-26 02:32:30 -060049{
50 Name prefix("ndn:/named-data/research/abc/def/ghi");
51
Junxiao Shiefceadc2014-03-09 18:52:57 -070052 shared_ptr<name_tree::Entry> npe = make_shared<name_tree::Entry>(prefix);
53 BOOST_CHECK_EQUAL(npe->getPrefix(), prefix);
HYuana9b85752014-02-26 02:32:30 -060054
55 // examine all the get methods
56
Haowei Yuanf52dac72014-03-24 23:35:03 -050057 size_t hash = npe->getHash();
58 BOOST_CHECK_EQUAL(hash, static_cast<size_t>(0));
HYuana9b85752014-02-26 02:32:30 -060059
Junxiao Shiefceadc2014-03-09 18:52:57 -070060 shared_ptr<name_tree::Entry> parent = npe->getParent();
HYuana9b85752014-02-26 02:32:30 -060061 BOOST_CHECK(!static_cast<bool>(parent));
62
Junxiao Shiefceadc2014-03-09 18:52:57 -070063 std::vector<shared_ptr<name_tree::Entry> >& childList = npe->getChildren();
Haowei Yuanf52dac72014-03-24 23:35:03 -050064 BOOST_CHECK_EQUAL(childList.size(), static_cast<size_t>(0));
HYuana9b85752014-02-26 02:32:30 -060065
Junxiao Shiefceadc2014-03-09 18:52:57 -070066 shared_ptr<fib::Entry> fib = npe->getFibEntry();
HYuana9b85752014-02-26 02:32:30 -060067 BOOST_CHECK(!static_cast<bool>(fib));
68
Junxiao Shi9f7455b2014-04-07 21:02:16 -070069 const std::vector< shared_ptr<pit::Entry> >& pitList = npe->getPitEntries();
Haowei Yuanf52dac72014-03-24 23:35:03 -050070 BOOST_CHECK_EQUAL(pitList.size(), static_cast<size_t>(0));
HYuana9b85752014-02-26 02:32:30 -060071
Haowei Yuane1079fc2014-03-08 14:41:25 -060072 // examine all the set method
HYuana9b85752014-02-26 02:32:30 -060073
Haowei Yuanf52dac72014-03-24 23:35:03 -050074 npe->setHash(static_cast<size_t>(12345));
75 BOOST_CHECK_EQUAL(npe->getHash(), static_cast<size_t>(12345));
HYuana9b85752014-02-26 02:32:30 -060076
77 Name parentName("ndn:/named-data/research/abc/def");
78 parent = make_shared<name_tree::Entry>(parentName);
Junxiao Shiefceadc2014-03-09 18:52:57 -070079 npe->setParent(parent);
80 BOOST_CHECK_EQUAL(npe->getParent(), parent);
HYuana9b85752014-02-26 02:32:30 -060081
Haowei Yuane1079fc2014-03-08 14:41:25 -060082 // Insert FIB
HYuana9b85752014-02-26 02:32:30 -060083
84 shared_ptr<fib::Entry> fibEntry(new fib::Entry(prefix));
85 shared_ptr<fib::Entry> fibEntryParent(new fib::Entry(parentName));
Haowei Yuane1079fc2014-03-08 14:41:25 -060086
Junxiao Shiefceadc2014-03-09 18:52:57 -070087 npe->setFibEntry(fibEntry);
88 BOOST_CHECK_EQUAL(npe->getFibEntry(), fibEntry);
HYuana9b85752014-02-26 02:32:30 -060089
Junxiao Shiefceadc2014-03-09 18:52:57 -070090 npe->setFibEntry(shared_ptr<fib::Entry>());
91 BOOST_CHECK(!static_cast<bool>(npe->getFibEntry()));
HYuana9b85752014-02-26 02:32:30 -060092
93 // Insert a PIT
94
95 shared_ptr<pit::Entry> PitEntry(make_shared<pit::Entry>(prefix));
Haowei Yuane1079fc2014-03-08 14:41:25 -060096 shared_ptr<pit::Entry> PitEntry2(make_shared<pit::Entry>(parentName));
HYuana9b85752014-02-26 02:32:30 -060097
Junxiao Shiefceadc2014-03-09 18:52:57 -070098 npe->insertPitEntry(PitEntry);
99 BOOST_CHECK_EQUAL(npe->getPitEntries().size(), 1);
HYuana9b85752014-02-26 02:32:30 -0600100
Junxiao Shiefceadc2014-03-09 18:52:57 -0700101 npe->insertPitEntry(PitEntry2);
102 BOOST_CHECK_EQUAL(npe->getPitEntries().size(), 2);
HYuana9b85752014-02-26 02:32:30 -0600103
Junxiao Shi9f7455b2014-04-07 21:02:16 -0700104 npe->erasePitEntry(PitEntry);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700105 BOOST_CHECK_EQUAL(npe->getPitEntries().size(), 1);
HYuana9b85752014-02-26 02:32:30 -0600106
Junxiao Shi9f7455b2014-04-07 21:02:16 -0700107 npe->erasePitEntry(PitEntry2);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700108 BOOST_CHECK_EQUAL(npe->getPitEntries().size(), 0);
HYuana9b85752014-02-26 02:32:30 -0600109}
110
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700111BOOST_AUTO_TEST_CASE(NameTreeBasic)
HYuana9b85752014-02-26 02:32:30 -0600112{
113 size_t nBuckets = 16;
114 NameTree nt(nBuckets);
115
116 BOOST_CHECK_EQUAL(nt.size(), 0);
Haowei Yuane1079fc2014-03-08 14:41:25 -0600117 BOOST_CHECK_EQUAL(nt.getNBuckets(), nBuckets);
HYuana9b85752014-02-26 02:32:30 -0600118
Haowei Yuane1079fc2014-03-08 14:41:25 -0600119 Name nameABC("ndn:/a/b/c");
HYuana9b85752014-02-26 02:32:30 -0600120 shared_ptr<name_tree::Entry> npeABC = nt.lookup(nameABC);
121 BOOST_CHECK_EQUAL(nt.size(), 4);
Haowei Yuane1079fc2014-03-08 14:41:25 -0600122
123 Name nameABD("/a/b/d");
HYuana9b85752014-02-26 02:32:30 -0600124 shared_ptr<name_tree::Entry> npeABD = nt.lookup(nameABD);
125 BOOST_CHECK_EQUAL(nt.size(), 5);
126
Haowei Yuane1079fc2014-03-08 14:41:25 -0600127 Name nameAE("/a/e/");
HYuana9b85752014-02-26 02:32:30 -0600128 shared_ptr<name_tree::Entry> npeAE = nt.lookup(nameAE);
129 BOOST_CHECK_EQUAL(nt.size(), 6);
130
Haowei Yuane1079fc2014-03-08 14:41:25 -0600131 Name nameF("/f");
HYuana9b85752014-02-26 02:32:30 -0600132 shared_ptr<name_tree::Entry> npeF = nt.lookup(nameF);
133 BOOST_CHECK_EQUAL(nt.size(), 7);
134
Haowei Yuane1079fc2014-03-08 14:41:25 -0600135 // validate lookup() and findExactMatch()
HYuana9b85752014-02-26 02:32:30 -0600136
137 Name nameAB ("/a/b");
138 BOOST_CHECK_EQUAL(npeABC->getParent(), nt.findExactMatch(nameAB));
139 BOOST_CHECK_EQUAL(npeABD->getParent(), nt.findExactMatch(nameAB));
140
141 Name nameA ("/a");
142 BOOST_CHECK_EQUAL(npeAE->getParent(), nt.findExactMatch(nameA));
143
144 Name nameRoot ("/");
145 BOOST_CHECK_EQUAL(npeF->getParent(), nt.findExactMatch(nameRoot));
146 BOOST_CHECK_EQUAL(nt.size(), 7);
147
Haowei Yuane1079fc2014-03-08 14:41:25 -0600148 Name name0("/does/not/exist");
HYuana9b85752014-02-26 02:32:30 -0600149 shared_ptr<name_tree::Entry> npe0 = nt.findExactMatch(name0);
150 BOOST_CHECK(!static_cast<bool>(npe0));
151
152
153 // Longest Prefix Matching
HYuana9b85752014-02-26 02:32:30 -0600154 shared_ptr<name_tree::Entry> temp;
155 Name nameABCLPM("/a/b/c/def/asdf/nlf");
156 temp = nt.findLongestPrefixMatch(nameABCLPM);
157 BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameABC));
158
159 Name nameABDLPM("/a/b/d/def/asdf/nlf");
160 temp = nt.findLongestPrefixMatch(nameABDLPM);
161 BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameABD));
162
163 Name nameABLPM("/a/b/hello/world");
164 temp = nt.findLongestPrefixMatch(nameABLPM);
165 BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameAB));
166
167 Name nameAELPM("/a/e/hello/world");
168 temp = nt.findLongestPrefixMatch(nameAELPM);
169 BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameAE));
170
171 Name nameALPM("/a/hello/world");
172 temp = nt.findLongestPrefixMatch(nameALPM);
173 BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameA));
174
175 Name nameFLPM("/f/hello/world");
176 temp = nt.findLongestPrefixMatch(nameFLPM);
177 BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameF));
178
179 Name nameRootLPM("/does_not_exist");
180 temp = nt.findLongestPrefixMatch(nameRootLPM);
181 BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameRoot));
182
HYuana9b85752014-02-26 02:32:30 -0600183 bool eraseResult = false;
184 temp = nt.findExactMatch(nameABC);
185 if (static_cast<bool>(temp))
186 eraseResult = nt.
187 eraseEntryIfEmpty(temp);
188 BOOST_CHECK_EQUAL(nt.size(), 6);
189 BOOST_CHECK(!static_cast<bool>(nt.findExactMatch(nameABC)));
190 BOOST_CHECK_EQUAL(eraseResult, true);
191
192 eraseResult = false;
193 temp = nt.findExactMatch(nameABCLPM);
Haowei Yuane1079fc2014-03-08 14:41:25 -0600194 if (static_cast<bool>(temp))
HYuana9b85752014-02-26 02:32:30 -0600195 eraseResult = nt.
196 eraseEntryIfEmpty(temp);
197 BOOST_CHECK(!static_cast<bool>(temp));
198 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);
Haowei Yuane1079fc2014-03-08 14:41:25 -0600208 if (static_cast<bool>(temp))
HYuana9b85752014-02-26 02:32:30 -0600209 eraseResult = nt.
210 eraseEntryIfEmpty(temp);
211 BOOST_CHECK_EQUAL(nt.size(), 6);
212 BOOST_CHECK_EQUAL(eraseResult, true);
213 BOOST_CHECK(!static_cast<bool>(nt.findExactMatch(nameABC)));
214
HYuana9b85752014-02-26 02:32:30 -0600215 BOOST_CHECK_EQUAL(nt.getNBuckets(), 16);
216
Haowei Yuane1079fc2014-03-08 14:41:25 -0600217 // should resize now
HYuana9b85752014-02-26 02:32:30 -0600218 Name nameABCD("a/b/c/d");
219 nt.lookup(nameABCD);
220 Name nameABCDE("a/b/c/d/e");
221 nt.lookup(nameABCDE);
222 BOOST_CHECK_EQUAL(nt.size(), 9);
223 BOOST_CHECK_EQUAL(nt.getNBuckets(), 32);
224
Haowei Yuane1079fc2014-03-08 14:41:25 -0600225 // try to erase /a/b/c, should return false
HYuana9b85752014-02-26 02:32:30 -0600226 temp = nt.findExactMatch(nameABC);
227 BOOST_CHECK_EQUAL(temp->getPrefix(), nameABC);
228 eraseResult = nt.
229 eraseEntryIfEmpty(temp);
230 BOOST_CHECK_EQUAL(eraseResult, false);
231 temp = nt.findExactMatch(nameABC);
232 BOOST_CHECK_EQUAL(temp->getPrefix(), nameABC);
233
234 temp = nt.findExactMatch(nameABD);
Haowei Yuane1079fc2014-03-08 14:41:25 -0600235 if (static_cast<bool>(temp))
HYuana9b85752014-02-26 02:32:30 -0600236 nt.
237 eraseEntryIfEmpty(temp);
238 BOOST_CHECK_EQUAL(nt.size(), 8);
Haowei Yuane1079fc2014-03-08 14:41:25 -0600239}
HYuana9b85752014-02-26 02:32:30 -0600240
Haowei Yuane1079fc2014-03-08 14:41:25 -0600241BOOST_AUTO_TEST_CASE(NameTreeIteratorFullEnumerate)
242{
Haowei Yuane1079fc2014-03-08 14:41:25 -0600243 size_t nBuckets = 1024;
244 NameTree nt(nBuckets);
HYuana9b85752014-02-26 02:32:30 -0600245
Haowei Yuane1079fc2014-03-08 14:41:25 -0600246 BOOST_CHECK_EQUAL(nt.size(), 0);
247 BOOST_CHECK_EQUAL(nt.getNBuckets(), nBuckets);
248
249 Name nameABC("ndn:/a/b/c");
250 shared_ptr<name_tree::Entry> npeABC = nt.lookup(nameABC);
251 BOOST_CHECK_EQUAL(nt.size(), 4);
252
253 Name nameABD("/a/b/d");
254 shared_ptr<name_tree::Entry> npeABD = nt.lookup(nameABD);
255 BOOST_CHECK_EQUAL(nt.size(), 5);
256
257 Name nameAE("/a/e/");
258 shared_ptr<name_tree::Entry> npeAE = nt.lookup(nameAE);
259 BOOST_CHECK_EQUAL(nt.size(), 6);
260
261 Name nameF("/f");
262 shared_ptr<name_tree::Entry> npeF = nt.lookup(nameF);
263 BOOST_CHECK_EQUAL(nt.size(), 7);
264
265 Name nameRoot("/");
266 shared_ptr<name_tree::Entry> npeRoot = nt.lookup(nameRoot);
267 BOOST_CHECK_EQUAL(nt.size(), 7);
268
269 Name nameA("/a");
270 Name nameAB("/a/b");
271
272 bool hasRoot = false;
273 bool hasA = false;
274 bool hasAB = false;
275 bool hasABC = false;
276 bool hasABD = false;
277 bool hasAE = false;
278 bool hasF = false;
279
280 int counter = 0;
281 NameTree::const_iterator it = nt.fullEnumerate();
282
283 for(; it != nt.end(); it++)
284 {
285 counter++;
286
287 if (it->getPrefix() == nameRoot)
288 hasRoot = true;
289 if (it->getPrefix() == nameA)
290 hasA = true;
291 if (it->getPrefix() == nameAB)
292 hasAB = true;
293 if (it->getPrefix() == nameABC)
294 hasABC = true;
295 if (it->getPrefix() == nameABD)
296 hasABD = true;
297 if (it->getPrefix() == nameAE)
298 hasAE = true;
299 if (it->getPrefix() == nameF)
300 hasF = true;
301 }
302
303 BOOST_CHECK_EQUAL(hasRoot , true);
304 BOOST_CHECK_EQUAL(hasA , true);
305 BOOST_CHECK_EQUAL(hasAB , true);
306 BOOST_CHECK_EQUAL(hasABC , true);
307 BOOST_CHECK_EQUAL(hasABD , true);
308 BOOST_CHECK_EQUAL(hasAE , true);
309 BOOST_CHECK_EQUAL(hasF , true);
310
311 BOOST_CHECK_EQUAL(counter , 7);
312}
313
314// Predicates for testing the partial enumerate function
315
316static inline std::pair<bool, bool>
317predicate_NameTreeEntry_NameA_Only(const name_tree::Entry& entry)
318{
319 Name nameA("/a");
320 bool first = nameA.equals(entry.getPrefix());
321 return std::make_pair(first, true);
322}
323
324static inline std::pair<bool, bool>
325predicate_NameTreeEntry_Except_NameA(const name_tree::Entry& entry)
326{
327 Name nameA("/a");
328 bool first = !(nameA.equals(entry.getPrefix()));
329 return std::make_pair(first, true);
330}
331
332static inline std::pair<bool, bool>
333predicate_NameTreeEntry_NoSubNameA(const name_tree::Entry& entry)
334{
335 Name nameA("/a");
336 bool second = !(nameA.equals(entry.getPrefix()));
337 return std::make_pair(true, second);
338}
339
340static inline std::pair<bool, bool>
341predicate_NameTreeEntry_NoNameA_NoSubNameAB(const name_tree::Entry& entry)
342{
343 Name nameA("/a");
344 Name nameAB("/a/b");
345 bool first = !(nameA.equals(entry.getPrefix()));
346 bool second = !(nameAB.equals(entry.getPrefix()));
347 return std::make_pair(first, second);
348}
349
350static inline std::pair<bool, bool>
351predicate_NameTreeEntry_NoNameA_NoSubNameAC(const name_tree::Entry& entry)
352{
353 Name nameA("/a");
354 Name nameAC("/a/c");
355 bool first = !(nameA.equals(entry.getPrefix()));
356 bool second = !(nameAC.equals(entry.getPrefix()));
357 return std::make_pair(first, second);
358}
359
360static inline std::pair<bool, bool>
361predicate_NameTreeEntry_Example(const name_tree::Entry& entry)
362{
363 Name nameRoot("/");
364 Name nameA("/a");
365 Name nameAB("/a/b");
366 Name nameABC("/a/b/c");
367 Name nameAD("/a/d");
368 Name nameE("/e");
369 Name nameF("/f");
370
371 bool first = false;
372 bool second = false;
373
374 Name name = entry.getPrefix();
375
376 if (name == nameRoot || name == nameAB || name == nameABC || name == nameAD)
377 {
378 first = true;
379 }
380
381 if(name == nameRoot || name == nameA || name == nameF)
382 {
383 second = true;
384 }
385
386 return std::make_pair(first, second);
387}
388
389BOOST_AUTO_TEST_CASE(NameTreeIteratorPartialEnumerate)
390{
Haowei Yuane1079fc2014-03-08 14:41:25 -0600391 typedef NameTree::const_iterator const_iterator;
392
393 size_t nBuckets = 16;
394 NameTree nameTree(nBuckets);
395 int counter = 0;
396
397 // empty nameTree, should return end();
398 Name nameA("/a");
399 bool hasA = false;
400 const_iterator itA = nameTree.partialEnumerate(nameA);
401 BOOST_CHECK(itA == nameTree.end());
402
403 // We have "/", "/a", "/a/b", "a/c" now.
404 Name nameAB("/a/b");
405 bool hasAB = false;
406 nameTree.lookup(nameAB);
407
408 Name nameAC("/a/c");
409 bool hasAC = false;
410 nameTree.lookup(nameAC);
411 BOOST_CHECK_EQUAL(nameTree.size(), 4);
412
413 // Enumerate on some name that is not in nameTree
414 Name name0="/0";
415 const_iterator it0 = nameTree.partialEnumerate(name0);
416 BOOST_CHECK(it0 == nameTree.end());
417
418 // Accept "root" nameA only
419 const_iterator itAOnly = nameTree.partialEnumerate(nameA, &predicate_NameTreeEntry_NameA_Only);
420 BOOST_CHECK_EQUAL(itAOnly->getPrefix(), nameA);
421 BOOST_CHECK(++itAOnly == nameTree.end());
422
423 // Accept anything except "root" nameA
424 const_iterator itExceptA = nameTree.partialEnumerate(nameA, &predicate_NameTreeEntry_Except_NameA);
425 hasA = false;
426 hasAB = false;
427 hasAC = false;
428
429 counter = 0;
430 for (; itExceptA != nameTree.end(); itExceptA++)
431 {
432 counter++;
433
434 if (itExceptA->getPrefix() == nameA)
435 hasA = true;
436
437 if (itExceptA->getPrefix() == nameAB)
438 hasAB = true;
439
440 if (itExceptA->getPrefix() == nameAC)
441 hasAC = true;
442 }
443 BOOST_CHECK_EQUAL(hasA, false);
444 BOOST_CHECK_EQUAL(hasAB, true);
445 BOOST_CHECK_EQUAL(hasAC, true);
446
447 BOOST_CHECK_EQUAL(counter, 2);
448
449 Name nameAB1("a/b/1");
450 bool hasAB1 = false;
451 nameTree.lookup(nameAB1);
452
453 Name nameAB2("a/b/2");
454 bool hasAB2 = false;
455 nameTree.lookup(nameAB2);
456
457 Name nameAC1("a/c/1");
458 bool hasAC1 = false;
459 nameTree.lookup(nameAC1);
460
461 Name nameAC2("a/c/2");
462 bool hasAC2 = false;
463 nameTree.lookup(nameAC2);
464
465 BOOST_CHECK_EQUAL(nameTree.size(), 8);
466
467 // No NameA
468 // No SubTree from NameAB
469 const_iterator itNoNameANoSubNameAB = nameTree.partialEnumerate(nameA, &predicate_NameTreeEntry_NoNameA_NoSubNameAB);
470 hasA = false;
471 hasAB = false;
472 hasAB1 = false;
473 hasAB2 = false;
474 hasAC = false;
475 hasAC1 = false;
476 hasAC2 = false;
477
478 counter = 0;
479
480 for (; itNoNameANoSubNameAB != nameTree.end(); itNoNameANoSubNameAB++)
481 {
482 counter++;
483
484 if (itNoNameANoSubNameAB->getPrefix() == nameA)
485 hasA = true;
486
487 if (itNoNameANoSubNameAB->getPrefix() == nameAB)
488 hasAB = true;
489
490 if (itNoNameANoSubNameAB->getPrefix() == nameAB1)
491 hasAB1 = true;
492
493 if (itNoNameANoSubNameAB->getPrefix() == nameAB2)
494 hasAB2 = true;
495
496 if (itNoNameANoSubNameAB->getPrefix() == nameAC)
497 hasAC = true;
498
499 if (itNoNameANoSubNameAB->getPrefix() == nameAC1)
500 hasAC1 = true;
501
502 if (itNoNameANoSubNameAB->getPrefix() == nameAC2)
503 hasAC2 = true;
504 }
505
506 BOOST_CHECK_EQUAL(hasA, false);
507 BOOST_CHECK_EQUAL(hasAB, true);
508 BOOST_CHECK_EQUAL(hasAB1, false);
509 BOOST_CHECK_EQUAL(hasAB2, false);
510 BOOST_CHECK_EQUAL(hasAC, true);
511 BOOST_CHECK_EQUAL(hasAC1, true);
512 BOOST_CHECK_EQUAL(hasAC2, true);
513
514 BOOST_CHECK_EQUAL(counter, 4);
515
516 // No NameA
517 // No SubTree from NameAC
518 const_iterator itNoNameANoSubNameAC = nameTree.partialEnumerate(nameA, &predicate_NameTreeEntry_NoNameA_NoSubNameAC);
519 hasA = false;
520 hasAB = false;
521 hasAB1 = false;
522 hasAB2 = false;
523 hasAC = false;
524 hasAC1 = false;
525 hasAC2 = false;
526
527 counter = 0;
528
529 for (; itNoNameANoSubNameAC != nameTree.end(); itNoNameANoSubNameAC++)
530 {
531 counter++;
532
533 if (itNoNameANoSubNameAC->getPrefix() == nameA)
534 hasA = true;
535
536 if (itNoNameANoSubNameAC->getPrefix() == nameAB)
537 hasAB = true;
538
539 if (itNoNameANoSubNameAC->getPrefix() == nameAB1)
540 hasAB1 = true;
541
542 if (itNoNameANoSubNameAC->getPrefix() == nameAB2)
543 hasAB2 = true;
544
545 if (itNoNameANoSubNameAC->getPrefix() == nameAC)
546 hasAC = true;
547
548 if (itNoNameANoSubNameAC->getPrefix() == nameAC1)
549 hasAC1 = true;
550
551 if (itNoNameANoSubNameAC->getPrefix() == nameAC2)
552 hasAC2 = true;
553 }
554
555 BOOST_CHECK_EQUAL(hasA, false);
556 BOOST_CHECK_EQUAL(hasAB, true);
557 BOOST_CHECK_EQUAL(hasAB1, true);
558 BOOST_CHECK_EQUAL(hasAB2, true);
559 BOOST_CHECK_EQUAL(hasAC, true);
560 BOOST_CHECK_EQUAL(hasAC1, false);
561 BOOST_CHECK_EQUAL(hasAC2, false);
562
563 BOOST_CHECK_EQUAL(counter, 4);
564
565 // No Subtree from NameA
566 const_iterator itNoANoSubNameA = nameTree.partialEnumerate(nameA, &predicate_NameTreeEntry_NoSubNameA);
567
568 hasA = false;
569 hasAB = false;
570 hasAB1 = false;
571 hasAB2 = false;
572 hasAC = false;
573 hasAC1 = false;
574 hasAC2 = false;
575
576 counter = 0;
577
578 for (; itNoANoSubNameA != nameTree.end(); itNoANoSubNameA++)
579 {
580 counter++;
581
582 if (itNoANoSubNameA->getPrefix() == nameA)
583 hasA = true;
584
585 if (itNoANoSubNameA->getPrefix() == nameAB)
586 hasAB = true;
587
588 if (itNoANoSubNameA->getPrefix() == nameAB1)
589 hasAB1 = true;
590
591 if (itNoANoSubNameA->getPrefix() == nameAB2)
592 hasAB2 = true;
593
594 if (itNoANoSubNameA->getPrefix() == nameAC)
595 hasAC = true;
596
597 if (itNoANoSubNameA->getPrefix() == nameAC1)
598 hasAC1 = true;
599
600 if (itNoANoSubNameA->getPrefix() == nameAC2)
601 hasAC2 = true;
602 }
603
604 BOOST_CHECK_EQUAL(hasA, true);
605 BOOST_CHECK_EQUAL(hasAB, false);
606 BOOST_CHECK_EQUAL(hasAB1, false);
607 BOOST_CHECK_EQUAL(hasAB2, false);
608 BOOST_CHECK_EQUAL(hasAC, false);
609 BOOST_CHECK_EQUAL(hasAC1, false);
610 BOOST_CHECK_EQUAL(hasAC2, false);
611
612 BOOST_CHECK_EQUAL(counter, 1);
613
614 // Example
615 // /
616 // /A
617 // /A/B x
618 // /A/B/C
619 // /A/D x
620 // /E
621 // /F
622
623 NameTree nameTreeExample(nBuckets);
624
625 Name nameRoot("/");
626 bool hasRoot = false;
627
628 nameTreeExample.lookup(nameA);
629 hasA = false;
630 nameTreeExample.lookup(nameAB);
631 hasAB = false;
632
633 Name nameABC("a/b/c");
634 bool hasABC = false;
635 nameTreeExample.lookup(nameABC);
636
637 Name nameAD("/a/d");
638 nameTreeExample.lookup(nameAD);
639 bool hasAD = false;
640
641 Name nameE("/e");
642 nameTreeExample.lookup(nameE);
643 bool hasE = false;
644
645 Name nameF("/f");
646 nameTreeExample.lookup(nameF);
647 bool hasF = false;
648
649 counter = 0;
650 const_iterator itExample = nameTreeExample.partialEnumerate(nameA, &predicate_NameTreeEntry_Example);
651
652 for (; itExample != nameTreeExample.end(); itExample++)
653 {
654 counter++;
655
656 if (itExample->getPrefix() == nameRoot)
657 hasRoot = true;
658
659 if (itExample->getPrefix() == nameA)
660 hasA = true;
661
662 if (itExample->getPrefix() == nameAB)
663 hasAB = true;
664
665 if (itExample->getPrefix() == nameABC)
666 hasABC = true;
667
668 if (itExample->getPrefix() == nameAD)
669 hasAD = true;
670
671 if (itExample->getPrefix() == nameE)
672 hasE = true;
673
674 if (itExample->getPrefix() == nameF)
675 hasF = true;
676 }
677
678 BOOST_CHECK_EQUAL(hasRoot, false);
679 BOOST_CHECK_EQUAL(hasA, false);
680 BOOST_CHECK_EQUAL(hasAB, true);
681 BOOST_CHECK_EQUAL(hasABC, false);
682 BOOST_CHECK_EQUAL(hasAD, true);
683 BOOST_CHECK_EQUAL(hasE, false);
684 BOOST_CHECK_EQUAL(hasF, false);
685
686 BOOST_CHECK_EQUAL(counter, 2);
687}
688
689
690BOOST_AUTO_TEST_CASE(NameTreeIteratorFindAllMatches)
691{
Haowei Yuane1079fc2014-03-08 14:41:25 -0600692 size_t nBuckets = 16;
693 NameTree nt(nBuckets);
694 int counter = 0;
695
696 Name nameABCDEF("a/b/c/d/e/f");
697 shared_ptr<name_tree::Entry> npeABCDEF = nt.lookup(nameABCDEF);
698
699 Name nameAAC("a/a/c");
700 shared_ptr<name_tree::Entry> npeAAC = nt.lookup(nameAAC);
701
702 Name nameAAD1("a/a/d/1");
703 shared_ptr<name_tree::Entry> npeAAD1 = nt.lookup(nameAAD1);
704
705 Name nameAAD2("a/a/d/2");
706 shared_ptr<name_tree::Entry> npeAAD2 = nt.lookup(nameAAD2);
707
708
709 BOOST_CHECK_EQUAL(nt.size(), 12);
710
711 Name nameRoot ("/");
712 Name nameA ("/a");
713 Name nameAB ("/a/b");
714 Name nameABC ("/a/b/c");
715 Name nameABCD ("/a/b/c/d");
716 Name nameABCDE("/a/b/c/d/e");
717 Name nameAA ("/a/a");
718 Name nameAAD ("/a/a/d");
719
720 bool hasRoot = false;
721 bool hasA = false;
722 bool hasAB = false;
723 bool hasABC = false;
724 bool hasABCD = false;
725 bool hasABCDE = false;
726 bool hasABCDEF = false;
727 bool hasAA = false;
728 bool hasAAC = false;
729 bool hasAAD = false;
730 bool hasAAD1 = false;
731 bool hasAAD2 = false;
732
733 counter = 0;
734
735 for (NameTree::const_iterator it = nt.findAllMatches(nameABCDEF);
736 it != nt.end(); it++)
737 {
738 counter++;
739
740 if (it->getPrefix() == nameRoot)
741 hasRoot = true;
742 if (it->getPrefix() == nameA)
743 hasA = true;
744 if (it->getPrefix() == nameAB)
745 hasAB = true;
746 if (it->getPrefix() == nameABC)
747 hasABC = true;
748 if (it->getPrefix() == nameABCD)
749 hasABCD = true;
750 if (it->getPrefix() == nameABCDE)
751 hasABCDE = true;
752 if (it->getPrefix() == nameABCDEF)
753 hasABCDEF = true;
754 if (it->getPrefix() == nameAA)
755 hasAA = true;
756 if (it->getPrefix() == nameAAC)
757 hasAAC = true;
758 if (it->getPrefix() == nameAAD)
759 hasAAD = true;
760 if (it->getPrefix() == nameAAD1)
761 hasAAD1 = true;
762 if (it->getPrefix() == nameAAD2)
763 hasAAD2 = true;
764 }
765
766 BOOST_CHECK_EQUAL(hasRoot , true);
767 BOOST_CHECK_EQUAL(hasA , true);
768 BOOST_CHECK_EQUAL(hasAB , true);
769 BOOST_CHECK_EQUAL(hasABC , true);
770 BOOST_CHECK_EQUAL(hasABCD , true);
771 BOOST_CHECK_EQUAL(hasABCDE , true);
772 BOOST_CHECK_EQUAL(hasABCDEF , true);
773 BOOST_CHECK_EQUAL(hasAA , false);
774 BOOST_CHECK_EQUAL(hasAAC , false);
775 BOOST_CHECK_EQUAL(hasAAD , false);
776 BOOST_CHECK_EQUAL(hasAAD1 , false);
777 BOOST_CHECK_EQUAL(hasAAD2 , false);
778
779 BOOST_CHECK_EQUAL(counter, 7);
HYuana9b85752014-02-26 02:32:30 -0600780}
781
Haowei Yuanf52dac72014-03-24 23:35:03 -0500782BOOST_AUTO_TEST_CASE(NameTreeHashTableResizeShrink)
783{
784 size_t nBuckets = 16;
785 NameTree nameTree(nBuckets);
786
787 Name prefix("/a/b/c/d/e/f/g/h"); // requires 9 buckets
788
789 shared_ptr<name_tree::Entry> entry = nameTree.lookup(prefix);
790 BOOST_CHECK_EQUAL(nameTree.size(), 9);
791 BOOST_CHECK_EQUAL(nameTree.getNBuckets(), 32);
792
793 nameTree.eraseEntryIfEmpty(entry);
794 BOOST_CHECK_EQUAL(nameTree.size(), 0);
795 BOOST_CHECK_EQUAL(nameTree.getNBuckets(), 16);
796}
797
HYuana9b85752014-02-26 02:32:30 -0600798BOOST_AUTO_TEST_SUITE_END()
799
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700800} // namespace tests
HYuana9b85752014-02-26 02:32:30 -0600801} // namespace nfd