table: enforce NameTree max depth universally
refs #4262 Change-Id: Ia9b04a89c12cd09aa244201b513cc1808c0c473f
This commit is contained in:
@@ -85,19 +85,15 @@ public: // lookup
|
||||
|
||||
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>
|
||||
|
||||
@@ -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 @@ Measurements::Measurements(NameTree& nameTree)
|
||||
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 @@ Measurements::get(name_tree::Entry& nte)
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 @@ namespace measurements {
|
||||
*/
|
||||
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 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/** \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 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/** \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 @@ public:
|
||||
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 @@ private:
|
||||
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*
|
||||
|
||||
@@ -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 @@ Entry::Entry(const Name& name, Node* node)
|
||||
, m_parent(nullptr)
|
||||
{
|
||||
BOOST_ASSERT(node != nullptr);
|
||||
BOOST_ASSERT(name.size() <= NameTree::getMaxDepth());
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+34
-25
@@ -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 @@ NameTree::NameTree(size_t nBuckets)
|
||||
}
|
||||
|
||||
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 @@ NameTree::lookup(const Name& name, bool enforceMaxDepth)
|
||||
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 @@ NameTree::lookup(const fib::Entry& fibEntry)
|
||||
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 @@ NameTree::lookup(const measurements::Entry& measurementsEntry)
|
||||
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 @@ NameTree::eraseIfEmpty(Entry* entry, bool canEraseAncestors)
|
||||
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 @@ NameTree::findLongestPrefixMatch(const pit::Entry& pitEntry, const EntrySelector
|
||||
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;
|
||||
}
|
||||
|
||||
+43
-33
@@ -28,6 +28,8 @@
|
||||
|
||||
#include "name-tree-iterator.hpp"
|
||||
|
||||
#include "core/fib-max-depth.hpp"
|
||||
|
||||
namespace nfd {
|
||||
namespace name_tree {
|
||||
|
||||
@@ -40,20 +42,17 @@ public:
|
||||
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: // information
|
||||
}
|
||||
|
||||
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 @@ public: // mutation
|
||||
* \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: // mutation
|
||||
|
||||
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 @@ public: // matching
|
||||
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 @@ public: // matching
|
||||
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,
|
||||
|
||||
+10
-11
@@ -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 @@ Pit::findOrInsert(const Interest& interest, bool allowInsert)
|
||||
{
|
||||
// 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};
|
||||
|
||||
@@ -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 @@ StrategyChoice::insert(const Name& prefix, const Name& strategyName)
|
||||
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) {
|
||||
|
||||
@@ -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_AUTO_TEST_CASE(Basic)
|
||||
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:
|
||||
|
||||
Reference in New Issue
Block a user