read: auto-register prefixes for inserted data
Change-Id: Iebddca056a4c74f179f7af7203881adfe1cba777
refs: #4247
diff --git a/src/handles/base-handle.hpp b/src/handles/base-handle.hpp
index a14360a..5d12076 100644
--- a/src/handles/base-handle.hpp
+++ b/src/handles/base-handle.hpp
@@ -44,8 +44,8 @@
public:
BaseHandle(Face& face, RepoStorage& storageHandle, KeyChain& keyChain,
Scheduler& scheduler)
- : m_face(face)
- , m_storageHandle(storageHandle)
+ : m_storageHandle(storageHandle)
+ , m_face(face)
, m_keyChain(keyChain)
, m_scheduler(scheduler)
// , m_storeindex(storeindex)
@@ -101,10 +101,11 @@
void
extractParameter(const Interest& interest, const Name& prefix, RepoCommandParameter& parameter);
-private:
-
- Face& m_face;
+protected:
RepoStorage& m_storageHandle;
+
+private:
+ Face& m_face;
KeyChain& m_keyChain;
Scheduler& m_scheduler;
// RepoStorage& m_storeindex;
diff --git a/src/handles/read-handle.cpp b/src/handles/read-handle.cpp
index 83133e2..1f13bf3 100644
--- a/src/handles/read-handle.cpp
+++ b/src/handles/read-handle.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014, Regents of the University of California.
+ * Copyright (c) 2014-2017, Regents of the University of California.
*
* This file is part of NDN repo-ng (Next generation of NDN repository).
* See AUTHORS.md for complete list of repo-ng authors and contributors.
@@ -18,15 +18,39 @@
*/
#include "read-handle.hpp"
+#include "repo.hpp"
namespace repo {
+ReadHandle::ReadHandle(Face& face, RepoStorage& storageHandle, KeyChain& keyChain,
+ Scheduler& scheduler, size_t prefixSubsetLength)
+ : BaseHandle(face, storageHandle, keyChain, scheduler)
+ , m_prefixSubsetLength(prefixSubsetLength)
+{
+}
+
+void
+ReadHandle::connectAutoListen()
+{
+ // Connect a RepoStorage's signals to the read handle
+ if (m_prefixSubsetLength != RepoConfig::DISABLED_SUBSET_LENGTH) {
+ afterDataDeletionConnection = m_storageHandle.afterDataInsertion.connect(
+ [this] (const Name& prefix) {
+ onDataInserted(prefix);
+ });
+ afterDataInsertionConnection = m_storageHandle.afterDataDeletion.connect(
+ [this] (const Name& prefix) {
+ onDataDeleted(prefix);
+ });
+ }
+}
+
void
ReadHandle::onInterest(const Name& prefix, const Interest& interest)
{
shared_ptr<ndn::Data> data = getStorageHandle().readData(interest);
- if (data != NULL) {
+ if (data != nullptr) {
getFace().put(*data);
}
}
@@ -47,4 +71,53 @@
bind(&ReadHandle::onRegisterFailed, this, _1, _2));
}
-} //namespace repo
+void
+ReadHandle::onDataDeleted(const Name& name)
+{
+ // We add one here to account for the implicit digest at the end,
+ // which is what we get from the underlying storage when deleting.
+ Name prefix = name.getPrefix(-(m_prefixSubsetLength + 1));
+ auto check = m_insertedDataPrefixes.find(prefix);
+ if (check != m_insertedDataPrefixes.end()) {
+ if (--(check->second.useCount) <= 0) {
+ getFace().unsetInterestFilter(check->second.prefixId);
+ m_insertedDataPrefixes.erase(prefix);
+ }
+ }
+}
+
+void
+ReadHandle::onDataInserted(const Name& name)
+{
+ // Note: We want to save the prefix that we register exactly, not the
+ // name that provoked the registration
+ Name prefixToRegister = name.getPrefix(-m_prefixSubsetLength);
+ ndn::InterestFilter filter(prefixToRegister);
+ auto check = m_insertedDataPrefixes.find(prefixToRegister);
+ if (check == m_insertedDataPrefixes.end()) {
+ // Because of stack lifetime problems, we assume here that the
+ // prefix registration will be successful, and we add the registered
+ // prefix to our list. This is because, if we fail, we shut
+ // everything down, anyway. If registration failures are ever
+ // considered to be recoverable, we would need to make this
+ // atomic.
+ const ndn::RegisteredPrefixId* prefixId = getFace().setInterestFilter(filter,
+ [this] (const ndn::InterestFilter& filter, const Interest& interest) {
+ // Implicit conversion to Name of filter
+ onInterest(filter, interest);
+ },
+ [this] (const Name& prefix) {
+ },
+ [this] (const Name& prefix, const std::string& reason) {
+ onRegisterFailed(prefix, reason);
+ });
+ RegisteredDataPrefix registeredPrefix{prefixId, 1};
+ // Newly registered prefix
+ m_insertedDataPrefixes.emplace(std::make_pair(prefixToRegister, registeredPrefix));
+ }
+ else {
+ check->second.useCount++;
+ }
+}
+
+} // namespace repo
diff --git a/src/handles/read-handle.hpp b/src/handles/read-handle.hpp
index 19d2034..a2bbd86 100644
--- a/src/handles/read-handle.hpp
+++ b/src/handles/read-handle.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014, Regents of the University of California.
+ * Copyright (c) 2014-2017, Regents of the University of California.
*
* This file is part of NDN repo-ng (Next generation of NDN repository).
* See AUTHORS.md for complete list of repo-ng authors and contributors.
@@ -20,23 +20,50 @@
#ifndef REPO_HANDLES_READ_HANDLE_HPP
#define REPO_HANDLES_READ_HANDLE_HPP
+#include "common.hpp"
#include "base-handle.hpp"
-
namespace repo {
class ReadHandle : public BaseHandle
{
public:
- ReadHandle(Face& face, RepoStorage& storageHandle, KeyChain& keyChain,
- Scheduler& scheduler)
- : BaseHandle(face, storageHandle, keyChain, scheduler)
+ using DataPrefixRegistrationCallback = std::function<void(const ndn::Name&)>;
+ using DataPrefixUnregistrationCallback = std::function<void(const ndn::Name&)>;
+ struct RegisteredDataPrefix
{
+ const ndn::RegisteredPrefixId* prefixId;
+ int useCount;
+ };
+
+ ReadHandle(Face& face, RepoStorage& storageHandle, KeyChain& keyChain,
+ Scheduler& scheduler, size_t prefixSubsetLength);
+
+ void
+ listen(const Name& prefix) override;
+
+ void
+ connectAutoListen();
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+ const std::map<ndn::Name, RegisteredDataPrefix>&
+ getRegisteredPrefixes()
+ {
+ return m_insertedDataPrefixes;
}
- virtual void
- listen(const Name& prefix);
+ /**
+ * @param after Do something after actually removing a prefix
+ */
+ void
+ onDataDeleted(const Name& name);
+
+ /**
+ * @param after Do something after successfully registering the data prefix
+ */
+ void
+ onDataInserted(const Name& name);
private:
/**
@@ -47,6 +74,12 @@
void
onRegisterFailed(const Name& prefix, const std::string& reason);
+
+private:
+ size_t m_prefixSubsetLength;
+ std::map<ndn::Name, RegisteredDataPrefix> m_insertedDataPrefixes;
+ ndn::util::signal::ScopedConnection afterDataDeletionConnection;
+ ndn::util::signal::ScopedConnection afterDataInsertionConnection;
};
} // namespace repo