blob: 1f13bf3666aa8969d54dfdbaa06875748ef1018c [file] [log] [blame]
Shuo Chen9c2477f2014-03-13 15:01:06 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Nick Gordon190e4dc2017-10-04 16:54:10 -05003 * Copyright (c) 2014-2017, Regents of the University of California.
Alexander Afanasyeve1e6f2a2014-04-25 11:28:12 -07004 *
5 * This file is part of NDN repo-ng (Next generation of NDN repository).
6 * See AUTHORS.md for complete list of repo-ng authors and contributors.
7 *
8 * repo-ng is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * repo-ng, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Shuo Chen9c2477f2014-03-13 15:01:06 -070018 */
Alexander Afanasyeve1e6f2a2014-04-25 11:28:12 -070019
Shuo Chen9c2477f2014-03-13 15:01:06 -070020#include "read-handle.hpp"
Nick Gordon190e4dc2017-10-04 16:54:10 -050021#include "repo.hpp"
Shuo Chen9c2477f2014-03-13 15:01:06 -070022
23namespace repo {
24
Nick Gordon190e4dc2017-10-04 16:54:10 -050025ReadHandle::ReadHandle(Face& face, RepoStorage& storageHandle, KeyChain& keyChain,
26 Scheduler& scheduler, size_t prefixSubsetLength)
27 : BaseHandle(face, storageHandle, keyChain, scheduler)
28 , m_prefixSubsetLength(prefixSubsetLength)
29{
30}
31
32void
33ReadHandle::connectAutoListen()
34{
35 // Connect a RepoStorage's signals to the read handle
36 if (m_prefixSubsetLength != RepoConfig::DISABLED_SUBSET_LENGTH) {
37 afterDataDeletionConnection = m_storageHandle.afterDataInsertion.connect(
38 [this] (const Name& prefix) {
39 onDataInserted(prefix);
40 });
41 afterDataInsertionConnection = m_storageHandle.afterDataDeletion.connect(
42 [this] (const Name& prefix) {
43 onDataDeleted(prefix);
44 });
45 }
46}
47
Shuo Chen9c2477f2014-03-13 15:01:06 -070048void
49ReadHandle::onInterest(const Name& prefix, const Interest& interest)
50{
Shuo Chen9c2477f2014-03-13 15:01:06 -070051
Weiqi Shif0330d52014-07-09 10:54:27 -070052 shared_ptr<ndn::Data> data = getStorageHandle().readData(interest);
Nick Gordon190e4dc2017-10-04 16:54:10 -050053 if (data != nullptr) {
Weiqi Shif0330d52014-07-09 10:54:27 -070054 getFace().put(*data);
55 }
Wentao Shang91fb4f22014-05-20 10:55:22 -070056}
57
58void
Shuo Chen9c2477f2014-03-13 15:01:06 -070059ReadHandle::onRegisterFailed(const Name& prefix, const std::string& reason)
60{
61 std::cerr << "ERROR: Failed to register prefix in local hub's daemon" << std::endl;
Shuo Chen29c77fe2014-03-18 11:29:41 -070062 getFace().shutdown();
Shuo Chen9c2477f2014-03-13 15:01:06 -070063}
64
65void
66ReadHandle::listen(const Name& prefix)
67{
Weiqi Shif0330d52014-07-09 10:54:27 -070068 ndn::InterestFilter filter(prefix);
69 getFace().setInterestFilter(filter,
Shuo Chen29c77fe2014-03-18 11:29:41 -070070 bind(&ReadHandle::onInterest, this, _1, _2),
71 bind(&ReadHandle::onRegisterFailed, this, _1, _2));
Shuo Chen9c2477f2014-03-13 15:01:06 -070072}
73
Nick Gordon190e4dc2017-10-04 16:54:10 -050074void
75ReadHandle::onDataDeleted(const Name& name)
76{
77 // We add one here to account for the implicit digest at the end,
78 // which is what we get from the underlying storage when deleting.
79 Name prefix = name.getPrefix(-(m_prefixSubsetLength + 1));
80 auto check = m_insertedDataPrefixes.find(prefix);
81 if (check != m_insertedDataPrefixes.end()) {
82 if (--(check->second.useCount) <= 0) {
83 getFace().unsetInterestFilter(check->second.prefixId);
84 m_insertedDataPrefixes.erase(prefix);
85 }
86 }
87}
88
89void
90ReadHandle::onDataInserted(const Name& name)
91{
92 // Note: We want to save the prefix that we register exactly, not the
93 // name that provoked the registration
94 Name prefixToRegister = name.getPrefix(-m_prefixSubsetLength);
95 ndn::InterestFilter filter(prefixToRegister);
96 auto check = m_insertedDataPrefixes.find(prefixToRegister);
97 if (check == m_insertedDataPrefixes.end()) {
98 // Because of stack lifetime problems, we assume here that the
99 // prefix registration will be successful, and we add the registered
100 // prefix to our list. This is because, if we fail, we shut
101 // everything down, anyway. If registration failures are ever
102 // considered to be recoverable, we would need to make this
103 // atomic.
104 const ndn::RegisteredPrefixId* prefixId = getFace().setInterestFilter(filter,
105 [this] (const ndn::InterestFilter& filter, const Interest& interest) {
106 // Implicit conversion to Name of filter
107 onInterest(filter, interest);
108 },
109 [this] (const Name& prefix) {
110 },
111 [this] (const Name& prefix, const std::string& reason) {
112 onRegisterFailed(prefix, reason);
113 });
114 RegisteredDataPrefix registeredPrefix{prefixId, 1};
115 // Newly registered prefix
116 m_insertedDataPrefixes.emplace(std::make_pair(prefixToRegister, registeredPrefix));
117 }
118 else {
119 check->second.useCount++;
120 }
121}
122
123} // namespace repo