blob: 2b43c624abd284326c89bfa39edd8be8fe51c9d6 [file] [log] [blame]
Alexander Afanasyev8811b352013-01-02 12:51:15 -08001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2012 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
19 * Zhenkai Zhu <zhenkai@cs.ucla.edu>
20 */
21
Alexander Afanasyev49a18522013-01-18 17:49:04 -080022#include "fetch-manager.h"
23#include <boost/make_shared.hpp>
24#include <boost/ref.hpp>
25#include <boost/throw_exception.hpp>
26
27using namespace boost;
28using namespace std;
29using namespace Ccnx;
30
Alexander Afanasyev83531a42013-01-19 16:21:54 -080031//The disposer object function
32struct fetcher_disposer { void operator() (Fetcher *delete_this) { delete delete_this; } };
33
34FetchManager::FetchManager (CcnxWrapperPtr ccnx, SyncLogPtr sync, uint32_t parallelFetches/* = 3*/)
Alexander Afanasyev49a18522013-01-18 17:49:04 -080035 : m_ccnx (ccnx)
36 , m_sync (sync)
Alexander Afanasyev83531a42013-01-19 16:21:54 -080037 , m_maxParallelFetches (parallelFetches)
38 , m_currentParallelFetches (0)
39
Alexander Afanasyev8811b352013-01-02 12:51:15 -080040{
Alexander Afanasyeve41e7d22013-01-19 15:13:47 -080041 m_scheduler = make_shared<Scheduler> ();
42 m_scheduler->start ();
Alexander Afanasyev49a18522013-01-18 17:49:04 -080043}
Alexander Afanasyeva199f972013-01-02 19:37:26 -080044
Alexander Afanasyev49a18522013-01-18 17:49:04 -080045FetchManager::~FetchManager ()
46{
Alexander Afanasyev83531a42013-01-19 16:21:54 -080047 m_fetchList.clear_and_dispose (fetcher_disposer ());
48
Alexander Afanasyeve41e7d22013-01-19 15:13:47 -080049 m_scheduler->shutdown ();
50 m_scheduler.reset ();
Alexander Afanasyev49a18522013-01-18 17:49:04 -080051}
Alexander Afanasyev8811b352013-01-02 12:51:15 -080052
Alexander Afanasyev49a18522013-01-18 17:49:04 -080053void
54FetchManager::Enqueue (const Ccnx::Name &deviceName, uint32_t minSeqNo, uint32_t maxSeqNo, int priority/*=PRIORITY_NORMAL*/)
55{
Alexander Afanasyev83531a42013-01-19 16:21:54 -080056 // we may need to guarantee that LookupLocator will gives an answer and not throw exception...
57 Name forwardingHint = m_sync->LookupLocator (deviceName);
58 Fetcher &fetcher = *(new Fetcher (*this, deviceName, minSeqNo, maxSeqNo, forwardingHint));
59
60 switch (priority)
61 {
62 case PRIORITY_HIGH:
63 m_fetchList.push_front (fetcher);
64 break;
65
66 case PRIORITY_NORMAL:
67 default:
68 m_fetchList.push_back (fetcher);
69 break;
70 }
71
72 ScheduleFetches (); // will start a fetch if m_currentParallelFetches is less than max, otherwise does nothing
Alexander Afanasyev49a18522013-01-18 17:49:04 -080073}
Alexander Afanasyeve41e7d22013-01-19 15:13:47 -080074
Alexander Afanasyev83531a42013-01-19 16:21:54 -080075void
76FetchManager::ScheduleFetches ()
Alexander Afanasyeve41e7d22013-01-19 15:13:47 -080077{
Alexander Afanasyev83531a42013-01-19 16:21:54 -080078 unique_lock<mutex> lock (m_parellelFetchMutex);
79
80 for (FetchList::iterator item = m_fetchList.begin ();
81 m_currentParallelFetches < m_maxParallelFetches && item != m_fetchList.end ();
82 item++)
83 {
84 if (item->m_active)
85 continue;
86
87 m_currentParallelFetches ++;
88 item->RestartPipeline ();
89 }
Alexander Afanasyeve41e7d22013-01-19 15:13:47 -080090}
91
Alexander Afanasyev83531a42013-01-19 16:21:54 -080092void
Alexander Afanasyevd6c2a902013-01-19 21:24:30 -080093FetchManager::DidNoDataTimeout (Fetcher &fetcher)
Alexander Afanasyeve41e7d22013-01-19 15:13:47 -080094{
Alexander Afanasyev83531a42013-01-19 16:21:54 -080095 fetcher.m_forwardingHint = Ccnx::Name ("/ndn/broadcast");
96 fetcher.m_active = false;
97 {
98 unique_lock<mutex> lock (m_parellelFetchMutex);
99 m_currentParallelFetches --;
100 // no need to do anything with the m_fetchList
101 }
Alexander Afanasyevd6c2a902013-01-19 21:24:30 -0800102
Alexander Afanasyev83531a42013-01-19 16:21:54 -0800103 ScheduleFetches ();
104}
105
106void
Alexander Afanasyevd6c2a902013-01-19 21:24:30 -0800107FetchManager::DidFetchComplete (Fetcher &fetcher)
Alexander Afanasyev83531a42013-01-19 16:21:54 -0800108{
Alexander Afanasyev83531a42013-01-19 16:21:54 -0800109 {
110 unique_lock<mutex> lock (m_parellelFetchMutex);
111 m_currentParallelFetches --;
112 m_fetchList.erase_and_dispose (FetchList::s_iterator_to (fetcher), fetcher_disposer ());
113 }
Alexander Afanasyevd6c2a902013-01-19 21:24:30 -0800114
Alexander Afanasyev83531a42013-01-19 16:21:54 -0800115 // ? do something else
Alexander Afanasyeve41e7d22013-01-19 15:13:47 -0800116}