blob: c6bf498cefc64eaea98320f557694f74b0d702dc [file] [log] [blame]
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyeva9369b42017-01-11 11:58:00 -08003 * Copyright (c) 2013-2017, Regents of the University of California.
Zhenkai Zhu8224bb62013-01-06 15:58:02 -08004 *
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -08005 * This file is part of ChronoShare, a decentralized file sharing application over NDN.
Zhenkai Zhu8224bb62013-01-06 15:58:02 -08006 *
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -08007 * ChronoShare is free software: you can redistribute it and/or modify it under the terms
8 * of the GNU General Public License as published by the Free Software Foundation, either
9 * version 3 of the License, or (at your option) any later version.
Zhenkai Zhu8224bb62013-01-06 15:58:02 -080010 *
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -080011 * ChronoShare is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU General Public License for more details.
Zhenkai Zhu8224bb62013-01-06 15:58:02 -080014 *
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -080015 * You should have received copies of the GNU General Public License along with
16 * ChronoShare, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * See AUTHORS.md for complete list of ChronoShare authors and contributors.
Zhenkai Zhu8224bb62013-01-06 15:58:02 -080019 */
20
Alexander Afanasyevf4cde4e2016-12-25 13:42:57 -080021#include "sync-core.hpp"
Alexander Afanasyevf4cde4e2016-12-25 13:42:57 -080022#include "logging.hpp"
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080023#include "periodic-task.hpp"
Alexander Afanasyevf4cde4e2016-12-25 13:42:57 -080024#include "random-interval-generator.hpp"
25#include "simple-interval-generator.hpp"
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080026#include "sync-state-helper.hpp"
Alexander Afanasyevabe952a2013-01-17 17:06:32 -080027
Alexander Afanasyevc507ac22013-01-21 16:01:58 -080028#include <boost/lexical_cast.hpp>
Zhenkai Zhu3b406592013-01-25 21:07:49 -080029#include <boost/make_shared.hpp>
Alexander Afanasyevc507ac22013-01-21 16:01:58 -080030
Alexander Afanasyeva9369b42017-01-11 11:58:00 -080031INIT_LOGGER("Sync.Core")
Alexander Afanasyevc507ac22013-01-21 16:01:58 -080032
Zhenkai Zhue851b952013-01-13 22:29:57 -080033const string SyncCore::RECOVER = "RECOVER";
Zhenkai Zhue573ae82013-01-15 13:15:52 -080034const double SyncCore::WAIT = 0.05;
Zhenkai Zhue851b952013-01-13 22:29:57 -080035const double SyncCore::RANDOM_PERCENT = 0.5;
36
Alexander Afanasyev50526282013-01-26 13:43:57 -080037const std::string SYNC_INTEREST_TAG = "send-sync-interest";
38const std::string SYNC_INTEREST_TAG2 = "send-sync-interest2";
39
Alexander Afanasyeva2fabcf2013-02-05 11:26:37 -080040const std::string LOCAL_STATE_CHANGE_DELAYED_TAG = "local-state-changed";
41
Alexander Afanasyevc507ac22013-01-21 16:01:58 -080042using namespace boost;
Alexander Afanasyev1dd37ed2013-08-14 18:08:09 -070043using namespace Ndnx;
Alexander Afanasyevc507ac22013-01-21 16:01:58 -080044
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080045SyncCore::SyncCore(SyncLogPtr syncLog, const Name& userName, const Name& localPrefix,
46 const Name& syncPrefix, const StateMsgCallback& callback, CcnxWrapperPtr ccnx,
47 double syncInterestInterval /*= -1.0*/)
48 : m_ccnx(ccnx)
Alexander Afanasyev49a30d02013-01-21 21:38:48 -080049 , m_log(syncLog)
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080050 , m_scheduler(new Scheduler())
Alexander Afanasyevd94a8c62013-01-24 13:53:40 -080051 , m_stateMsgCallback(callback)
52 , m_syncPrefix(syncPrefix)
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080053 , m_recoverWaitGenerator(
54 new RandomIntervalGenerator(WAIT, RANDOM_PERCENT, RandomIntervalGenerator::UP))
Zhenkai Zhu95160102013-01-25 21:54:57 -080055 , m_syncInterestInterval(syncInterestInterval)
Zhenkai Zhu8224bb62013-01-06 15:58:02 -080056{
Zhenkai Zhub330aed2013-01-17 13:29:37 -080057 m_rootHash = m_log->RememberStateInStateLog();
Alexander Afanasyevd6c2a902013-01-19 21:24:30 -080058
Alexander Afanasyev1dd37ed2013-08-14 18:08:09 -070059 m_ndnx->setInterestFilter(m_syncPrefix, boost::bind(&SyncCore::handleInterest, this, _1));
Alexander Afanasyevdac84922013-01-20 23:32:17 -080060 // m_log->initYP(m_yp);
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080061 m_log->UpdateLocalLocator(localPrefix);
Alexander Afanasyev7326a252013-01-20 23:43:25 -080062
Zhenkai Zhue573ae82013-01-15 13:15:52 -080063 m_scheduler->start();
Alexander Afanasyev50526282013-01-26 13:43:57 -080064
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080065 double interval =
66 (m_syncInterestInterval > 0 && m_syncInterestInterval < 30.0) ? m_syncInterestInterval : 4.0;
67 m_sendSyncInterestTask =
68 make_shared<PeriodicTask>(bind(&SyncCore::sendSyncInterest, this), SYNC_INTEREST_TAG,
69 m_scheduler, make_shared<SimpleIntervalGenerator>(interval));
Alexander Afanasyev50526282013-01-26 13:43:57 -080070 // sendSyncInterest();
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080071 Scheduler::scheduleOneTimeTask(m_scheduler, 0.1, bind(&SyncCore::sendSyncInterest, this),
72 SYNC_INTEREST_TAG2);
Zhenkai Zhu74dd53c2013-01-10 23:39:57 -080073}
74
75SyncCore::~SyncCore()
76{
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080077 m_scheduler->shutdown();
Alexander Afanasyevd6c2a902013-01-19 21:24:30 -080078 // need to "deregister" closures
Zhenkai Zhue851b952013-01-13 22:29:57 -080079}
80
Zhenkai Zhu74dd53c2013-01-10 23:39:57 -080081void
Zhenkai Zhue851b952013-01-13 22:29:57 -080082SyncCore::updateLocalState(sqlite3_int64 seqno)
Zhenkai Zhu74dd53c2013-01-10 23:39:57 -080083{
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080084 m_log->UpdateLocalSeqNo(seqno);
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -080085 localStateChanged();
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -080086}
Alexander Afanasyev49a30d02013-01-21 21:38:48 -080087
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -080088void
89SyncCore::localStateChanged()
90{
Zhenkai Zhu74dd53c2013-01-10 23:39:57 -080091 HashPtr oldHash = m_rootHash;
Zhenkai Zhub330aed2013-01-17 13:29:37 -080092 m_rootHash = m_log->RememberStateInStateLog();
Zhenkai Zhu74dd53c2013-01-10 23:39:57 -080093
Zhenkai Zhub330aed2013-01-17 13:29:37 -080094 SyncStateMsgPtr msg = m_log->FindStateDifferences(*oldHash, *m_rootHash);
Zhenkai Zhu74dd53c2013-01-10 23:39:57 -080095
96 // reply sync Interest with oldHash as last component
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080097 Name syncName = Name(m_syncPrefix)(oldHash->GetHash(), oldHash->GetHashBytes());
98 BytesPtr syncData = serializeGZipMsg(*msg);
Alexander Afanasyev49a30d02013-01-21 21:38:48 -080099
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800100 m_ccnx->publishData(syncName, *syncData, FRESHNESS);
101 _LOG_DEBUG("[" << m_log->GetLocalName() << "] localStateChanged ");
102 _LOG_TRACE("[" << m_log->GetLocalName() << "] publishes: " << oldHash->shortHash());
Alexander Afanasyevfc720362013-01-24 21:49:48 -0800103 // _LOG_TRACE (msg);
Zhenkai Zhu74dd53c2013-01-10 23:39:57 -0800104
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800105 m_scheduler->deleteTask(SYNC_INTEREST_TAG2);
Zhenkai Zhu74dd53c2013-01-10 23:39:57 -0800106 // no hurry in sending out new Sync Interest; if others send the new Sync Interest first, no problem, we know the new root hash already;
107 // this is trying to avoid the situation that the order of SyncData and new Sync Interest gets reversed at receivers
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800108 Scheduler::scheduleOneTimeTask(m_scheduler, 0.05, bind(&SyncCore::sendSyncInterest, this),
109 SYNC_INTEREST_TAG2);
Alexander Afanasyevc507ac22013-01-21 16:01:58 -0800110
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800111 // sendSyncInterest();
Zhenkai Zhu74dd53c2013-01-10 23:39:57 -0800112}
113
114void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800115SyncCore::localStateChangedDelayed()
Alexander Afanasyeva2fabcf2013-02-05 11:26:37 -0800116{
117 // many calls to localStateChangedDelayed within 0.5 second will be suppressed to one localStateChanged calls
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800118 Scheduler::scheduleOneTimeTask(m_scheduler, 0.5, bind(&SyncCore::localStateChanged, this),
119 LOCAL_STATE_CHANGE_DELAYED_TAG);
Alexander Afanasyeva2fabcf2013-02-05 11:26:37 -0800120}
121
122void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800123SyncCore::handleInterest(const Name& name)
Zhenkai Zhue851b952013-01-13 22:29:57 -0800124{
125 int size = name.size();
126 int prefixSize = m_syncPrefix.size();
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800127 if (size == prefixSize + 1) {
Zhenkai Zhue851b952013-01-13 22:29:57 -0800128 // this is normal sync interest
129 handleSyncInterest(name);
130 }
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800131 else if (size == prefixSize + 2 && name.getCompAsString(m_syncPrefix.size()) == RECOVER) {
Zhenkai Zhue851b952013-01-13 22:29:57 -0800132 // this is recovery interest
133 handleRecoverInterest(name);
134 }
135}
136
137void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800138SyncCore::handleRecoverInterest(const Name& name)
Zhenkai Zhue851b952013-01-13 22:29:57 -0800139{
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800140 _LOG_DEBUG("[" << m_log->GetLocalName() << "] <<<<< RECOVER Interest with name " << name);
Alexander Afanasyevfc720362013-01-24 21:49:48 -0800141
Zhenkai Zhue851b952013-01-13 22:29:57 -0800142 Bytes hashBytes = name.getComp(name.size() - 1);
143 // this is the hash unkonwn to the sender of the interest
144 Hash hash(head(hashBytes), hashBytes.size());
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800145 if (m_log->LookupSyncLog(hash) > 0) {
Zhenkai Zhue851b952013-01-13 22:29:57 -0800146 // we know the hash, should reply everything
Zhenkai Zhub330aed2013-01-17 13:29:37 -0800147 SyncStateMsgPtr msg = m_log->FindStateDifferences(*(Hash::Origin), *m_rootHash);
Alexander Afanasyev49a30d02013-01-21 21:38:48 -0800148
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800149 BytesPtr syncData = serializeGZipMsg(*msg);
150 m_ccnx->publishData(name, *syncData, FRESHNESS);
151 _LOG_TRACE("[" << m_log->GetLocalName() << "] publishes " << hash.shortHash());
Alexander Afanasyevfc720362013-01-24 21:49:48 -0800152 // _LOG_TRACE (msg);
Zhenkai Zhue851b952013-01-13 22:29:57 -0800153 }
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800154 else {
155 // we don't recognize this hash, can not help
156 }
Zhenkai Zhue851b952013-01-13 22:29:57 -0800157}
158
159void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800160SyncCore::handleSyncInterest(const Name& name)
Zhenkai Zhu74dd53c2013-01-10 23:39:57 -0800161{
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800162 _LOG_DEBUG("[" << m_log->GetLocalName() << "] <<<<< SYNC Interest with name " << name);
Alexander Afanasyevfc720362013-01-24 21:49:48 -0800163
Zhenkai Zhue851b952013-01-13 22:29:57 -0800164 Bytes hashBytes = name.getComp(name.size() - 1);
165 HashPtr hash(new Hash(head(hashBytes), hashBytes.size()));
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800166 if (*hash == *m_rootHash) {
Zhenkai Zhue851b952013-01-13 22:29:57 -0800167 // we have the same hash; nothing needs to be done
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800168 _LOG_TRACE("same as root hash: " << hash->shortHash());
Zhenkai Zhue851b952013-01-13 22:29:57 -0800169 return;
170 }
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800171 else if (m_log->LookupSyncLog(*hash) > 0) {
Zhenkai Zhue851b952013-01-13 22:29:57 -0800172 // we know something more
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800173 _LOG_TRACE("found hash in sync log");
Zhenkai Zhub330aed2013-01-17 13:29:37 -0800174 SyncStateMsgPtr msg = m_log->FindStateDifferences(*hash, *m_rootHash);
Zhenkai Zhue851b952013-01-13 22:29:57 -0800175
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800176 BytesPtr syncData = serializeGZipMsg(*msg);
177 m_ccnx->publishData(name, *syncData, FRESHNESS);
178 _LOG_TRACE(m_log->GetLocalName() << " publishes: " << hash->shortHash());
179 _LOG_TRACE(msg);
Zhenkai Zhue851b952013-01-13 22:29:57 -0800180 }
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800181 else {
Zhenkai Zhue851b952013-01-13 22:29:57 -0800182 // we don't recognize the hash, send recover Interest if still don't know the hash after a randomized wait period
Zhenkai Zhue573ae82013-01-15 13:15:52 -0800183 double wait = m_recoverWaitGenerator->nextInterval();
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800184 _LOG_TRACE(m_log->GetLocalName() << ", rootHash: " << *m_rootHash
185 << ", hash: " << hash->shortHash());
186 _LOG_TRACE("recover task scheduled after wait: " << wait);
Zhenkai Zhue573ae82013-01-15 13:15:52 -0800187
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800188 Scheduler::scheduleOneTimeTask(m_scheduler, wait, boost::bind(&SyncCore::recover, this, hash),
189 "r-" + lexical_cast<string>(*hash));
Zhenkai Zhue851b952013-01-13 22:29:57 -0800190 }
Zhenkai Zhu74dd53c2013-01-10 23:39:57 -0800191}
192
Zhenkai Zhuff4fa8a2013-01-28 22:02:40 -0800193void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800194SyncCore::handleSyncInterestTimeout(const Name& name, const Closure& closure, Selectors selectors)
Zhenkai Zhu74dd53c2013-01-10 23:39:57 -0800195{
Zhenkai Zhu3b406592013-01-25 21:07:49 -0800196 // sync interest will be resent by scheduler
Zhenkai Zhue851b952013-01-13 22:29:57 -0800197}
198
Zhenkai Zhuff4fa8a2013-01-28 22:02:40 -0800199void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800200SyncCore::handleRecoverInterestTimeout(const Name& name, const Closure& closure, Selectors selectors)
Zhenkai Zhue851b952013-01-13 22:29:57 -0800201{
202 // We do not re-express recovery interest for now
203 // if difference is not resolved, the sync interest will trigger
204 // recovery anyway; so it's not so important to have recovery interest
205 // re-expressed
Zhenkai Zhue851b952013-01-13 22:29:57 -0800206}
207
208void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800209SyncCore::handleRecoverData(const Name& name, PcoPtr content)
Zhenkai Zhue851b952013-01-13 22:29:57 -0800210{
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800211 _LOG_DEBUG("[" << m_log->GetLocalName() << "] <<<<< RECOVER DATA with name: " << name);
Alexander Afanasyevc507ac22013-01-21 16:01:58 -0800212 //cout << "handle recover data" << end;
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800213 if (content && content->contentPtr() && content->contentPtr()->size() > 0) {
214 handleStateData(*content->contentPtr());
215 }
216 else {
217 _LOG_ERROR("Got recovery DATA with empty content");
218 }
Alexander Afanasyev50526282013-01-26 13:43:57 -0800219
220 // sendSyncInterest();
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800221 m_scheduler->deleteTask(SYNC_INTEREST_TAG2);
222 Scheduler::scheduleOneTimeTask(m_scheduler, 0, bind(&SyncCore::sendSyncInterest, this),
223 SYNC_INTEREST_TAG2);
Zhenkai Zhu74dd53c2013-01-10 23:39:57 -0800224}
225
226void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800227SyncCore::handleSyncData(const Name& name, PcoPtr content)
Zhenkai Zhu74dd53c2013-01-10 23:39:57 -0800228{
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800229 _LOG_DEBUG("[" << m_log->GetLocalName() << "] <<<<< SYNC DATA with name: " << name);
Alexander Afanasyevfc720362013-01-24 21:49:48 -0800230
Zhenkai Zhue851b952013-01-13 22:29:57 -0800231 // suppress recover in interest - data out of order case
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800232 if (content && content->contentPtr() && content->contentPtr()->size() > 0) {
233 handleStateData(*content->contentPtr());
234 }
235 else {
236 _LOG_ERROR("Got sync DATA with empty content");
237 }
Zhenkai Zhue851b952013-01-13 22:29:57 -0800238
239 // resume outstanding sync interest
Alexander Afanasyev50526282013-01-26 13:43:57 -0800240 // sendSyncInterest();
241
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800242 m_scheduler->deleteTask(SYNC_INTEREST_TAG2);
243 Scheduler::scheduleOneTimeTask(m_scheduler, 0, bind(&SyncCore::sendSyncInterest, this),
244 SYNC_INTEREST_TAG2);
Zhenkai Zhue851b952013-01-13 22:29:57 -0800245}
246
247void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800248SyncCore::handleStateData(const Bytes& content)
Zhenkai Zhue851b952013-01-13 22:29:57 -0800249{
Zhenkai Zhu7c1cd8d2013-01-31 12:27:17 -0800250 SyncStateMsgPtr msg = deserializeGZipMsg<SyncStateMsg>(content);
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800251 if (!(msg)) {
Zhenkai Zhu74dd53c2013-01-10 23:39:57 -0800252 // ignore misformed SyncData
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800253 _LOG_ERROR("Misformed SyncData");
Zhenkai Zhu74dd53c2013-01-10 23:39:57 -0800254 return;
255 }
256
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800257 _LOG_TRACE(m_log->GetLocalName() << " receives Msg ");
258 _LOG_TRACE(msg);
Zhenkai Zhu74dd53c2013-01-10 23:39:57 -0800259 int size = msg->state_size();
260 int index = 0;
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800261 while (index < size) {
Zhenkai Zhu74dd53c2013-01-10 23:39:57 -0800262 SyncState state = msg->state(index);
Zhenkai Zhue851b952013-01-13 22:29:57 -0800263 string devStr = state.name();
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800264 Name deviceName((const unsigned char*)devStr.c_str(), devStr.size());
265 // cout << "Got Name: " << deviceName;
266 if (state.type() == SyncState::UPDATE) {
Zhenkai Zhue851b952013-01-13 22:29:57 -0800267 sqlite3_int64 seqno = state.seq();
Zhenkai Zhub330aed2013-01-17 13:29:37 -0800268 m_log->UpdateDeviceSeqNo(deviceName, seqno);
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800269 if (state.has_locator()) {
Zhenkai Zhue851b952013-01-13 22:29:57 -0800270 string locStr = state.locator();
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800271 Name locatorName((const unsigned char*)locStr.c_str(), locStr.size());
272 // cout << ", Got loc: " << locatorName << endl;
Zhenkai Zhub330aed2013-01-17 13:29:37 -0800273 m_log->UpdateLocator(deviceName, locatorName);
Alexander Afanasyev49a30d02013-01-21 21:38:48 -0800274
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800275 _LOG_TRACE("self: " << m_log->GetLocalName() << ", device: " << deviceName << " < == > "
276 << locatorName);
Zhenkai Zhue851b952013-01-13 22:29:57 -0800277 }
278 }
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800279 else {
280 _LOG_ERROR("Receive SYNC DELETE, but we don't support it yet");
Zhenkai Zhue851b952013-01-13 22:29:57 -0800281 deregister(deviceName);
282 }
Zhenkai Zhu74dd53c2013-01-10 23:39:57 -0800283 index++;
284 }
285
Zhenkai Zhue851b952013-01-13 22:29:57 -0800286 // find the actuall difference and invoke callback on the actual difference
287 HashPtr oldHash = m_rootHash;
Zhenkai Zhub330aed2013-01-17 13:29:37 -0800288 m_rootHash = m_log->RememberStateInStateLog();
Zhenkai Zhu085aae72013-01-17 21:09:01 -0800289 // get diff with both new SeqNo and old SeqNo
290 SyncStateMsgPtr diff = m_log->FindStateDifferences(*oldHash, *m_rootHash, true);
Zhenkai Zhu6e7d4d22013-01-15 18:18:18 -0800291
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800292 if (diff->state_size() > 0) {
293 m_stateMsgCallback(diff);
Zhenkai Zhu9501b8b2013-01-17 12:37:00 -0800294 }
Zhenkai Zhu74dd53c2013-01-10 23:39:57 -0800295}
296
297void
298SyncCore::sendSyncInterest()
299{
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800300 Name syncInterest = Name(m_syncPrefix)(m_rootHash->GetHash(), m_rootHash->GetHashBytes());
Alexander Afanasyev49a30d02013-01-21 21:38:48 -0800301
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800302 _LOG_DEBUG("[" << m_log->GetLocalName() << "] >>> SYNC Interest for " << m_rootHash->shortHash()
303 << ": "
304 << syncInterest);
Alexander Afanasyevfc720362013-01-24 21:49:48 -0800305
Zhenkai Zhu95160102013-01-25 21:54:57 -0800306 Selectors selectors;
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800307 if (m_syncInterestInterval > 0 && m_syncInterestInterval < 30.0) {
Zhenkai Zhu95160102013-01-25 21:54:57 -0800308 selectors.interestLifetime(m_syncInterestInterval);
309 }
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800310 m_ccnx->sendInterest(syncInterest,
311 Closure(boost::bind(&SyncCore::handleSyncData, this, _1, _2),
312 boost::bind(&SyncCore::handleSyncInterestTimeout, this, _1, _2, _3)),
313 selectors);
Zhenkai Zhu3b406592013-01-25 21:07:49 -0800314
Zhenkai Zhu95160102013-01-25 21:54:57 -0800315 // if there is a pending syncSyncInterest task, reschedule it to be m_syncInterestInterval seconds from now
Zhenkai Zhu3b406592013-01-25 21:07:49 -0800316 // if no such task exists, it will be added
Zhenkai Zhu3b406592013-01-25 21:07:49 -0800317 m_scheduler->rescheduleTask(m_sendSyncInterestTask);
Zhenkai Zhue851b952013-01-13 22:29:57 -0800318}
319
320void
Alexander Afanasyev50526282013-01-26 13:43:57 -0800321SyncCore::recover(HashPtr hash)
Zhenkai Zhue851b952013-01-13 22:29:57 -0800322{
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800323 if (!(*hash == *m_rootHash) && m_log->LookupSyncLog(*hash) <= 0) {
324 _LOG_TRACE(m_log->GetLocalName() << ", Recover for: " << hash->shortHash());
Zhenkai Zhue851b952013-01-13 22:29:57 -0800325 // unfortunately we still don't recognize this hash
326 Bytes bytes;
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800327 readRaw(bytes, (const unsigned char*)hash->GetHash(), hash->GetHashBytes());
Alexander Afanasyev49a30d02013-01-21 21:38:48 -0800328
Zhenkai Zhue851b952013-01-13 22:29:57 -0800329 // append the unknown hash
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800330 Name recoverInterest = Name(m_syncPrefix)(RECOVER)(bytes);
Alexander Afanasyev49a30d02013-01-21 21:38:48 -0800331
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800332 _LOG_DEBUG("[" << m_log->GetLocalName() << "] >>> RECOVER Interests for " << hash->shortHash());
Alexander Afanasyevfc720362013-01-24 21:49:48 -0800333
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800334 m_ccnx->sendInterest(recoverInterest,
335 Closure(boost::bind(&SyncCore::handleRecoverData, this, _1, _2),
336 boost::bind(&SyncCore::handleRecoverInterestTimeout, this, _1, _2,
337 _3)));
Zhenkai Zhue851b952013-01-13 22:29:57 -0800338 }
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800339 else {
Zhenkai Zhue851b952013-01-13 22:29:57 -0800340 // we already learned the hash; cheers!
341 }
342}
343
344void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800345SyncCore::deregister(const Name& name)
Zhenkai Zhue851b952013-01-13 22:29:57 -0800346{
347 // Do nothing for now
348 // TODO: handle deregistering
Zhenkai Zhu74dd53c2013-01-10 23:39:57 -0800349}
350
Zhenkai Zhu9501b8b2013-01-17 12:37:00 -0800351sqlite3_int64
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800352SyncCore::seq(const Name& name)
Zhenkai Zhu9501b8b2013-01-17 12:37:00 -0800353{
Zhenkai Zhub330aed2013-01-17 13:29:37 -0800354 return m_log->SeqNo(name);
Zhenkai Zhu9501b8b2013-01-17 12:37:00 -0800355}