rbtree_unittest.cc 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868
  1. // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <gtest/gtest.h>
  15. #include <exceptions/exceptions.h>
  16. #include <util/memory_segment_local.h>
  17. #include <dns/name.h>
  18. #include <dns/rrclass.h>
  19. #include <dns/rrset.h>
  20. #include <dns/rrtype.h>
  21. #include <dns/rrttl.h>
  22. #include <datasrc/rbtree.h>
  23. #include <dns/tests/unittest_util.h>
  24. using namespace std;
  25. using namespace isc;
  26. using namespace isc::dns;
  27. using isc::UnitTestUtil;
  28. using namespace isc::datasrc;
  29. // XXX: some compilers cannot find class static constants used in
  30. // EXPECT_xxx macros, for which we need an explicit empty definition.
  31. const size_t Name::MAX_LABELS;
  32. /* The initial structure of rbtree
  33. *
  34. * b
  35. * / \
  36. * a d.e.f
  37. * / | \
  38. * c | g.h
  39. * | |
  40. * w.y i
  41. * / | \ \
  42. * x | z k
  43. * | |
  44. * p j
  45. * / \
  46. * o q
  47. */
  48. namespace {
  49. class TreeHolder {
  50. public:
  51. TreeHolder(util::MemorySegment& mem_sgmt, RBTree<int>* tree) :
  52. mem_sgmt_(mem_sgmt), tree_(tree)
  53. {}
  54. ~TreeHolder() {
  55. RBTree<int>::destroy(mem_sgmt_, tree_);
  56. }
  57. RBTree<int>* get() { return (tree_); }
  58. private:
  59. util::MemorySegment& mem_sgmt_;
  60. RBTree<int>* tree_;
  61. };
  62. class RBTreeTest : public::testing::Test {
  63. protected:
  64. RBTreeTest() :
  65. rbtree_holder_(mem_sgmt_, RBTree<int>::create(mem_sgmt_)),
  66. rbtree_expose_empty_node_holder_(mem_sgmt_,
  67. RBTree<int>::create(mem_sgmt_, true)),
  68. rbtree(*rbtree_holder_.get()),
  69. rbtree_expose_empty_node(*rbtree_expose_empty_node_holder_.get()),
  70. crbtnode(NULL)
  71. {
  72. const char* const domain_names[] = {
  73. "c", "b", "a", "x.d.e.f", "z.d.e.f", "g.h", "i.g.h", "o.w.y.d.e.f",
  74. "j.z.d.e.f", "p.w.y.d.e.f", "q.w.y.d.e.f", "k.g.h"};
  75. int name_count = sizeof(domain_names) / sizeof(domain_names[0]);
  76. for (int i = 0; i < name_count; ++i) {
  77. rbtree.insert(mem_sgmt_, Name(domain_names[i]), &rbtnode);
  78. rbtnode->setData(RBNode<int>::NodeDataPtr(new int(i + 1)));
  79. rbtree_expose_empty_node.insert(mem_sgmt_, Name(domain_names[i]),
  80. &rbtnode);
  81. rbtnode->setData(RBNode<int>::NodeDataPtr(new int(i + 1)));
  82. }
  83. }
  84. util::MemorySegmentLocal mem_sgmt_;
  85. TreeHolder rbtree_holder_;
  86. TreeHolder rbtree_expose_empty_node_holder_;
  87. RBTree<int>& rbtree;
  88. RBTree<int>& rbtree_expose_empty_node;
  89. RBNode<int>* rbtnode;
  90. const RBNode<int>* crbtnode;
  91. };
  92. TEST_F(RBTreeTest, nodeCount) {
  93. EXPECT_EQ(14, rbtree.getNodeCount());
  94. // Delete all nodes, then the count should be set to 0. This also tests
  95. // the behavior of deleteAllNodes().
  96. rbtree.deleteAllNodes(mem_sgmt_);
  97. EXPECT_EQ(0, rbtree.getNodeCount());
  98. }
  99. TEST_F(RBTreeTest, setGetData) {
  100. rbtnode->setData(RBNode<int>::NodeDataPtr(new int(11)));
  101. EXPECT_EQ(11, *(rbtnode->getData()));
  102. }
  103. TEST_F(RBTreeTest, insertNames) {
  104. EXPECT_EQ(RBTree<int>::ALREADYEXISTS, rbtree.insert(mem_sgmt_,
  105. Name("d.e.f"),
  106. &rbtnode));
  107. EXPECT_EQ(Name("d.e.f"), rbtnode->getName());
  108. EXPECT_EQ(14, rbtree.getNodeCount());
  109. //insert not exist node
  110. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("."),
  111. &rbtnode));
  112. EXPECT_EQ(Name("."), rbtnode->getName());
  113. EXPECT_EQ(15, rbtree.getNodeCount());
  114. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_,
  115. Name("example.com"),
  116. &rbtnode));
  117. EXPECT_EQ(16, rbtree.getNodeCount());
  118. rbtnode->setData(RBNode<int>::NodeDataPtr(new int(12)));
  119. // return ALREADYEXISTS, since node "example.com" already has been explicitly inserted
  120. EXPECT_EQ(RBTree<int>::ALREADYEXISTS, rbtree.insert(mem_sgmt_,
  121. Name("example.com"),
  122. &rbtnode));
  123. EXPECT_EQ(16, rbtree.getNodeCount());
  124. // split the node "d.e.f"
  125. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("k.e.f"),
  126. &rbtnode));
  127. EXPECT_EQ(Name("k"), rbtnode->getName());
  128. EXPECT_EQ(18, rbtree.getNodeCount());
  129. // split the node "g.h"
  130. EXPECT_EQ(RBTree<int>::ALREADYEXISTS, rbtree.insert(mem_sgmt_, Name("h"),
  131. &rbtnode));
  132. EXPECT_EQ(Name("h"), rbtnode->getName());
  133. EXPECT_EQ(19, rbtree.getNodeCount());
  134. // add child domain
  135. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_,
  136. Name("m.p.w.y.d.e.f"),
  137. &rbtnode));
  138. EXPECT_EQ(Name("m"), rbtnode->getName());
  139. EXPECT_EQ(20, rbtree.getNodeCount());
  140. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_,
  141. Name("n.p.w.y.d.e.f"),
  142. &rbtnode));
  143. EXPECT_EQ(Name("n"), rbtnode->getName());
  144. EXPECT_EQ(21, rbtree.getNodeCount());
  145. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("l.a"),
  146. &rbtnode));
  147. EXPECT_EQ(Name("l"), rbtnode->getName());
  148. EXPECT_EQ(22, rbtree.getNodeCount());
  149. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("r.d.e.f"),
  150. &rbtnode));
  151. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("s.d.e.f"),
  152. &rbtnode));
  153. EXPECT_EQ(24, rbtree.getNodeCount());
  154. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_,
  155. Name("h.w.y.d.e.f"),
  156. &rbtnode));
  157. // add more nodes one by one to cover leftRotate and rightRotate
  158. EXPECT_EQ(RBTree<int>::ALREADYEXISTS, rbtree.insert(mem_sgmt_, Name("f"),
  159. &rbtnode));
  160. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("m"),
  161. &rbtnode));
  162. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("nm"),
  163. &rbtnode));
  164. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("om"),
  165. &rbtnode));
  166. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("k"),
  167. &rbtnode));
  168. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("l"),
  169. &rbtnode));
  170. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("fe"),
  171. &rbtnode));
  172. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("ge"),
  173. &rbtnode));
  174. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("i"),
  175. &rbtnode));
  176. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("ae"),
  177. &rbtnode));
  178. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("n"),
  179. &rbtnode));
  180. }
  181. TEST_F(RBTreeTest, findName) {
  182. // find const rbtnode
  183. // exact match
  184. EXPECT_EQ(RBTree<int>::EXACTMATCH, rbtree.find(Name("a"), &crbtnode));
  185. EXPECT_EQ(Name("a"), crbtnode->getName());
  186. // not found
  187. EXPECT_EQ(RBTree<int>::NOTFOUND, rbtree.find(Name("d.e.f"), &crbtnode));
  188. EXPECT_EQ(RBTree<int>::NOTFOUND, rbtree.find(Name("y.d.e.f"), &crbtnode));
  189. EXPECT_EQ(RBTree<int>::NOTFOUND, rbtree.find(Name("x"), &crbtnode));
  190. EXPECT_EQ(RBTree<int>::NOTFOUND, rbtree.find(Name("m.n"), &crbtnode));
  191. // if we expose empty node, we can get the empty node created during insert
  192. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  193. rbtree_expose_empty_node.find(Name("d.e.f"), &crbtnode));
  194. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  195. rbtree_expose_empty_node.find(Name("w.y.d.e.f"), &crbtnode));
  196. // partial match
  197. EXPECT_EQ(RBTree<int>::PARTIALMATCH, rbtree.find(Name("m.b"), &crbtnode));
  198. EXPECT_EQ(Name("b"), crbtnode->getName());
  199. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  200. rbtree_expose_empty_node.find(Name("m.d.e.f"), &crbtnode));
  201. // find rbtnode
  202. EXPECT_EQ(RBTree<int>::EXACTMATCH, rbtree.find(Name("q.w.y.d.e.f"), &rbtnode));
  203. EXPECT_EQ(Name("q"), rbtnode->getName());
  204. }
  205. TEST_F(RBTreeTest, findError) {
  206. // For the version that takes a node chain, the chain must be empty.
  207. RBTreeNodeChain<int> chain;
  208. EXPECT_EQ(RBTree<int>::EXACTMATCH, rbtree.find(Name("a"), &crbtnode,
  209. chain));
  210. // trying to reuse the same chain. it should result in an exception.
  211. EXPECT_THROW(rbtree.find(Name("a"), &crbtnode, chain),
  212. BadValue);
  213. }
  214. TEST_F(RBTreeTest, flags) {
  215. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_,
  216. Name("flags.example"),
  217. &rbtnode));
  218. // by default, flags are all off
  219. EXPECT_FALSE(rbtnode->getFlag(RBNode<int>::FLAG_CALLBACK));
  220. // set operation, by default it enables the flag
  221. rbtnode->setFlag(RBNode<int>::FLAG_CALLBACK);
  222. EXPECT_TRUE(rbtnode->getFlag(RBNode<int>::FLAG_CALLBACK));
  223. // try disable the flag explicitly
  224. rbtnode->setFlag(RBNode<int>::FLAG_CALLBACK, false);
  225. EXPECT_FALSE(rbtnode->getFlag(RBNode<int>::FLAG_CALLBACK));
  226. // try enable the flag explicitly
  227. rbtnode->setFlag(RBNode<int>::FLAG_CALLBACK, true);
  228. EXPECT_TRUE(rbtnode->getFlag(RBNode<int>::FLAG_CALLBACK));
  229. // setting an unknown flag will trigger an exception
  230. EXPECT_THROW(rbtnode->setFlag(static_cast<RBNode<int>::Flags>(2), true),
  231. isc::InvalidParameter);
  232. }
  233. bool
  234. testCallback(const RBNode<int>&, bool* callack_checker) {
  235. *callack_checker = true;
  236. return (false);
  237. }
  238. TEST_F(RBTreeTest, callback) {
  239. // by default callback isn't enabled
  240. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_,
  241. Name("callback.example"),
  242. &rbtnode));
  243. rbtnode->setData(RBNode<int>::NodeDataPtr(new int(1)));
  244. EXPECT_FALSE(rbtnode->getFlag(RBNode<int>::FLAG_CALLBACK));
  245. // enable/re-disable callback
  246. rbtnode->setFlag(RBNode<int>::FLAG_CALLBACK);
  247. EXPECT_TRUE(rbtnode->getFlag(RBNode<int>::FLAG_CALLBACK));
  248. rbtnode->setFlag(RBNode<int>::FLAG_CALLBACK, false);
  249. EXPECT_FALSE(rbtnode->getFlag(RBNode<int>::FLAG_CALLBACK));
  250. // enable again for subsequent tests
  251. rbtnode->setFlag(RBNode<int>::FLAG_CALLBACK);
  252. // add more levels below and above the callback node for partial match.
  253. RBNode<int>* subrbtnode;
  254. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_,
  255. Name("sub.callback.example"),
  256. &subrbtnode));
  257. subrbtnode->setData(RBNode<int>::NodeDataPtr(new int(2)));
  258. RBNode<int>* parentrbtnode;
  259. EXPECT_EQ(RBTree<int>::ALREADYEXISTS, rbtree.insert(mem_sgmt_,
  260. Name("example"),
  261. &parentrbtnode));
  262. // the chilld/parent nodes shouldn't "inherit" the callback flag.
  263. // "rbtnode" may be invalid due to the insertion, so we need to re-find
  264. // it.
  265. EXPECT_EQ(RBTree<int>::EXACTMATCH, rbtree.find(Name("callback.example"),
  266. &rbtnode));
  267. EXPECT_TRUE(rbtnode->getFlag(RBNode<int>::FLAG_CALLBACK));
  268. EXPECT_FALSE(subrbtnode->getFlag(RBNode<int>::FLAG_CALLBACK));
  269. EXPECT_FALSE(parentrbtnode->getFlag(RBNode<int>::FLAG_CALLBACK));
  270. // check if the callback is called from find()
  271. RBTreeNodeChain<int> node_path1;
  272. bool callback_called = false;
  273. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  274. rbtree.find(Name("sub.callback.example"), &crbtnode, node_path1,
  275. testCallback, &callback_called));
  276. EXPECT_TRUE(callback_called);
  277. // enable callback at the parent node, but it doesn't have data so
  278. // the callback shouldn't be called.
  279. RBTreeNodeChain<int> node_path2;
  280. parentrbtnode->setFlag(RBNode<int>::FLAG_CALLBACK);
  281. callback_called = false;
  282. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  283. rbtree.find(Name("callback.example"), &crbtnode, node_path2,
  284. testCallback, &callback_called));
  285. EXPECT_FALSE(callback_called);
  286. }
  287. TEST_F(RBTreeTest, chainLevel) {
  288. RBTreeNodeChain<int> chain;
  289. // by default there should be no level in the chain.
  290. EXPECT_EQ(0, chain.getLevelCount());
  291. // insert one node to the tree and find it. there should be exactly
  292. // one level in the chain.
  293. TreeHolder tree_holder(mem_sgmt_, RBTree<int>::create(mem_sgmt_, true));
  294. RBTree<int>& tree(*tree_holder.get());
  295. Name node_name(Name::ROOT_NAME());
  296. EXPECT_EQ(RBTree<int>::SUCCESS, tree.insert(mem_sgmt_, node_name,
  297. &rbtnode));
  298. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  299. tree.find(node_name, &crbtnode, chain));
  300. EXPECT_EQ(1, chain.getLevelCount());
  301. /*
  302. * Now creating a possibly deepest tree with MAX_LABELS levels.
  303. * it should look like:
  304. * (.)
  305. * |
  306. * a
  307. * |
  308. * a
  309. * : (MAX_LABELS - 1) "a"'s
  310. *
  311. * then confirm that find() for the deepest name succeeds without any
  312. * disruption, and the resulting chain has the expected level.
  313. * Note that the root name (".") solely belongs to a single level,
  314. * so the levels begin with 2.
  315. */
  316. for (unsigned int i = 2; i <= Name::MAX_LABELS; ++i) {
  317. node_name = Name("a.").concatenate(node_name);
  318. EXPECT_EQ(RBTree<int>::SUCCESS, tree.insert(mem_sgmt_, node_name,
  319. &rbtnode));
  320. RBTreeNodeChain<int> found_chain;
  321. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  322. tree.find(node_name, &crbtnode, found_chain));
  323. EXPECT_EQ(i, found_chain.getLevelCount());
  324. }
  325. // Confirm the last inserted name has the possible maximum length with
  326. // maximum label count. This confirms the rbtree and chain level cannot
  327. // be larger.
  328. EXPECT_EQ(Name::MAX_LABELS, node_name.getLabelCount());
  329. EXPECT_THROW(node_name.concatenate(Name("a.")), TooLongName);
  330. }
  331. TEST_F(RBTreeTest, getAbsoluteNameError) {
  332. // an empty chain isn't allowed.
  333. RBTreeNodeChain<int> chain;
  334. EXPECT_THROW(chain.getAbsoluteName(), BadValue);
  335. }
  336. /*
  337. *the domain order should be:
  338. * a, b, c, d.e.f, x.d.e.f, w.y.d.e.f, o.w.y.d.e.f, p.w.y.d.e.f, q.w.y.d.e.f,
  339. * z.d.e.f, j.z.d.e.f, g.h, i.g.h, k.g.h
  340. * b
  341. * / \
  342. * a d.e.f
  343. * / | \
  344. * c | g.h
  345. * | |
  346. * w.y i
  347. * / | \ \
  348. * x | z k
  349. * | |
  350. * p j
  351. * / \
  352. * o q
  353. */
  354. const char* const names[] = {
  355. "a", "b", "c", "d.e.f", "x.d.e.f", "w.y.d.e.f", "o.w.y.d.e.f",
  356. "p.w.y.d.e.f", "q.w.y.d.e.f", "z.d.e.f", "j.z.d.e.f",
  357. "g.h", "i.g.h", "k.g.h"};
  358. const size_t name_count(sizeof(names) / sizeof(*names));
  359. TEST_F(RBTreeTest, nextNode) {
  360. RBTreeNodeChain<int> node_path;
  361. const RBNode<int>* node = NULL;
  362. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  363. rbtree.find(Name(names[0]), &node, node_path));
  364. for (int i = 0; i < name_count; ++i) {
  365. EXPECT_NE(static_cast<void*>(NULL), node);
  366. EXPECT_EQ(Name(names[i]), node_path.getAbsoluteName());
  367. node = rbtree.nextNode(node_path);
  368. }
  369. // We should have reached the end of the tree.
  370. EXPECT_EQ(static_cast<void*>(NULL), node);
  371. }
  372. // Just walk using previousNode until the beginning of the tree and check it is
  373. // OK
  374. //
  375. // rbtree - the tree to walk
  376. // node - result of previous call to find(), starting position of the walk
  377. // node_path - the path from the previous call to find(), will be modified
  378. // chain_length - the number of names that should be in the chain to be walked
  379. // (0 means it should be empty, 3 means 'a', 'b' and 'c' should be there -
  380. // this is always from the beginning of the names[] list).
  381. // skip_first - if this is false, the node should already contain the node with
  382. // the first name of the chain. If it is true, the node should be NULL
  383. // (true is for finds that return no match, false for the ones that return
  384. // match)
  385. void
  386. previousWalk(RBTree<int>& rbtree, const RBNode<int>* node,
  387. RBTreeNodeChain<int>& node_path, size_t chain_length,
  388. bool skip_first)
  389. {
  390. if (skip_first) {
  391. // If the first is not found, this is supposed to be NULL and we skip
  392. // it in our checks.
  393. EXPECT_EQ(static_cast<void*>(NULL), node);
  394. node = rbtree.previousNode(node_path);
  395. }
  396. for (size_t i(chain_length); i > 0; --i) {
  397. EXPECT_NE(static_cast<void*>(NULL), node);
  398. EXPECT_EQ(Name(names[i - 1]), node_path.getAbsoluteName());
  399. // Find the node at the path and check the value is the same
  400. // (that it really returns the correct corresponding node)
  401. //
  402. // The "empty" nodes can not be found
  403. if (node->getData()) {
  404. const RBNode<int>* node2(NULL);
  405. RBTreeNodeChain<int> node_path2;
  406. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  407. rbtree.find(Name(names[i - 1]), &node2, node_path2));
  408. EXPECT_EQ(node, node2);
  409. }
  410. node = rbtree.previousNode(node_path);
  411. }
  412. // We should have reached the start of the tree.
  413. EXPECT_EQ(static_cast<void*>(NULL), node);
  414. // Calling previousNode() yet again should still return NULL without
  415. // fail.
  416. node = rbtree.previousNode(node_path);
  417. EXPECT_EQ(static_cast<void*>(NULL), node);
  418. }
  419. // Check the previousNode
  420. TEST_F(RBTreeTest, previousNode) {
  421. // First, iterate the whole tree from the end to the beginning.
  422. RBTreeNodeChain<int> node_path;
  423. EXPECT_THROW(rbtree.previousNode(node_path), isc::BadValue) <<
  424. "Throw before a search was done on the path";
  425. const RBNode<int>* node(NULL);
  426. {
  427. SCOPED_TRACE("Iterate through");
  428. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  429. rbtree.find(Name(names[name_count - 1]), &node, node_path));
  430. previousWalk(rbtree, node, node_path, name_count, false);
  431. node = NULL;
  432. node_path.clear();
  433. }
  434. {
  435. SCOPED_TRACE("Iterate from the middle");
  436. // Now, start somewhere in the middle, but within the real node.
  437. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  438. rbtree.find(Name(names[4]), &node, node_path));
  439. previousWalk(rbtree, node, node_path, 5, false);
  440. node = NULL;
  441. node_path.clear();
  442. }
  443. {
  444. SCOPED_TRACE("Start at the first");
  445. // If we start at the lowest (which is "a"), we get to the beginning
  446. // right away.
  447. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  448. rbtree.find(Name(names[0]), &node, node_path));
  449. EXPECT_NE(static_cast<void*>(NULL), node);
  450. EXPECT_EQ(static_cast<void*>(NULL), rbtree.previousNode(node_path));
  451. node = NULL;
  452. node_path.clear();
  453. }
  454. {
  455. SCOPED_TRACE("Start before the first");
  456. // If we start before the lowest (0 < a), we should not get a node nor
  457. EXPECT_EQ(RBTree<int>::NOTFOUND,
  458. rbtree.find<void*>(Name("0"), &node, node_path, NULL, NULL));
  459. EXPECT_EQ(static_cast<void*>(NULL), node);
  460. EXPECT_EQ(static_cast<void*>(NULL), rbtree.previousNode(node_path));
  461. node = NULL;
  462. node_path.clear();
  463. }
  464. {
  465. SCOPED_TRACE("Start after the last");
  466. EXPECT_EQ(RBTree<int>::NOTFOUND,
  467. rbtree.find(Name("z"), &node, node_path));
  468. previousWalk(rbtree, node, node_path, name_count, true);
  469. node = NULL;
  470. node_path.clear();
  471. }
  472. {
  473. SCOPED_TRACE("Start below a leaf");
  474. // We exit a leaf by going down. We should start by the one
  475. // we exited - 'c' (actually, we should get it by the find, as partial
  476. // match).
  477. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  478. rbtree.find(Name("b.c"), &node, node_path));
  479. previousWalk(rbtree, node, node_path, 3, false);
  480. node = NULL;
  481. node_path.clear();
  482. }
  483. {
  484. SCOPED_TRACE("Start to the right of a leaf");
  485. // When searching for this, we exit the 'x' node to the right side,
  486. // so we should go x afterwards.
  487. // The d.e.f is empty node, so it is hidden by find. Therefore NOTFOUND
  488. // and not PARTIALMATCH.
  489. EXPECT_EQ(RBTree<int>::NOTFOUND,
  490. rbtree.find(Name("xy.d.e.f"), &node, node_path));
  491. previousWalk(rbtree, node, node_path, 5, true);
  492. node = NULL;
  493. node_path.clear();
  494. }
  495. {
  496. SCOPED_TRACE("Start to the left of a leaf");
  497. // This is similar to the previous, but we exit the 'z' leaf to the
  498. // left side, so should not visit z at all then.
  499. // The d.e.f is empty node, so it is hidden by find. Therefore NOTFOUND
  500. // and not PARTIALMATCH.
  501. EXPECT_EQ(RBTree<int>::NOTFOUND,
  502. rbtree.find(Name("yz.d.e.f"), &node, node_path));
  503. previousWalk(rbtree, node, node_path, 9, true);
  504. node = NULL;
  505. node_path.clear();
  506. }
  507. {
  508. SCOPED_TRACE("Start to the right of a parent");
  509. // When searching for this, we exit the 'g.h' node to the right
  510. // side, so we should go to g.h's children afterwards.
  511. // 'g.h' is an empty node, so we get a NOTFOUND and not
  512. // PARTIALMATCH.
  513. EXPECT_EQ(RBTree<int>::NOTFOUND,
  514. rbtree.find(Name("x.h"), &node, node_path));
  515. // 'g.h' is the COMMONANCESTOR.
  516. EXPECT_EQ(node_path.getLastComparedNode()->getName(), Name("g.h"));
  517. EXPECT_EQ(NameComparisonResult::COMMONANCESTOR,
  518. node_path.getLastComparisonResult().getRelation());
  519. // find() exits to the right of 'g.h'
  520. EXPECT_GT(node_path.getLastComparisonResult().getOrder(), 0);
  521. // We then descend into 'i.g.h' and walk all the nodes in the
  522. // tree.
  523. previousWalk(rbtree, node, node_path, name_count, true);
  524. node = NULL;
  525. node_path.clear();
  526. }
  527. {
  528. SCOPED_TRACE("Start inside a wrong node");
  529. // The d.e.f is a single node, but we want only part of it. We
  530. // should start iterating before it.
  531. EXPECT_EQ(RBTree<int>::NOTFOUND,
  532. rbtree.find(Name("e.f"), &node, node_path));
  533. previousWalk(rbtree, node, node_path, 3, true);
  534. node = NULL;
  535. node_path.clear();
  536. }
  537. {
  538. SCOPED_TRACE("Lookup in empty tree");
  539. // Just check it doesn't crash, etc.
  540. TreeHolder tree_holder(mem_sgmt_, RBTree<int>::create(mem_sgmt_));
  541. RBTree<int>& empty_tree(*tree_holder.get());
  542. EXPECT_EQ(RBTree<int>::NOTFOUND,
  543. empty_tree.find(Name("x"), &node, node_path));
  544. EXPECT_EQ(static_cast<void*>(NULL), node);
  545. EXPECT_EQ(static_cast<void*>(NULL),
  546. empty_tree.previousNode(node_path));
  547. node = NULL;
  548. node_path.clear();
  549. }
  550. }
  551. TEST_F(RBTreeTest, nextNodeError) {
  552. // Empty chain for nextNode() is invalid.
  553. RBTreeNodeChain<int> chain;
  554. EXPECT_THROW(rbtree.nextNode(chain), BadValue);
  555. }
  556. // A helper function for getLastComparedNode() below.
  557. void
  558. comparisonChecks(const RBTreeNodeChain<int>& chain,
  559. int expected_order, int expected_common_labels,
  560. NameComparisonResult::NameRelation expected_reln)
  561. {
  562. if (expected_order > 0) {
  563. EXPECT_LT(0, chain.getLastComparisonResult().getOrder());
  564. } else if (expected_order < 0) {
  565. EXPECT_GT(0, chain.getLastComparisonResult().getOrder());
  566. } else {
  567. EXPECT_EQ(0, chain.getLastComparisonResult().getOrder());
  568. }
  569. EXPECT_EQ(expected_common_labels,
  570. chain.getLastComparisonResult().getCommonLabels());
  571. EXPECT_EQ(expected_reln,
  572. chain.getLastComparisonResult().getRelation());
  573. }
  574. TEST_F(RBTreeTest, getLastComparedNode) {
  575. RBTree<int>& tree = rbtree_expose_empty_node; // use the "empty OK" mode
  576. RBTreeNodeChain<int> chain;
  577. // initially there should be no 'last compared'.
  578. EXPECT_EQ(static_cast<void*>(NULL), chain.getLastComparedNode());
  579. // A search for an empty tree should result in no 'last compared', too.
  580. TreeHolder tree_holder(mem_sgmt_, RBTree<int>::create(mem_sgmt_));
  581. RBTree<int>& empty_tree(*tree_holder.get());
  582. EXPECT_EQ(RBTree<int>::NOTFOUND,
  583. empty_tree.find(Name("a"), &crbtnode, chain));
  584. EXPECT_EQ(static_cast<void*>(NULL), chain.getLastComparedNode());
  585. chain.clear();
  586. const RBNode<int>* expected_node = NULL;
  587. // Exact match case. The returned node should be last compared.
  588. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  589. tree.find(Name("x.d.e.f"), &expected_node, chain));
  590. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  591. // 2 = # labels of "x."
  592. comparisonChecks(chain, 0, 2, NameComparisonResult::EQUAL);
  593. chain.clear();
  594. // Partial match, search stopped at the matching node, which should be
  595. // the last compared node.
  596. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  597. tree.find(Name("k.g.h"), &expected_node));
  598. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  599. tree.find(Name("x.k.g.h"), &crbtnode, chain));
  600. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  601. // k.g.h < x.k.g.h, 2 = # labels of "k."
  602. comparisonChecks(chain, 1, 2, NameComparisonResult::SUBDOMAIN);
  603. chain.clear();
  604. // Partial match, search stopped in the subtree below the matching node
  605. // after following a left branch.
  606. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  607. tree.find(Name("x.d.e.f"), &expected_node));
  608. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  609. tree.find(Name("a.d.e.f"), &crbtnode, chain));
  610. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  611. // a < x, 1 = # labels of "." (trailing dot)
  612. comparisonChecks(chain, -1, 1, NameComparisonResult::COMMONANCESTOR);
  613. chain.clear();
  614. // Partial match, search stopped in the subtree below the matching node
  615. // after following a right branch.
  616. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  617. tree.find(Name("z.d.e.f"), &expected_node));
  618. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  619. tree.find(Name("zz.d.e.f"), &crbtnode, chain));
  620. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  621. // zz > z, 1 = # labels of "." (trailing dot)
  622. comparisonChecks(chain, 1, 1, NameComparisonResult::COMMONANCESTOR);
  623. chain.clear();
  624. // Partial match, search stopped at a node for a super domain of the
  625. // search name in the subtree below the matching node.
  626. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  627. tree.find(Name("w.y.d.e.f"), &expected_node));
  628. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  629. tree.find(Name("y.d.e.f"), &crbtnode, chain));
  630. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  631. // y < w.y, 2 = # labels of "y."
  632. comparisonChecks(chain, -1, 2, NameComparisonResult::SUPERDOMAIN);
  633. chain.clear();
  634. // Partial match, search stopped at a node that share a common ancestor
  635. // with the search name in the subtree below the matching node.
  636. // (the expected node is the same as the previous case)
  637. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  638. tree.find(Name("z.y.d.e.f"), &crbtnode, chain));
  639. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  640. // z.y > w.y, 2 = # labels of "y."
  641. comparisonChecks(chain, 1, 2, NameComparisonResult::COMMONANCESTOR);
  642. chain.clear();
  643. // Search stops in the highest level after following a left branch.
  644. EXPECT_EQ(RBTree<int>::EXACTMATCH, tree.find(Name("c"), &expected_node));
  645. EXPECT_EQ(RBTree<int>::NOTFOUND,
  646. tree.find(Name("bb"), &crbtnode, chain));
  647. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  648. // bb < c, 1 = # labels of "." (trailing dot)
  649. comparisonChecks(chain, -1, 1, NameComparisonResult::COMMONANCESTOR);
  650. chain.clear();
  651. // Search stops in the highest level after following a right branch.
  652. // (the expected node is the same as the previous case)
  653. EXPECT_EQ(RBTree<int>::NOTFOUND,
  654. tree.find(Name("d"), &crbtnode, chain));
  655. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  656. // d > c, 1 = # labels of "." (trailing dot)
  657. comparisonChecks(chain, 1, 1, NameComparisonResult::COMMONANCESTOR);
  658. chain.clear();
  659. }
  660. TEST_F(RBTreeTest, dumpTree) {
  661. std::ostringstream str;
  662. std::ostringstream str2;
  663. rbtree.dumpTree(str);
  664. str2 << "tree has 14 node(s)\n"
  665. "b. (black) [subtreeroot]\n"
  666. " a. (black)\n"
  667. " NULL\n"
  668. " NULL\n"
  669. " d.e.f. (black) [invisible]\n"
  670. " begin down from d.e.f.\n"
  671. " w.y. (black) [invisible] [subtreeroot]\n"
  672. " begin down from w.y.\n"
  673. " p. (black) [subtreeroot]\n"
  674. " o. (red)\n"
  675. " NULL\n"
  676. " NULL\n"
  677. " q. (red)\n"
  678. " NULL\n"
  679. " NULL\n"
  680. " end down from w.y.\n"
  681. " x. (red)\n"
  682. " NULL\n"
  683. " NULL\n"
  684. " z. (red)\n"
  685. " begin down from z.\n"
  686. " j. (black) [subtreeroot]\n"
  687. " NULL\n"
  688. " NULL\n"
  689. " end down from z.\n"
  690. " NULL\n"
  691. " NULL\n"
  692. " end down from d.e.f.\n"
  693. " c. (red)\n"
  694. " NULL\n"
  695. " NULL\n"
  696. " g.h. (red)\n"
  697. " begin down from g.h.\n"
  698. " i. (black) [subtreeroot]\n"
  699. " NULL\n"
  700. " k. (red)\n"
  701. " NULL\n"
  702. " NULL\n"
  703. " end down from g.h.\n"
  704. " NULL\n"
  705. " NULL\n";
  706. EXPECT_EQ(str2.str(), str.str());
  707. }
  708. TEST_F(RBTreeTest, swap) {
  709. // Store info about the first tree
  710. std::ostringstream str1;
  711. rbtree.dumpTree(str1);
  712. size_t count1(rbtree.getNodeCount());
  713. // Create second one and store state
  714. TreeHolder tree_holder(mem_sgmt_, RBTree<int>::create(mem_sgmt_));
  715. RBTree<int>& tree2(*tree_holder.get());
  716. RBNode<int>* node;
  717. tree2.insert(mem_sgmt_, Name("second"), &node);
  718. std::ostringstream str2;
  719. tree2.dumpTree(str2);
  720. // Swap them
  721. ASSERT_NO_THROW(tree2.swap(rbtree));
  722. // Check their sizes
  723. ASSERT_EQ(1, rbtree.getNodeCount());
  724. ASSERT_EQ(count1, tree2.getNodeCount());
  725. // And content
  726. std::ostringstream out;
  727. rbtree.dumpTree(out);
  728. ASSERT_EQ(str2.str(), out.str());
  729. out.str("");
  730. tree2.dumpTree(out);
  731. ASSERT_EQ(str1.str(), out.str());
  732. }
  733. // Matching in the "root zone" may be special (e.g. there's no parent,
  734. // any domain names should be considered a subdomain of it), so it makes
  735. // sense to test cases with the root zone explicitly.
  736. TEST_F(RBTreeTest, root) {
  737. TreeHolder tree_holder(mem_sgmt_, RBTree<int>::create(mem_sgmt_));
  738. RBTree<int>& root(*tree_holder.get());
  739. root.insert(mem_sgmt_, Name::ROOT_NAME(), &rbtnode);
  740. rbtnode->setData(RBNode<int>::NodeDataPtr(new int(1)));
  741. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  742. root.find(Name::ROOT_NAME(), &crbtnode));
  743. EXPECT_EQ(rbtnode, crbtnode);
  744. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  745. root.find(Name("example.com"), &crbtnode));
  746. EXPECT_EQ(rbtnode, crbtnode);
  747. // Insert a new name that better matches the query name. find() should
  748. // find the better one.
  749. root.insert(mem_sgmt_, Name("com"), &rbtnode);
  750. rbtnode->setData(RBNode<int>::NodeDataPtr(new int(2)));
  751. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  752. root.find(Name("example.com"), &crbtnode));
  753. EXPECT_EQ(rbtnode, crbtnode);
  754. // Perform the same tests for the tree that allows matching against empty
  755. // nodes.
  756. TreeHolder tree_holder_emptyok(mem_sgmt_,
  757. RBTree<int>::create(mem_sgmt_, true));
  758. RBTree<int>& root_emptyok(*tree_holder_emptyok.get());
  759. root_emptyok.insert(mem_sgmt_, Name::ROOT_NAME(), &rbtnode);
  760. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  761. root_emptyok.find(Name::ROOT_NAME(), &crbtnode));
  762. EXPECT_EQ(rbtnode, crbtnode);
  763. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  764. root_emptyok.find(Name("example.com"), &crbtnode));
  765. EXPECT_EQ(rbtnode, crbtnode);
  766. root.insert(mem_sgmt_, Name("com"), &rbtnode);
  767. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  768. root.find(Name("example.com"), &crbtnode));
  769. EXPECT_EQ(rbtnode, crbtnode);
  770. }
  771. }