table: enforce NameTree max depth universally
refs #4262
Change-Id: Ia9b04a89c12cd09aa244201b513cc1808c0c473f
diff --git a/daemon/table/fib.hpp b/daemon/table/fib.hpp
index ac864e8..4b94c21 100644
--- a/daemon/table/fib.hpp
+++ b/daemon/table/fib.hpp
@@ -85,19 +85,15 @@
public: // mutation
/** \brief Maximum number of components in a FIB entry prefix.
- *
- * This constant is currently advisory, but will become mandatory later.
*/
static constexpr size_t
getMaxDepth()
{
- static_assert(FIB_MAX_DEPTH == NameTree::getMaxDepth(), "");
return FIB_MAX_DEPTH;
}
- /** \brief inserts a FIB entry for prefix
- *
- * If an entry for exact same prefix exists, that entry is returned.
+ /** \brief find or insert a FIB entry
+ * \param prefix FIB entry name; it must have no more than \c getMaxDepth() components.
* \return the entry, and true for new entry or false for existing entry
*/
std::pair<Entry*, bool>
diff --git a/daemon/table/measurements.cpp b/daemon/table/measurements.cpp
index 2ed0f65..4d84746 100644
--- a/daemon/table/measurements.cpp
+++ b/daemon/table/measurements.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2017, Regents of the University of California,
+ * Copyright (c) 2014-2018, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -40,8 +40,6 @@
Entry&
Measurements::get(name_tree::Entry& nte)
{
- BOOST_ASSERT(nte.getName().size() <= NameTree::getMaxDepth());
-
Entry* entry = nte.getMeasurementsEntry();
if (entry != nullptr) {
return *entry;
@@ -61,21 +59,21 @@
Entry&
Measurements::get(const Name& name)
{
- name_tree::Entry& nte = m_nameTree.lookup(name, true);
+ name_tree::Entry& nte = m_nameTree.lookup(name, std::min(name.size(), getMaxDepth()));
return this->get(nte);
}
Entry&
Measurements::get(const fib::Entry& fibEntry)
{
- name_tree::Entry& nte = m_nameTree.lookup(fibEntry.getPrefix(), true);
+ name_tree::Entry& nte = m_nameTree.lookup(fibEntry);
return this->get(nte);
}
Entry&
Measurements::get(const pit::Entry& pitEntry)
{
- name_tree::Entry& nte = m_nameTree.lookup(pitEntry.getName(), true);
+ name_tree::Entry& nte = m_nameTree.lookup(pitEntry);
return this->get(nte);
}
diff --git a/daemon/table/measurements.hpp b/daemon/table/measurements.hpp
index 80c938a..d110ed6 100644
--- a/daemon/table/measurements.hpp
+++ b/daemon/table/measurements.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016, Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -45,7 +45,7 @@
*/
typedef std::function<bool(const Entry&)> EntryPredicate;
-/** \brief an \p EntryPredicate that accepts any entry
+/** \brief an \c EntryPredicate that accepts any entry
*/
class AnyEntry
{
@@ -57,7 +57,7 @@
}
};
-/** \brief an \p EntryPredicate that accepts an entry if it has StrategyInfo of type T
+/** \brief an \c EntryPredicate that accepts an entry if it has StrategyInfo of type T
*/
template<typename T>
class EntryWithStrategyInfo
@@ -70,31 +70,48 @@
}
};
-/** \brief represents the Measurements table
+/** \brief the Measurements table
+ *
+ * The Measurements table is a data structure for forwarding strategies to store per name prefix
+ * measurements. A strategy can access this table via \c Strategy::getMeasurements(), and then
+ * place any object that derive from \c StrategyInfo type onto Measurements entries.
*/
class Measurements : noncopyable
{
public:
explicit
- Measurements(NameTree& nametree);
+ Measurements(NameTree& nameTree);
- /** \brief find or insert a Measurements entry for \p name
+ /** \brief maximum depth of a Measurements entry
+ */
+ static constexpr size_t
+ getMaxDepth()
+ {
+ return NameTree::getMaxDepth();
+ }
+
+ /** \brief find or insert an entry by name
+ *
+ * An entry name can have at most \c getMaxDepth() components. If \p name exceeds this limit,
+ * it is truncated to the first \c getMaxDepth() components.
*/
Entry&
get(const Name& name);
- /** \brief find or insert a Measurements entry for \p fibEntry.getPrefix()
+ /** \brief equivalent to `get(fibEntry.getPrefix())`
*/
Entry&
get(const fib::Entry& fibEntry);
- /** \brief find or insert a Measurements entry for \p pitEntry.getName()
+ /** \brief equivalent to
+ * `get(pitEntry.getName(), std::min(pitEntry.getName().size(), getMaxDepth()))`
*/
Entry&
get(const pit::Entry& pitEntry);
- /** \brief find or insert a Measurements entry for child's parent
- * \retval nullptr if child is the root entry
+ /** \brief find or insert a parent entry
+ * \retval nullptr child is the root entry
+ * \return get(child.getName().getPrefix(-1))
*/
Entry*
getParent(const Entry& child);
@@ -105,7 +122,7 @@
findLongestPrefixMatch(const Name& name,
const EntryPredicate& pred = AnyEntry()) const;
- /** \brief perform a longest prefix match for \p pitEntry.getName()
+ /** \brief perform a longest prefix match for `pitEntry.getName()`
*/
Entry*
findLongestPrefixMatch(const pit::Entry& pitEntry,
@@ -136,7 +153,7 @@
Entry&
get(name_tree::Entry& nte);
- /** \tparam K a parameter acceptable to NameTree::findLongestPrefixMatch
+ /** \tparam K a parameter acceptable to \c NameTree::findLongestPrefixMatch
*/
template<typename K>
Entry*
diff --git a/daemon/table/name-tree-entry.cpp b/daemon/table/name-tree-entry.cpp
index 8d33a89..889d84f 100644
--- a/daemon/table/name-tree-entry.cpp
+++ b/daemon/table/name-tree-entry.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016, Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -24,6 +24,7 @@
*/
#include "name-tree-entry.hpp"
+#include "name-tree.hpp"
namespace nfd {
namespace name_tree {
@@ -34,6 +35,7 @@
, m_parent(nullptr)
{
BOOST_ASSERT(node != nullptr);
+ BOOST_ASSERT(name.size() <= NameTree::getMaxDepth());
}
void
diff --git a/daemon/table/name-tree.cpp b/daemon/table/name-tree.cpp
index 1fa54af..02553cb 100644
--- a/daemon/table/name-tree.cpp
+++ b/daemon/table/name-tree.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2017, Regents of the University of California,
+ * Copyright (c) 2014-2018, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -41,18 +41,19 @@
}
Entry&
-NameTree::lookup(const Name& name, bool enforceMaxDepth)
+NameTree::lookup(const Name& name, size_t prefixLen)
{
- NFD_LOG_TRACE("lookup " << name);
- size_t depth = enforceMaxDepth ? std::min(name.size(), getMaxDepth()) : name.size();
+ NFD_LOG_TRACE("lookup(" << name << ", " << prefixLen << ')');
+ BOOST_ASSERT(prefixLen <= name.size());
+ BOOST_ASSERT(prefixLen <= getMaxDepth());
- HashSequence hashes = computeHashes(name, depth);
+ HashSequence hashes = computeHashes(name, prefixLen);
const Node* node = nullptr;
Entry* parent = nullptr;
- for (size_t prefixLen = 0; prefixLen <= depth; ++prefixLen) {
+ for (size_t i = 0; i <= prefixLen; ++i) {
bool isNew = false;
- std::tie(node, isNew) = m_ht.insert(name, prefixLen, hashes);
+ std::tie(node, isNew) = m_ht.insert(name, i, hashes);
if (isNew && parent != nullptr) {
node->entry.setParent(*parent);
@@ -65,6 +66,7 @@
Entry&
NameTree::lookup(const fib::Entry& fibEntry)
{
+ NFD_LOG_TRACE("lookup(FIB " << fibEntry.getPrefix() << ')');
Entry* nte = this->getEntry(fibEntry);
if (nte == nullptr) {
// special case: Fib::s_emptyEntry is unattached
@@ -79,28 +81,26 @@
Entry&
NameTree::lookup(const pit::Entry& pitEntry)
{
+ const Name& name = pitEntry.getName();
+ NFD_LOG_TRACE("lookup(PIT " << name << ')');
+ bool hasDigest = name.size() > 0 && name[-1].isImplicitSha256Digest();
+ if (hasDigest && name.size() <= getMaxDepth()) {
+ return this->lookup(name);
+ }
+
Entry* nte = this->getEntry(pitEntry);
BOOST_ASSERT(nte != nullptr);
-
BOOST_ASSERT(std::count_if(nte->getPitEntries().begin(), nte->getPitEntries().end(),
[&pitEntry] (const shared_ptr<pit::Entry>& pitEntry1) {
return pitEntry1.get() == &pitEntry;
}) == 1);
-
- if (nte->getName().size() == pitEntry.getName().size()) {
- return *nte;
- }
-
- // special case: PIT entry whose Interest name ends with an implicit digest
- // are attached to the name tree entry with one-shorter-prefix.
- BOOST_ASSERT(pitEntry.getName().at(-1).isImplicitSha256Digest());
- BOOST_ASSERT(nte->getName() == pitEntry.getName().getPrefix(-1));
- return this->lookup(pitEntry.getName());
+ return *nte;
}
Entry&
NameTree::lookup(const measurements::Entry& measurementsEntry)
{
+ NFD_LOG_TRACE("lookup(M " << measurementsEntry.getName() << ')');
Entry* nte = this->getEntry(measurementsEntry);
BOOST_ASSERT(nte != nullptr);
@@ -111,6 +111,7 @@
Entry&
NameTree::lookup(const strategy_choice::Entry& strategyChoiceEntry)
{
+ NFD_LOG_TRACE("lookup(SC " << strategyChoiceEntry.getPrefix() << ')');
Entry* nte = this->getEntry(strategyChoiceEntry);
BOOST_ASSERT(nte != nullptr);
@@ -148,17 +149,23 @@
Entry*
NameTree::findExactMatch(const Name& name, size_t prefixLen) const
{
- const Node* node = m_ht.find(name, std::min(name.size(), prefixLen));
+ prefixLen = std::min(name.size(), prefixLen);
+ if (prefixLen > getMaxDepth()) {
+ return nullptr;
+ }
+
+ const Node* node = m_ht.find(name, prefixLen);
return node == nullptr ? nullptr : &node->entry;
}
Entry*
NameTree::findLongestPrefixMatch(const Name& name, const EntrySelector& entrySelector) const
{
- HashSequence hashes = computeHashes(name);
+ size_t depth = std::min(name.size(), getMaxDepth());
+ HashSequence hashes = computeHashes(name, depth);
- for (ssize_t prefixLen = name.size(); prefixLen >= 0; --prefixLen) {
- const Node* node = m_ht.find(name, prefixLen, hashes);
+ for (ssize_t i = depth; i >= 0; --i) {
+ const Node* node = m_ht.find(name, i, hashes);
if (node != nullptr && entrySelector(node->entry)) {
return &node->entry;
}
@@ -186,10 +193,12 @@
const Entry* nte = this->getEntry(pitEntry);
BOOST_ASSERT(nte != nullptr);
- // PIT entry Interest name either exceeds depth limit or ends with an implicit digest: go deeper
+ const Name& name = pitEntry.getName();
+ size_t depth = std::min(name.size(), getMaxDepth());
if (nte->getName().size() < pitEntry.getName().size()) {
- for (size_t prefixLen = nte->getName().size() + 1; prefixLen <= pitEntry.getName().size(); ++prefixLen) {
- const Entry* exact = this->findExactMatch(pitEntry.getName(), prefixLen);
+ // PIT entry name either exceeds depth limit or ends with an implicit digest: go deeper
+ for (size_t i = nte->getName().size() + 1; i <= depth; ++i) {
+ const Entry* exact = this->findExactMatch(name, i);
if (exact == nullptr) {
break;
}
diff --git a/daemon/table/name-tree.hpp b/daemon/table/name-tree.hpp
index 805be56..4ecca80 100644
--- a/daemon/table/name-tree.hpp
+++ b/daemon/table/name-tree.hpp
@@ -28,6 +28,8 @@
#include "name-tree-iterator.hpp"
+#include "core/fib-max-depth.hpp"
+
namespace nfd {
namespace name_tree {
@@ -40,20 +42,17 @@
NameTree(size_t nBuckets = 1024);
public: // information
- /** \brief Maximum depth of the name tree.
+ /** \brief maximum depth of the name tree
*
- * Calling NameTree::lookup with a name with many components would cause the creation of many
+ * Calling \c NameTree::lookup with a name with many components would cause the creation of many
* NameTree entries, which could take very long time. This constant limits the maximum number of
* name components in the name of a NameTree entry. Thus, it limits the number of NameTree
* entries created from a long name, bounding the processing complexity.
- *
- * This constant is currently advisory. It is enforced in NameTree::lookup only if
- * \p enforceMaxDepth is set to true. This will become mandatory later.
*/
static constexpr size_t
getMaxDepth()
{
- return 32;
+ return FIB_MAX_DEPTH;
}
/** \return number of name tree entries
@@ -83,40 +82,51 @@
}
public: // mutation
- /** \brief find or insert an entry with specified name
- * \param name a name prefix
- * \param enforceMaxDepth if true, use \p name.getPrefix(getMaxDepth()) in place of \p name
- * \return an entry with \p name
- * \post an entry with \p name and all ancestors are created
- * \note Existing iterators are unaffected.
+ /** \brief find or insert an entry by name
+ *
+ * This method seeks a name tree entry of name \c name.getPrefix(prefixLen).
+ * If the entry does not exist, it is created along with all ancestors.
+ * Existing iterators are unaffected during this operation.
+ *
+ * \warning \p prefixLen must not exceed \c name.size().
+ * \warning \p prefixLen must not exceed \c getMaxDepth().
*/
Entry&
- lookup(const Name& name, bool enforceMaxDepth = false);
+ lookup(const Name& name, size_t prefixLen);
- /** \brief equivalent to .lookup(fibEntry.getPrefix())
- * \param fibEntry a FIB entry attached to this name tree, or Fib::s_emptyEntry
- * \note This overload is more efficient than .lookup(const Name&) in common cases.
+ /** \brief equivalent to `lookup(name, name.size())`
+ */
+ Entry&
+ lookup(const Name& name)
+ {
+ return this->lookup(name, name.size());
+ }
+
+ /** \brief equivalent to `lookup(fibEntry.getPrefix())`
+ * \param fibEntry a FIB entry attached to this name tree, or \c Fib::s_emptyEntry
+ * \note This overload is more efficient than `lookup(const Name&)` in common cases.
*/
Entry&
lookup(const fib::Entry& fibEntry);
- /** \brief equivalent to .lookup(pitEntry.getName()).
+ /** \brief equivalent to
+ * `lookup(pitEntry.getName(), std::min(pitEntry.getName().size(), getMaxDepth()))`
* \param pitEntry a PIT entry attached to this name tree
- * \note This overload is more efficient than .lookup(const Name&) in common cases.
+ * \note This overload is more efficient than `lookup(const Name&)` in common cases.
*/
Entry&
lookup(const pit::Entry& pitEntry);
- /** \brief equivalent to .lookup(measurementsEntry.getName())
+ /** \brief equivalent to `lookup(measurementsEntry.getName())`
* \param measurementsEntry a Measurements entry attached to this name tree
- * \note This overload is more efficient than .lookup(const Name&) in common cases.
+ * \note This overload is more efficient than `lookup(const Name&)` in common cases.
*/
Entry&
lookup(const measurements::Entry& measurementsEntry);
- /** \brief equivalent to .lookup(strategyChoiceEntry.getPrefix())
+ /** \brief equivalent to `lookup(strategyChoiceEntry.getPrefix())`
* \param strategyChoiceEntry a StrategyChoice entry attached to this name tree
- * \note This overload is more efficient than .lookup(const Name&) in common cases.
+ * \note This overload is more efficient than `lookup(const Name&)` in common cases.
*/
Entry&
lookup(const strategy_choice::Entry& strategyChoiceEntry);
@@ -126,7 +136,7 @@
* \param canEraseAncestors whether ancestors should be deleted if they become empty
* \return number of deleted entries
* \sa Entry::isEmpty()
- * \post If the entry is empty, it's deleted. If canEraseAncestors is true,
+ * \post If the entry is empty, it's deleted. If \p canEraseAncestors is true,
* ancestors of the entry are also deleted if they become empty.
* \note This function must be called after detaching a table entry from a name tree entry,
* \note Existing iterators, except those pointing to deleted entries, are unaffected.
@@ -136,7 +146,7 @@
public: // matching
/** \brief exact match lookup
- * \return entry with \p name.getPrefix(prefixLen), or nullptr if it does not exist
+ * \return entry with \c name.getPrefix(prefixLen), or nullptr if it does not exist
*/
Entry*
findExactMatch(const Name& name, size_t prefixLen = std::numeric_limits<size_t>::max()) const;
@@ -150,19 +160,19 @@
findLongestPrefixMatch(const Name& name,
const EntrySelector& entrySelector = AnyEntry()) const;
- /** \brief equivalent to .findLongestPrefixMatch(entry.getName(), entrySelector)
+ /** \brief equivalent to `findLongestPrefixMatch(entry.getName(), entrySelector)`
* \note This overload is more efficient than
- * .findLongestPrefixMatch(const Name&, const EntrySelector&) in common cases.
+ * `findLongestPrefixMatch(const Name&, const EntrySelector&)` in common cases.
*/
Entry*
findLongestPrefixMatch(const Entry& entry,
const EntrySelector& entrySelector = AnyEntry()) const;
- /** \brief equivalent to .findLongestPrefixMatch(getEntry(tableEntry)->getName(), entrySelector)
- * \tparam EntryT fib::Entry or measurements::Entry or strategy_choice::Entry
+ /** \brief equivalent to `findLongestPrefixMatch(getEntry(tableEntry)->getName(), entrySelector)`
+ * \tparam EntryT \c fib::Entry or \c measurements::Entry or \c strategy_choice::Entry
* \note This overload is more efficient than
- * .findLongestPrefixMatch(const Name&, const EntrySelector&) in common cases.
- * \warning Undefined behavior may occur if tableEntry is not attached to this name tree.
+ * `findLongestPrefixMatch(const Name&, const EntrySelector&)` in common cases.
+ * \warning Undefined behavior may occur if \p tableEntry is not attached to this name tree.
*/
template<typename EntryT>
Entry*
@@ -174,10 +184,10 @@
return this->findLongestPrefixMatch(*nte, entrySelector);
}
- /** \brief equivalent to .findLongestPrefixMatch(pitEntry.getName(), entrySelector)
+ /** \brief equivalent to `findLongestPrefixMatch(pitEntry.getName(), entrySelector)`
* \note This overload is more efficient than
- * .findLongestPrefixMatch(const Name&, const EntrySelector&) in common cases.
- * \warning Undefined behavior may occur if pitEntry is not attached to this name tree.
+ * `findLongestPrefixMatch(const Name&, const EntrySelector&)` in common cases.
+ * \warning Undefined behavior may occur if \p pitEntry is not attached to this name tree.
*/
Entry*
findLongestPrefixMatch(const pit::Entry& pitEntry,
diff --git a/daemon/table/pit.cpp b/daemon/table/pit.cpp
index 2050417..7a708da 100644
--- a/daemon/table/pit.cpp
+++ b/daemon/table/pit.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2017, Regents of the University of California,
+ * Copyright (c) 2014-2018, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -45,29 +45,28 @@
{
// determine which NameTree entry should the PIT entry be attached onto
const Name& name = interest.getName();
- bool isEndWithDigest = name.size() > 0 && name[-1].isImplicitSha256Digest();
- const Name& nteName = isEndWithDigest ? name.getPrefix(-1) : name;
+ bool hasDigest = name.size() > 0 && name[-1].isImplicitSha256Digest();
+ size_t nteDepth = name.size() - static_cast<int>(hasDigest);
+ nteDepth = std::min(nteDepth, NameTree::getMaxDepth());
// ensure NameTree entry exists
name_tree::Entry* nte = nullptr;
if (allowInsert) {
- nte = &m_nameTree.lookup(nteName, true);
+ nte = &m_nameTree.lookup(name, nteDepth);
}
else {
- nte = m_nameTree.findExactMatch(nteName);
+ nte = m_nameTree.findExactMatch(name, nteDepth);
if (nte == nullptr) {
return {nullptr, true};
}
}
// check if PIT entry already exists
- size_t nteNameLen = nte->getName().size();
- const std::vector<shared_ptr<Entry>>& pitEntries = nte->getPitEntries();
+ const auto& pitEntries = nte->getPitEntries();
auto it = std::find_if(pitEntries.begin(), pitEntries.end(),
- [&interest, nteNameLen] (const shared_ptr<Entry>& entry) {
- // initial part of name is guaranteed to be equal by NameTree
- // check implicit digest (or its absence) only
- return entry->canMatch(interest, nteNameLen);
+ [&interest, nteDepth] (const shared_ptr<Entry>& entry) {
+ // NameTree guarantees first nteDepth components are equal
+ return entry->canMatch(interest, nteDepth);
});
if (it != pitEntries.end()) {
return {*it, false};
diff --git a/daemon/table/strategy-choice.cpp b/daemon/table/strategy-choice.cpp
index 55db095..7d25b4b 100644
--- a/daemon/table/strategy-choice.cpp
+++ b/daemon/table/strategy-choice.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2017, Regents of the University of California,
+ * Copyright (c) 2014-2018, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -87,7 +87,7 @@
return InsertResult::NOT_REGISTERED;
}
- name_tree::Entry& nte = m_nameTree.lookup(prefix, true);
+ name_tree::Entry& nte = m_nameTree.lookup(prefix);
Entry* entry = nte.getStrategyChoiceEntry();
Strategy* oldStrategy = nullptr;
if (entry != nullptr) {
diff --git a/tests/daemon/table/name-tree.t.cpp b/tests/daemon/table/name-tree.t.cpp
index 8b7307a..458d7e3 100644
--- a/tests/daemon/table/name-tree.t.cpp
+++ b/tests/daemon/table/name-tree.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2017, Regents of the University of California,
+ * Copyright (c) 2014-2018, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -417,20 +417,6 @@
BOOST_CHECK_EQUAL(nt.size(), 8);
}
-BOOST_AUTO_TEST_CASE(LongName)
-{
- Name name;
- for (int i = 0; i < 2000; ++i) {
- name.append("X");
- }
-
- NameTree nt;
-
- Entry& entry1 = nt.lookup(name, true);
- BOOST_CHECK_EQUAL(entry1.getName().size(), NameTree::getMaxDepth());
- BOOST_CHECK_EQUAL(nt.size(), NameTree::getMaxDepth() + 1);
-}
-
/** \brief verify a NameTree enumeration contains expected entries
*
* Example: