blob: dbdfef763422d0fa8435351b013746ec51b06296 [file] [log] [blame]
Shuo Chen9c2477f2014-03-13 15:01:06 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyevbb058c02018-02-15 22:49:24 +00002/*
3 * Copyright (c) 2014-2018, 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
weijia yuan3aa8d2b2018-03-06 15:35:57 -080023#include <ndn-cxx/util/logger.hpp>
24
Shuo Chen9c2477f2014-03-13 15:01:06 -070025namespace repo {
26
weijia yuan3aa8d2b2018-03-06 15:35:57 -080027NDN_LOG_INIT(repo.ReadHandle);
28
weijia yuan82cf9142018-10-21 12:25:02 -070029ReadHandle::ReadHandle(Face& face, RepoStorage& storageHandle, size_t prefixSubsetLength)
30 : m_prefixSubsetLength(prefixSubsetLength)
31 , m_face(face)
32 , m_storageHandle(storageHandle)
Nick Gordon190e4dc2017-10-04 16:54:10 -050033{
Alexander Afanasyevbb058c02018-02-15 22:49:24 +000034 connectAutoListen();
Nick Gordon190e4dc2017-10-04 16:54:10 -050035}
36
37void
38ReadHandle::connectAutoListen()
39{
40 // Connect a RepoStorage's signals to the read handle
41 if (m_prefixSubsetLength != RepoConfig::DISABLED_SUBSET_LENGTH) {
weijia yuan3aa8d2b2018-03-06 15:35:57 -080042 afterDataInsertionConnection = m_storageHandle.afterDataInsertion.connect(
Nick Gordon190e4dc2017-10-04 16:54:10 -050043 [this] (const Name& prefix) {
44 onDataInserted(prefix);
45 });
weijia yuan3aa8d2b2018-03-06 15:35:57 -080046 afterDataDeletionConnection = m_storageHandle.afterDataDeletion.connect(
Nick Gordon190e4dc2017-10-04 16:54:10 -050047 [this] (const Name& prefix) {
48 onDataDeleted(prefix);
49 });
50 }
51}
52
Shuo Chen9c2477f2014-03-13 15:01:06 -070053void
54ReadHandle::onInterest(const Name& prefix, const Interest& interest)
55{
weijia yuan3aa8d2b2018-03-06 15:35:57 -080056 NDN_LOG_DEBUG("Received Interest " << interest.getName());
57 std::shared_ptr<ndn::Data> data = m_storageHandle.readData(interest);
Nick Gordon190e4dc2017-10-04 16:54:10 -050058 if (data != nullptr) {
weijia yuan3aa8d2b2018-03-06 15:35:57 -080059 NDN_LOG_DEBUG("Put Data: " << *data);
60 m_face.put(*data);
61 }
62 else {
63 NDN_LOG_DEBUG("No data for " << interest.getName());
Weiqi Shif0330d52014-07-09 10:54:27 -070064 }
Wentao Shang91fb4f22014-05-20 10:55:22 -070065}
66
67void
Shuo Chen9c2477f2014-03-13 15:01:06 -070068ReadHandle::onRegisterFailed(const Name& prefix, const std::string& reason)
69{
weijia yuan3aa8d2b2018-03-06 15:35:57 -080070 NDN_LOG_ERROR("ERROR: Failed to register prefix in local hub's daemon");
weijia yuan82cf9142018-10-21 12:25:02 -070071 m_face.shutdown();
Shuo Chen9c2477f2014-03-13 15:01:06 -070072}
73
74void
75ReadHandle::listen(const Name& prefix)
76{
Weiqi Shif0330d52014-07-09 10:54:27 -070077 ndn::InterestFilter filter(prefix);
weijia yuan82cf9142018-10-21 12:25:02 -070078 m_face.setInterestFilter(filter,
weijia yuan3aa8d2b2018-03-06 15:35:57 -080079 std::bind(&ReadHandle::onInterest, this, _1, _2),
80 std::bind(&ReadHandle::onRegisterFailed, this, _1, _2));
Shuo Chen9c2477f2014-03-13 15:01:06 -070081}
82
Nick Gordon190e4dc2017-10-04 16:54:10 -050083void
84ReadHandle::onDataDeleted(const Name& name)
85{
86 // We add one here to account for the implicit digest at the end,
87 // which is what we get from the underlying storage when deleting.
88 Name prefix = name.getPrefix(-(m_prefixSubsetLength + 1));
89 auto check = m_insertedDataPrefixes.find(prefix);
90 if (check != m_insertedDataPrefixes.end()) {
91 if (--(check->second.useCount) <= 0) {
weijia yuan82cf9142018-10-21 12:25:02 -070092 m_face.unsetInterestFilter(check->second.prefixId);
Nick Gordon190e4dc2017-10-04 16:54:10 -050093 m_insertedDataPrefixes.erase(prefix);
94 }
95 }
96}
97
98void
99ReadHandle::onDataInserted(const Name& name)
100{
101 // Note: We want to save the prefix that we register exactly, not the
102 // name that provoked the registration
103 Name prefixToRegister = name.getPrefix(-m_prefixSubsetLength);
104 ndn::InterestFilter filter(prefixToRegister);
105 auto check = m_insertedDataPrefixes.find(prefixToRegister);
106 if (check == m_insertedDataPrefixes.end()) {
107 // Because of stack lifetime problems, we assume here that the
108 // prefix registration will be successful, and we add the registered
109 // prefix to our list. This is because, if we fail, we shut
110 // everything down, anyway. If registration failures are ever
111 // considered to be recoverable, we would need to make this
112 // atomic.
weijia yuan82cf9142018-10-21 12:25:02 -0700113 const ndn::RegisteredPrefixId* prefixId = m_face.setInterestFilter(filter,
Nick Gordon190e4dc2017-10-04 16:54:10 -0500114 [this] (const ndn::InterestFilter& filter, const Interest& interest) {
115 // Implicit conversion to Name of filter
116 onInterest(filter, interest);
117 },
Davide Pesavento8cc7b912017-11-16 13:15:24 -0500118 [] (const Name&) {},
Nick Gordon190e4dc2017-10-04 16:54:10 -0500119 [this] (const Name& prefix, const std::string& reason) {
120 onRegisterFailed(prefix, reason);
121 });
122 RegisteredDataPrefix registeredPrefix{prefixId, 1};
123 // Newly registered prefix
124 m_insertedDataPrefixes.emplace(std::make_pair(prefixToRegister, registeredPrefix));
125 }
126 else {
127 check->second.useCount++;
128 }
129}
130
131} // namespace repo