blob: 44a9d18b91d494e0746cf205814858aff847d118 [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
23namespace repo {
24
weijia yuan82cf9142018-10-21 12:25:02 -070025ReadHandle::ReadHandle(Face& face, RepoStorage& storageHandle, size_t prefixSubsetLength)
26 : m_prefixSubsetLength(prefixSubsetLength)
27 , m_face(face)
28 , m_storageHandle(storageHandle)
Nick Gordon190e4dc2017-10-04 16:54:10 -050029{
Alexander Afanasyevbb058c02018-02-15 22:49:24 +000030 connectAutoListen();
Nick Gordon190e4dc2017-10-04 16:54:10 -050031}
32
33void
34ReadHandle::connectAutoListen()
35{
36 // Connect a RepoStorage's signals to the read handle
37 if (m_prefixSubsetLength != RepoConfig::DISABLED_SUBSET_LENGTH) {
38 afterDataDeletionConnection = m_storageHandle.afterDataInsertion.connect(
39 [this] (const Name& prefix) {
40 onDataInserted(prefix);
41 });
42 afterDataInsertionConnection = m_storageHandle.afterDataDeletion.connect(
43 [this] (const Name& prefix) {
44 onDataDeleted(prefix);
45 });
46 }
47}
48
Shuo Chen9c2477f2014-03-13 15:01:06 -070049void
50ReadHandle::onInterest(const Name& prefix, const Interest& interest)
51{
weijia yuan82cf9142018-10-21 12:25:02 -070052 shared_ptr<ndn::Data> data = m_storageHandle.readData(interest);
Nick Gordon190e4dc2017-10-04 16:54:10 -050053 if (data != nullptr) {
weijia yuan82cf9142018-10-21 12:25:02 -070054 m_face.put(*data);
Weiqi Shif0330d52014-07-09 10:54:27 -070055 }
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;
weijia yuan82cf9142018-10-21 12:25:02 -070062 m_face.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);
weijia yuan82cf9142018-10-21 12:25:02 -070069 m_face.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) {
weijia yuan82cf9142018-10-21 12:25:02 -070083 m_face.unsetInterestFilter(check->second.prefixId);
Nick Gordon190e4dc2017-10-04 16:54:10 -050084 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.
weijia yuan82cf9142018-10-21 12:25:02 -0700104 const ndn::RegisteredPrefixId* prefixId = m_face.setInterestFilter(filter,
Nick Gordon190e4dc2017-10-04 16:54:10 -0500105 [this] (const ndn::InterestFilter& filter, const Interest& interest) {
106 // Implicit conversion to Name of filter
107 onInterest(filter, interest);
108 },
Davide Pesavento8cc7b912017-11-16 13:15:24 -0500109 [] (const Name&) {},
Nick Gordon190e4dc2017-10-04 16:54:10 -0500110 [this] (const Name& prefix, const std::string& reason) {
111 onRegisterFailed(prefix, reason);
112 });
113 RegisteredDataPrefix registeredPrefix{prefixId, 1};
114 // Newly registered prefix
115 m_insertedDataPrefixes.emplace(std::make_pair(prefixToRegister, registeredPrefix));
116 }
117 else {
118 check->second.useCount++;
119 }
120}
121
122} // namespace repo