interest: reduce implicit digest computation in matchesData
refs #1707
Change-Id: I9f1d2eebc3ec5ef2e408afb40881640a6b2dae80
diff --git a/src/interest.cpp b/src/interest.cpp
index db3744c..f5ff57b 100644
--- a/src/interest.cpp
+++ b/src/interest.cpp
@@ -21,10 +21,9 @@
* Based on code originally written by Jeff Thompson <jefft0@remap.ucla.edu>
*/
-#include "common.hpp"
-
#include "interest.hpp"
#include "util/random.hpp"
+#include "util/crypto.hpp"
#include "data.hpp"
namespace ndn {
@@ -102,10 +101,69 @@
bool
Interest::matchesData(const Data& data) const
{
- if (!this->matchesName(data.getFullName())) {
+ size_t interestNameLength = m_name.size();
+ const Name& dataName = data.getName();
+ size_t fullNameLength = dataName.size() + 1;
+
+ // check MinSuffixComponents
+ bool hasMinSuffixComponents = getMinSuffixComponents() >= 0;
+ size_t minSuffixComponents = hasMinSuffixComponents ?
+ static_cast<size_t>(getMinSuffixComponents()) : 0;
+ if (!(interestNameLength + minSuffixComponents <= fullNameLength))
return false;
+
+ // check MaxSuffixComponents
+ bool hasMaxSuffixComponents = getMaxSuffixComponents() >= 0;
+ if (hasMaxSuffixComponents &&
+ !(interestNameLength + getMaxSuffixComponents() >= fullNameLength))
+ return false;
+
+ // check prefix
+ if (interestNameLength == fullNameLength) {
+ bool mightEndWithDigest = (interestNameLength > 0) &&
+ (m_name.get(-1).value_size() == crypto::SHA256_DIGEST_SIZE);
+ if (mightEndWithDigest) {
+ // Interest Name is same length as Data full Name, last component could match digest
+ if (!m_name.isPrefixOf(data.getFullName()))
+ return false;
+ }
+ else {
+ // Interest Name is same length as Data full Name, but last component isn't digest
+ // so there's no possibility of matching
+ return false;
+ }
+ }
+ else {
+ // Interest Name is a strict prefix of Data full Name
+ if (!m_name.isPrefixOf(dataName))
+ return false;
}
+ // check Exclude
+ // Exclude won't be violated if Interest Name is same as Data full Name
+ if (!getExclude().empty() && fullNameLength > interestNameLength) {
+ if (interestNameLength == fullNameLength - 1) {
+ // component to exclude is the digest
+ if (getExclude().isExcluded(data.getFullName().get(interestNameLength)))
+ return false;
+ // There's opportunity to inspect the Exclude filter and determine whether
+ // the digest would make a difference.
+ // eg. "Exclude=<Any>AA" won't exclude any digest - fullName not needed
+ // "Exclude=ZZ<Any>" excludes all digests - fullName not needed
+ // "Exclude=<Any>80000000000000000000000000000000"
+ // excludes half of the digests - fullName required
+ // But Interests that contain the exact Data Name before digest and also
+ // contain Exclude filter is too rare to optimize for, so we request
+ // fullName no mater what's in the Exclude filter.
+ }
+ else {
+ // component to exclude is not the digest
+ if (getExclude().isExcluded(dataName.get(interestNameLength)))
+ return false;
+ }
+ }
+
+ // check PublisherPublicKeyLocator
const KeyLocator& publisherPublicKeyLocator = this->getPublisherPublicKeyLocator();
if (!publisherPublicKeyLocator.empty()) {
const Signature& signature = data.getSignature();