blob: 897fab15b3aa455bfbf253620f5bda84d17b2403 [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{
Weiqi Shif0330d52014-07-09 10:54:27 -070051 shared_ptr<ndn::Data> data = getStorageHandle().readData(interest);
Nick Gordon190e4dc2017-10-04 16:54:10 -050052 if (data != nullptr) {
Weiqi Shif0330d52014-07-09 10:54:27 -070053 getFace().put(*data);
54 }
Wentao Shang91fb4f22014-05-20 10:55:22 -070055}
56
57void
Shuo Chen9c2477f2014-03-13 15:01:06 -070058ReadHandle::onRegisterFailed(const Name& prefix, const std::string& reason)
59{
60 std::cerr << "ERROR: Failed to register prefix in local hub's daemon" << std::endl;
Shuo Chen29c77fe2014-03-18 11:29:41 -070061 getFace().shutdown();
Shuo Chen9c2477f2014-03-13 15:01:06 -070062}
63
64void
65ReadHandle::listen(const Name& prefix)
66{
Weiqi Shif0330d52014-07-09 10:54:27 -070067 ndn::InterestFilter filter(prefix);
68 getFace().setInterestFilter(filter,
Shuo Chen29c77fe2014-03-18 11:29:41 -070069 bind(&ReadHandle::onInterest, this, _1, _2),
70 bind(&ReadHandle::onRegisterFailed, this, _1, _2));
Shuo Chen9c2477f2014-03-13 15:01:06 -070071}
72
Nick Gordon190e4dc2017-10-04 16:54:10 -050073void
74ReadHandle::onDataDeleted(const Name& name)
75{
76 // We add one here to account for the implicit digest at the end,
77 // which is what we get from the underlying storage when deleting.
78 Name prefix = name.getPrefix(-(m_prefixSubsetLength + 1));
79 auto check = m_insertedDataPrefixes.find(prefix);
80 if (check != m_insertedDataPrefixes.end()) {
81 if (--(check->second.useCount) <= 0) {
82 getFace().unsetInterestFilter(check->second.prefixId);
83 m_insertedDataPrefixes.erase(prefix);
84 }
85 }
86}
87
88void
89ReadHandle::onDataInserted(const Name& name)
90{
91 // Note: We want to save the prefix that we register exactly, not the
92 // name that provoked the registration
93 Name prefixToRegister = name.getPrefix(-m_prefixSubsetLength);
94 ndn::InterestFilter filter(prefixToRegister);
95 auto check = m_insertedDataPrefixes.find(prefixToRegister);
96 if (check == m_insertedDataPrefixes.end()) {
97 // Because of stack lifetime problems, we assume here that the
98 // prefix registration will be successful, and we add the registered
99 // prefix to our list. This is because, if we fail, we shut
100 // everything down, anyway. If registration failures are ever
101 // considered to be recoverable, we would need to make this
102 // atomic.
103 const ndn::RegisteredPrefixId* prefixId = getFace().setInterestFilter(filter,
104 [this] (const ndn::InterestFilter& filter, const Interest& interest) {
105 // Implicit conversion to Name of filter
106 onInterest(filter, interest);
107 },
Davide Pesavento8cc7b912017-11-16 13:15:24 -0500108 [] (const Name&) {},
Nick Gordon190e4dc2017-10-04 16:54:10 -0500109 [this] (const Name& prefix, const std::string& reason) {
110 onRegisterFailed(prefix, reason);
111 });
112 RegisteredDataPrefix registeredPrefix{prefixId, 1};
113 // Newly registered prefix
114 m_insertedDataPrefixes.emplace(std::make_pair(prefixToRegister, registeredPrefix));
115 }
116 else {
117 check->second.useCount++;
118 }
119}
120
121} // namespace repo