Merge with branch 'simulation'
diff --git a/model/sync-app-data-fetch.cc b/model/sync-app-data-fetch.cc
deleted file mode 100644
index 5cfabce..0000000
--- a/model/sync-app-data-fetch.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2012 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
- * Chaoyi Bian <bcy@pku.edu.cn>
- * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- */
-
-#include "sync-app-data-fetch.h"
-#include "sync-log.h"
-
-using namespace std;
-using namespace boost;
-
-namespace Sync
-{
-
-INIT_LOGGER ("AppDataFetch");
-
-void
-AppDataFetch::onUpdate (const std::string &prefix, const SeqNo &newSeq, const SeqNo &oldSeq)
-{
- _LOG_FUNCTION (this << ", " << prefix << ", " << newSeq << ", " << oldSeq);
-
- // sequence number logic here
- uint32_t start = 0;
- if (oldSeq.isValid () && oldSeq.getSession() == newSeq.getSession())
- {
- start = oldSeq.getSeq () + 1;
- }
- uint32_t end = newSeq.getSeq ();
-
- //
- // add logic for wrap around
- //
-
- for (uint32_t i = start; i <= end; i++)
- {
- ostringstream interestName;
- interestName << prefix << "/" << newSeq.getSession () << "/" << i;
- m_ccnxHandle->sendInterest (interestName.str (), m_dataCallback);
- }
-}
-
-void
-AppDataFetch::onRemove (const std::string &prefix)
-{
- _LOG_FUNCTION (this << ", " << prefix);
-
- // I guess this should be somewhere in app
-}
-
-}
diff --git a/model/sync-app-data-fetch.h b/model/sync-app-data-fetch.h
deleted file mode 100644
index 1e42860..0000000
--- a/model/sync-app-data-fetch.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2012 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
- * Chaoyi Bian <bcy@pku.edu.cn>
- * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- */
-
-#ifndef SYNC_APP_DATA_FETCH_H
-#define SYNC_APP_DATA_FETCH_H
-
-#include "sync-ccnx-wrapper.h"
-#include "sync-seq-no.h"
-
-namespace Sync {
-
-/**
- * \ingroup sync
- * @brief fetch application data, by default it will try to fetch every piece
- * of data
- */
-class AppDataFetch
-{
-public:
- /**
- * @brief Constructor
- * @param ccnxHandle handle for CCNx
- * @param dataCallback the callback function to process data
- */
- AppDataFetch (CcnxWrapperPtr ccnxHandle,
- CcnxWrapper::DataCallback dataCallback)
- : m_ccnxHandle (ccnxHandle)
- , m_dataCallback (dataCallback)
- { }
-
- /**
- * @brief Set data callback
- * @param dataCallback the callback function to process data
- */
- void
- setDataCallback(CcnxWrapper::DataCallback dataCallback)
- {
- m_dataCallback = dataCallback;
- }
-
- /**
- * @brief Fired from SyncLogic when new data is available
- *
- * @param prefix the prefix for the data
- * @param newSeq old session ID/sequence number
- * @param oldSeq new session ID/sequence number
- */
- void
- onUpdate (const std::string &prefix, const SeqNo &newSeq, const SeqNo &oldSeq);
-
- /**
- * @brief Fired from SyncLogic when data is removed
- *
- * @param prefix the prefix for the data
- */
- void
- onRemove (const std::string &prefix);
-
-private:
- CcnxWrapperPtr m_ccnxHandle;
- CcnxWrapper::DataCallback m_dataCallback;
-};
-
-
-} // Sync
-
-#endif // SYNC_APP_DATA_FETCH_H
diff --git a/model/sync-app-data-publish.cc b/model/sync-app-data-publish.cc
deleted file mode 100644
index e7bee97..0000000
--- a/model/sync-app-data-publish.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2012 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
- * Chaoyi Bian <bcy@pku.edu.cn>
- * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- */
-
-#include "sync-app-data-publish.h"
-#include <boost/throw_exception.hpp>
-typedef boost::error_info<struct tag_errmsg, std::string> errmsg_info_str;
-typedef boost::error_info<struct tag_errmsg, int> errmsg_info_int;
-
-using namespace std;
-using namespace boost;
-
-namespace Sync
-{
-
-
-string
-AppDataPublish::getRecentData (const string &prefix, uint32_t session)
-{
- if (m_recentData.find(make_pair(prefix, session)) != m_recentData.end())
- return m_recentData[make_pair(prefix, session)];
- else
- return "";
-}
-
-uint32_t
-AppDataPublish::getNextSeq (const string &prefix, uint32_t session)
-{
- SequenceLog::iterator i = m_sequenceLog.find (prefix);
-
- if (i != m_sequenceLog.end ())
- {
- Seq s = i->second;
- if (s.session == session)
- return s.seq;
- }
- return 0;
-}
-
-uint32_t
-AppDataPublish::publishData (const string &name, uint32_t session, const string &dataBuffer, int freshness)
-{
- uint32_t seq = getNextSeq (name, session);
-
- ostringstream contentNameWithSeqno;
- contentNameWithSeqno << name << "/" << session << "/" << seq;
-
- m_ccnxHandle->publishData (contentNameWithSeqno.str (), dataBuffer, freshness);
-
- Seq s;
- s.session = session;
- s.seq = seq + 1;
- m_sequenceLog[name] = s;
-
- unordered_map<pair<string, uint32_t>, string>::iterator it = m_recentData.find(make_pair(name, session));
- if (it != m_recentData.end())
- m_recentData.erase(it);
- m_recentData.insert(make_pair(make_pair(name, session), dataBuffer));
-
- return seq;
-}
-
-} // Sync
diff --git a/model/sync-app-data-publish.h b/model/sync-app-data-publish.h
deleted file mode 100644
index ec95a60..0000000
--- a/model/sync-app-data-publish.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2012 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
- * Chaoyi Bian <bcy@pku.edu.cn>
- * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- */
-
-#ifndef SYNC_APP_DATA_PUBLISH_H
-#define SYNC_APP_DATA_PUBLISH_H
-
-#include <boost/unordered_map.hpp>
-#include "sync-seq-no.h"
-#include "sync-ccnx-wrapper.h"
-#include <utility>
-#include <map>
-
-namespace Sync {
-
-struct Seq
-{
- uint32_t session;
- uint32_t seq;
-};
-
-struct GetSeqException : virtual boost::exception, virtual std::exception { };
-
-/**
- * \ingroup sync
- * @brief publishes application data using incrementing sequence number (for
- * each sequence namber and keeps track of most recently published data for
- * each name prefix
- */
-class AppDataPublish
-{
-public:
- AppDataPublish (CcnxWrapperPtr ccnxHandle)
- : m_ccnxHandle (ccnxHandle)
- { }
-
- /**
- * @brief get the name (including sequence number) and the content
- * (unencoded, just XML stanza) of the most recent published data
- *
- * @param prefix the name prefix to look for
- * @param session session
- * @return the pair of name and content
- */
- std::string
- getRecentData (const std::string &prefix, uint32_t session);
-
- /**
- * @brief get the most recent sequence number for a name prefix
- * @param prefix the name prefix to look for
- * @param session session
- */
- uint32_t
- getNextSeq (const std::string &prefix, uint32_t session);
-
- /**
- * @brief publish data for a name prefix, updates the corresponding
- * sequence number and recent data
- *
- * @param name data prefix
- * @param session session to which data is published
- * @param dataBuffer the data itself
- * @param freshness the freshness for the data object
- * @return published sequence number, will throw an exception if something wrong happened
- */
- uint32_t publishData (const std::string &name, uint32_t session, const std::string &dataBuffer, int freshness);
-
-private:
- typedef boost::unordered_map<std::string, Seq> SequenceLog;
- typedef boost::unordered_map<std::pair<std::string, uint32_t>, std::string> RecentData;
-
- CcnxWrapperPtr m_ccnxHandle;
- SequenceLog m_sequenceLog;
- RecentData m_recentData;
-};
-
-} // Sync
-
-#endif // SYNC_APP_DATA_PUBLISH_H
diff --git a/model/sync-app-socket-c.cc b/model/sync-app-socket-c.cc
deleted file mode 100644
index 4bdf384..0000000
--- a/model/sync-app-socket-c.cc
+++ /dev/null
@@ -1,74 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2012 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
- * Chaoyi Bian <bcy@pku.edu.cn>
- * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- */
-
-#include "sync-app-socket.h"
-using namespace std;
-using namespace Sync;
-
-class CallbackHolder{
-private:
- void (*m_callback)(const char *, const char *);
-
-public:
- CallbackHolder(void (*callback)(const char*, const char*)):m_callback(callback){};
- void callbackWrapper(string name, string data) {
- m_callback(name.c_str(), data.c_str());
- }
-};
-
-struct SyncAppSocketStruct;
-
-extern "C"
-SyncAppSocketStruct *
-create_sync_app_socket(const char *prefix, void (*callback)(const char *, const char *))
-{
- CallbackHolder *holder = new CallbackHolder(callback);
- boost::function<void (string, string)> cb = bind(&CallbackHolder::callbackWrapper, holder, _1, _2);
- SyncAppSocket *sock = new SyncAppSocket(prefix, cb);
- return (SyncAppSocketStruct *) sock;
-}
-
-extern "C"
-void
-delete_sync_app_socket(SyncAppSocketStruct **sock) {
- SyncAppSocket *temp = *((SyncAppSocket **)sock);
- delete temp;
- temp = NULL;
-}
-
-// assume char *buf ends with '\0', or otherwise it's going to crash;
-// should fix this "feature"
-extern "C"
-int
-sync_app_socket_publish(SyncAppSocketStruct *sock, const char *prefix, int session, const char *buf, int freshness)
-{
- SyncAppSocket *temp = (SyncAppSocket *)sock;
- return temp->publish(prefix, session, buf, freshness);
-}
-
-extern "C"
-void
-sync_app_socket_remove(SyncAppSocketStruct *sock, const char *prefix)
-{
- SyncAppSocket *temp = (SyncAppSocket *)sock;
- temp->remove(prefix);
-}
diff --git a/model/sync-app-socket.cc b/model/sync-app-socket.cc
deleted file mode 100644
index 848a6d0..0000000
--- a/model/sync-app-socket.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2012 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
- * Chaoyi Bian <bcy@pku.edu.cn>
- * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- */
-
-#include "sync-app-socket.h"
-
-using namespace std;
-using namespace boost;
-
-namespace Sync
-{
-
-SyncAppSocket::SyncAppSocket (const string &syncPrefix, CcnxWrapper::DataCallback dataCallback)
- : m_appHandle (new CcnxWrapper())
- , m_fetcher (m_appHandle, dataCallback)
- , m_publisher (m_appHandle)
- , m_syncLogic (syncPrefix,
- bind (&AppDataFetch::onUpdate, m_fetcher, _1, _2, _3),
- bind (&AppDataFetch::onRemove, m_fetcher, _1))
-{
-}
-
-SyncAppSocket::~SyncAppSocket()
-{
-}
-
-bool SyncAppSocket::publish (const string &prefix, uint32_t session, const string &dataBuffer, int freshness)
-{
- uint32_t sequence = m_publisher.publishData (prefix, session, dataBuffer, freshness);
- m_syncLogic.addLocalNames (prefix, session, sequence);
-}
-
-}
diff --git a/model/sync-app-socket.h b/model/sync-app-socket.h
deleted file mode 100644
index d17857c..0000000
--- a/model/sync-app-socket.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2012 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
- * Chaoyi Bian <bcy@pku.edu.cn>
- * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- */
-
-#ifndef SYNC_APP_SOCKET_H
-#define SYNC_APP_SOCKET_H
-
-#include "sync-logic.h"
-#include "sync-app-data-fetch.h"
-#include "sync-app-data-publish.h"
-#include <boost/function.hpp>
-
-namespace Sync {
-
-/**
- * \ingroup sync
- * @brief A simple interface to interact with client code
- */
-class SyncAppSocket
-{
-public:
- /**
- * @brief the constructor for SyncAppSocket; the parameter syncPrefix
- * should be passed to the constructor of m_syncAppWrapper; the other
- * parameter should be passed to the constructor of m_fetcher; furthermore,
- * the fetch function of m_fetcher should be a second paramter passed to
- * the constructor of m_syncAppWrapper, so that m_syncAppWrapper can tell
- * m_fetcher to fetch the actual app data after it learns the names
- *
- * @param syncPrefix the name prefix for Sync Interest
- * @param dataCallback the callback to process data
- */
- SyncAppSocket (const std::string &syncPrefix, CcnxWrapper::DataCallback dataCallback);
- ~SyncAppSocket ();
-
- /**
- * @brief publish data from local client and tell SyncLogic to update
- * the sync tree by adding the local names
- *
- * @param prefix the name prefix for the data
- * @param session session to which data is published
- * @param dataBuffer the data itself
- * @param freshness the freshness time for the data (in seconds)
- */
- bool publish (const std::string &prefix, uint32_t session, const std::string &dataBuffer, int freshness);
-
- /**
- * @brief delete a participant's subtree from the sync tree; SyncLogic will do the work
- * this is just a wrapper
- *
- * @param prefix the prefix for the participant
- */
- void remove (const std::string &prefix) {m_syncLogic.remove(prefix);}
-
-private:
- CcnxWrapperPtr m_appHandle;
-
- AppDataFetch m_fetcher;
- AppDataPublish m_publisher;
- SyncLogic m_syncLogic;
-};
-
-} // Sync
-
-#endif // SYNC_APP_SOCKET_H
diff --git a/model/sync-ccnx-wrapper.cc b/model/sync-ccnx-wrapper.cc
deleted file mode 100644
index ea0f876..0000000
--- a/model/sync-ccnx-wrapper.cc
+++ /dev/null
@@ -1,336 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2012 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
- * Chaoyi Bian <bcy@pku.edu.cn>
- * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- */
-
-#include "sync-ccnx-wrapper.h"
-#include "sync-log.h"
-#include <poll.h>
-#include <boost/throw_exception.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
-
-typedef boost::error_info<struct tag_errmsg, std::string> errmsg_info_str;
-typedef boost::error_info<struct tag_errmsg, int> errmsg_info_int;
-
-using namespace std;
-using namespace boost;
-
-INIT_LOGGER ("CcnxWrapper");
-
-namespace Sync {
-
-#ifdef _DEBUG_WRAPPER_
-CcnxWrapper::CcnxWrapper(char c)
-#else
-CcnxWrapper::CcnxWrapper()
-#endif
- : m_handle (0)
- , m_keyStore (0)
- , m_keyLoactor (0)
- , m_running (true)
-{
-#ifdef _DEBUG_WRAPPER_
- m_c = c;
-#endif
- m_handle = ccn_create ();
- initKeyStore ();
- createKeyLocator ();
- if (ccn_connect(m_handle, NULL) < 0)
- BOOST_THROW_EXCEPTION (CcnxOperationException() << errmsg_info_str("connection to ccnd failed"));
- m_thread = thread (&CcnxWrapper::ccnLoop, this);
-}
-
-CcnxWrapper::~CcnxWrapper()
-{
- // std::cout << "CcnxWrapper::~CcnxWrapper()" << std::endl;
- {
- recursive_mutex::scoped_lock lock(m_mutex);
- m_running = false;
- }
-
- m_thread.join ();
- ccn_disconnect (m_handle);
- ccn_destroy (&m_handle);
- ccn_charbuf_destroy (&m_keyLoactor);
- ccn_keystore_destroy (&m_keyStore);
-}
-
-/// @cond include_hidden
-
-void
-CcnxWrapper::createKeyLocator ()
-{
- m_keyLoactor = ccn_charbuf_create();
- ccn_charbuf_append_tt (m_keyLoactor, CCN_DTAG_KeyLocator, CCN_DTAG);
- ccn_charbuf_append_tt (m_keyLoactor, CCN_DTAG_Key, CCN_DTAG);
- int res = ccn_append_pubkey_blob (m_keyLoactor, ccn_keystore_public_key(m_keyStore));
- if (res >= 0)
- {
- ccn_charbuf_append_closer (m_keyLoactor); /* </Key> */
- ccn_charbuf_append_closer (m_keyLoactor); /* </KeyLocator> */
- }
-}
-
-const ccn_pkey*
-CcnxWrapper::getPrivateKey ()
-{
- return ccn_keystore_private_key (m_keyStore);
-}
-
-const unsigned char*
-CcnxWrapper::getPublicKeyDigest ()
-{
- return ccn_keystore_public_key_digest(m_keyStore);
-}
-
-ssize_t
-CcnxWrapper::getPublicKeyDigestLength ()
-{
- return ccn_keystore_public_key_digest_length(m_keyStore);
-}
-
-void
-CcnxWrapper::initKeyStore ()
-{
- m_keyStore = ccn_keystore_create ();
- string keyStoreFile = string(getenv("HOME")) + string("/.ccnx/.ccnx_keystore");
- if (ccn_keystore_init (m_keyStore, (char *)keyStoreFile.c_str(), (char*)"Th1s1sn0t8g00dp8ssw0rd.") < 0)
- BOOST_THROW_EXCEPTION(CcnxOperationException() << errmsg_info_str(keyStoreFile.c_str()));
-}
-
-void
-CcnxWrapper::ccnLoop ()
-{
- _LOG_FUNCTION (this);
-
- while (m_running)
- {
-#ifdef _DEBUG_WRAPPER_
- std::cout << m_c << flush;
-#endif
- int res = 0;
- {
- recursive_mutex::scoped_lock lock (m_mutex);
- res = ccn_run (m_handle, 0);
-
- }
-
- if (!m_running) break;
-
- if (res < 0)
- BOOST_THROW_EXCEPTION (CcnxOperationException()
- << errmsg_info_str("ccn_run returned error"));
-
-
- pollfd pfds[1];
- {
- recursive_mutex::scoped_lock lock (m_mutex);
-
- pfds[0].fd = ccn_get_connection_fd (m_handle);
- pfds[0].events = POLLIN;
- if (ccn_output_is_pending (m_handle))
- pfds[0].events |= POLLOUT;
- }
-
- int ret = poll (pfds, 1, 1);
- if (ret < 0)
- {
- BOOST_THROW_EXCEPTION (CcnxOperationException() << errmsg_info_str("ccnd socket failed (probably ccnd got stopped)"));
- }
- }
-}
-
-/// @endcond
-
-int
-CcnxWrapper::publishData (const string &name, const string &dataBuffer, int freshness)
-{
- recursive_mutex::scoped_lock lock(m_mutex);
- if (!m_running)
- return -1;
-
- // cout << "Publish: " << name << endl;
- ccn_charbuf *pname = ccn_charbuf_create();
- ccn_charbuf *signed_info = ccn_charbuf_create();
- ccn_charbuf *content = ccn_charbuf_create();
-
- ccn_name_from_uri(pname, name.c_str());
- ccn_signed_info_create(signed_info,
- getPublicKeyDigest(),
- getPublicKeyDigestLength(),
- NULL,
- CCN_CONTENT_DATA,
- freshness,
- NULL,
- m_keyLoactor);
- if(ccn_encode_ContentObject(content, pname, signed_info,
- dataBuffer.c_str(), dataBuffer.length (),
- NULL, getPrivateKey()) < 0)
- BOOST_THROW_EXCEPTION(CcnxOperationException() << errmsg_info_str("encode content failed"));
-
- if (ccn_put(m_handle, content->buf, content->length) < 0)
- BOOST_THROW_EXCEPTION(CcnxOperationException() << errmsg_info_str("ccnput failed"));
-
- ccn_charbuf_destroy (&pname);
- ccn_charbuf_destroy (&signed_info);
- ccn_charbuf_destroy (&content);
- return 0;
-}
-
-
-static ccn_upcall_res
-incomingInterest(ccn_closure *selfp,
- ccn_upcall_kind kind,
- ccn_upcall_info *info)
-{
- CcnxWrapper::InterestCallback *f = static_cast<CcnxWrapper::InterestCallback*> (selfp->data);
-
- switch (kind)
- {
- case CCN_UPCALL_FINAL: // effective in unit tests
- delete f;
- delete selfp;
- return CCN_UPCALL_RESULT_OK;
-
- case CCN_UPCALL_INTEREST:
- break;
-
- default:
- return CCN_UPCALL_RESULT_OK;
- }
-
- string interest;
- for (int i = 0; i < info->interest_comps->n - 1; i++)
- {
- char *comp;
- size_t size;
- interest += "/";
- ccn_name_comp_get(info->interest_ccnb, info->interest_comps, i, (const unsigned char **)&comp, &size);
- string compStr(comp, size);
- interest += compStr;
- }
- (*f) (interest);
- return CCN_UPCALL_RESULT_OK;
-}
-
-static ccn_upcall_res
-incomingData(ccn_closure *selfp,
- ccn_upcall_kind kind,
- ccn_upcall_info *info)
-{
- CcnxWrapper::DataCallback *f = static_cast<CcnxWrapper::DataCallback*> (selfp->data);
-
- switch (kind)
- {
- case CCN_UPCALL_FINAL: // effecitve in unit tests
- delete f;
- delete selfp;
- return CCN_UPCALL_RESULT_OK;
-
- case CCN_UPCALL_CONTENT:
- break;
-
- default:
- return CCN_UPCALL_RESULT_OK;
- }
-
- char *pcontent;
- size_t len;
- if (ccn_content_get_value(info->content_ccnb, info->pco->offset[CCN_PCO_E], info->pco, (const unsigned char **)&pcontent, &len) < 0)
- BOOST_THROW_EXCEPTION(CcnxOperationException() << errmsg_info_str("decode ContentObject failed"));
- string content(pcontent, len);
-
- string name;
- for (int i = 0; i < info->content_comps->n - 1; i++)
- {
- char *comp;
- size_t size;
- name += "/";
- ccn_name_comp_get(info->content_ccnb, info->content_comps, i, (const unsigned char **)&comp, &size);
- string compStr(comp, size);
- name += compStr;
- }
- (*f) (name, content);
- return CCN_UPCALL_RESULT_OK;
-}
-
-int CcnxWrapper::sendInterest (const string &strInterest, const DataCallback &dataCallback)
-{
- recursive_mutex::scoped_lock lock(m_mutex);
- if (!m_running)
- return -1;
-
- // std::cout << "Send interests for " << strInterest << std::endl;
- ccn_charbuf *pname = ccn_charbuf_create();
- ccn_closure *dataClosure = new ccn_closure;
-
- ccn_name_from_uri (pname, strInterest.c_str());
- dataClosure->data = new DataCallback (dataCallback); // should be removed when closure is removed
-
- dataClosure->p = &incomingData;
- if (ccn_express_interest (m_handle, pname, dataClosure, NULL) < 0)
- BOOST_THROW_EXCEPTION(CcnxOperationException() << errmsg_info_str("express interest failed"));
-
- ccn_charbuf_destroy (&pname);
- return 0;
-}
-
-int CcnxWrapper::setInterestFilter (const string &prefix, const InterestCallback &interestCallback)
-{
- recursive_mutex::scoped_lock lock(m_mutex);
- if (!m_running)
- return -1;
-
- ccn_charbuf *pname = ccn_charbuf_create();
- ccn_closure *interestClosure = new ccn_closure;
-
- ccn_name_from_uri (pname, prefix.c_str());
- interestClosure->data = new InterestCallback (interestCallback); // should be removed when closure is removed
- interestClosure->p = &incomingInterest;
- int ret = ccn_set_interest_filter (m_handle, pname, interestClosure);
- if (ret < 0)
- {
- BOOST_THROW_EXCEPTION(CcnxOperationException() << errmsg_info_str("set interest filter failed") << errmsg_info_int (ret));
- }
-
- ccn_charbuf_destroy(&pname);
-}
-
-void
-CcnxWrapper::clearInterestFilter (const std::string &prefix)
-{
- recursive_mutex::scoped_lock lock(m_mutex);
- if (!m_running)
- return;
-
- std::cout << "clearInterestFilter" << std::endl;
- ccn_charbuf *pname = ccn_charbuf_create();
-
- ccn_name_from_uri (pname, prefix.c_str());
- int ret = ccn_set_interest_filter (m_handle, pname, 0);
- if (ret < 0)
- {
- BOOST_THROW_EXCEPTION(CcnxOperationException() << errmsg_info_str("set interest filter failed") << errmsg_info_int (ret));
- }
-
- ccn_charbuf_destroy(&pname);
-}
-
-}
diff --git a/model/sync-ccnx-wrapper.h b/model/sync-ccnx-wrapper.h
deleted file mode 100644
index 0ccbec4..0000000
--- a/model/sync-ccnx-wrapper.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2012 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
- * Chaoyi Bian <bcy@pku.edu.cn>
- * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- */
-
-#ifndef SYNC_CCNX_WRAPPER_H
-#define SYNC_CCNX_WRAPPER_H
-
-extern "C" {
-#include <ccn/ccn.h>
-#include <ccn/charbuf.h>
-#include <ccn/keystore.h>
-#include <ccn/uri.h>
-#include <ccn/bloom.h>
-#include <ccn/signing.h>
-}
-
-#include <boost/exception/all.hpp>
-#include <boost/thread/recursive_mutex.hpp>
-#include <boost/thread/thread.hpp>
-#include <boost/function.hpp>
-#include <string>
-
-/**
- * \defgroup sync SYNC protocol
- *
- * Implementation of SYNC protocol
- */
-namespace Sync {
-
-struct CcnxOperationException : virtual boost::exception, virtual std::exception { };
-/**
- * \ingroup sync
- * @brief A wrapper for ccnx library; clients of this code do not need to deal
- * with ccnx library
- */
-class CcnxWrapper {
-public:
- typedef boost::function<void (std::string, std::string)> DataCallback;
- typedef boost::function<void (std::string)> InterestCallback;
-
- /**
- * @brief initialize the wrapper; a lot of things needs to be done. 1) init
- * keystore 2) init keylocator 3) start a thread to hold a loop of ccn_run
- *
- */
-#ifdef _DEBUG_WRAPPER_
- CcnxWrapper(char c='.');
- char m_c;
-#else
- CcnxWrapper();
-#endif
- ~CcnxWrapper();
-
- /**
- * @brief send Interest; need to grab lock m_mutex first
- *
- * @param strInterest the Interest name
- * @param dataCallback the callback function to deal with the returned data
- * @return the return code of ccn_express_interest
- */
- int
- sendInterest (const std::string &strInterest, const DataCallback &dataCallback);
-
- /**
- * @brief set Interest filter (specify what interest you want to receive)
- *
- * @param prefix the prefix of Interest
- * @param interestCallback the callback function to deal with the returned data
- * @return the return code of ccn_set_interest_filter
- */
- int
- setInterestFilter (const std::string &prefix, const InterestCallback &interestCallback);
-
- /**
- * @brief clear Interest filter
- * @param prefix the prefix of Interest
- */
- void
- clearInterestFilter (const std::string &prefix);
-
- /**
- * @brief publish data and put it to local ccn content store; need to grab
- * lock m_mutex first
- *
- * @param name the name for the data object
- * @param dataBuffer the data to be published
- * @param freshness the freshness time for the data object
- * @return code generated by ccnx library calls, >0 if success
- */
- int
- publishData (const std::string &name, const std::string &dataBuffer, int freshness);
-
-private:
- /// @cond include_hidden
- void
- createKeyLocator ();
-
- void
- initKeyStore ();
-
- const ccn_pkey *
- getPrivateKey ();
-
- const unsigned char *
- getPublicKeyDigest ();
-
- ssize_t
- getPublicKeyDigestLength ();
-
- void
- ccnLoop ();
- /// @endcond
-private:
- ccn* m_handle;
- ccn_keystore *m_keyStore;
- ccn_charbuf *m_keyLoactor;
- // to lock, use "boost::recursive_mutex::scoped_lock scoped_lock(mutex);
- boost::recursive_mutex m_mutex;
- boost::thread m_thread;
- bool m_running;
-};
-
-typedef boost::shared_ptr<CcnxWrapper> CcnxWrapperPtr;
-
-} // Sync
-
-#endif // SYNC_CCNX_WRAPPER_H
diff --git a/model/sync-diff-state-container.h b/model/sync-diff-state-container.h
index 6e98aa4..2ae7c59 100644
--- a/model/sync-diff-state-container.h
+++ b/model/sync-diff-state-container.h
@@ -33,36 +33,16 @@
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
// #include <boost/multi_index/random_access_index.hpp>
-// #include <boost/multi_index/member.hpp>
+#include <boost/multi_index/member.hpp>
#include <boost/multi_index/mem_fun.hpp>
namespace mi = boost::multi_index;
namespace Sync {
-struct DigestPtrHash : public std::unary_function<Digest, std::size_t>
-{
- std::size_t
- operator() (DigestConstPtr digest) const
- {
- // std::cout << "digest->getHash: " << digest->getHash () << " (" << *digest << ")" << std::endl;
- return digest->getHash ();
- }
-};
-
-struct DigestPtrEqual : public std::unary_function<Digest, std::size_t>
-{
- bool
- operator() (DigestConstPtr digest1, DigestConstPtr digest2) const
- {
- // std::cout << boost::cref(*digest1) << " == " << boost::cref(*digest2) << " : " << (*digest1 == *digest2) << std::endl;
- return *digest1 == *digest2;
- }
-};
-
-
/// @cond include_hidden
struct sequenced { };
+struct timed { };
/// @endcond
/**
diff --git a/model/sync-digest.h b/model/sync-digest.h
index 8982019..97d2fd4 100644
--- a/model/sync-digest.h
+++ b/model/sync-digest.h
@@ -173,6 +173,26 @@
// return *this;
// }
+struct DigestPtrHash : public std::unary_function<Digest, std::size_t>
+{
+ std::size_t
+ operator() (DigestConstPtr digest) const
+ {
+ // std::cout << "digest->getHash: " << digest->getHash () << " (" << *digest << ")" << std::endl;
+ return digest->getHash ();
+ }
+};
+
+struct DigestPtrEqual : public std::unary_function<Digest, std::size_t>
+{
+ bool
+ operator() (DigestConstPtr digest1, DigestConstPtr digest2) const
+ {
+ // std::cout << boost::cref(*digest1) << " == " << boost::cref(*digest2) << " : " << (*digest1 == *digest2) << std::endl;
+ return *digest1 == *digest2;
+ }
+};
+
} // Sync
diff --git a/model/sync-app-socket-c.h b/model/sync-event.h
similarity index 61%
rename from model/sync-app-socket-c.h
rename to model/sync-event.h
index 53ffab1..7808947 100644
--- a/model/sync-app-socket-c.h
+++ b/model/sync-event.h
@@ -20,20 +20,16 @@
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
-#ifndef SYNC_APP_SOCKET_C_H
-#define SYNC_APP_SOCKET_C_H
+#ifndef SYNC_EVENT_H
+#define SYNC_EVENT_H
-#ifdef __cplusplus
-extern "C" {
-#endif
- typedef struct SyncAppSocketStruct SyncAppSocketStruct;
+#include <boost/function.hpp>
- SyncAppSocketStruct *create_sync_app_socket(const char *prefix, void (*callback)(const char *, const char *));
- void delete_sync_app_socket(SyncAppSocketStruct **sock);
- int sync_app_socket_publish(SyncAppSocketStruct *sock, const char *prefix, int session, const char *buf, int freshness);
- void sync_app_socket_remove(SyncAppSocketStruct *sock, const char *prefix);
-#ifdef __cplusplus
-}
-#endif
+namespace Sync
+{
-#endif // SYNC_APP_SOCKET_C_H
+typedef boost::function< void ( ) > Event;
+
+} // Sync
+
+#endif // SYNC_EVENT_H
diff --git a/model/sync-full-state.h b/model/sync-full-state.h
index cff1306..c39ec4f 100644
--- a/model/sync-full-state.h
+++ b/model/sync-full-state.h
@@ -37,6 +37,11 @@
namespace Sync {
+class FullState;
+typedef boost::shared_ptr<FullState> FullStatePtr;
+typedef boost::shared_ptr<FullState> FullStateConstPtr;
+
+
/**
* \ingroup sync
* @brief Cumulative SYNC state
diff --git a/model/sync-interest-container.h b/model/sync-interest-container.h
new file mode 100644
index 0000000..b998b18
--- /dev/null
+++ b/model/sync-interest-container.h
@@ -0,0 +1,97 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ * Chaoyi Bian <bcy@pku.edu.cn>
+ * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef SYNC_INTEREST_CONTAINER_H
+#define SYNC_INTEREST_CONTAINER_H
+
+#include "sync-digest.h"
+
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/tag.hpp>
+// #include <boost/multi_index/ordered_index.hpp>
+// #include <boost/multi_index/composite_key.hpp>
+#include <boost/multi_index/hashed_index.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+// #include <boost/multi_index/random_access_index.hpp>
+#include <boost/multi_index/member.hpp>
+#include <boost/multi_index/mem_fun.hpp>
+
+namespace mi = boost::multi_index;
+
+namespace Sync {
+
+struct Interest
+{
+ Interest (DigestConstPtr digest, const std::string &name, bool unknown=false)
+ : m_digest (digest)
+ , m_name (name)
+ , m_time (TIME_NOW)
+ , m_unknown (unknown)
+ {
+ }
+
+ DigestConstPtr m_digest;
+ std::string m_name;
+ TimeAbsolute m_time;
+ bool m_unknown;
+};
+
+/// @cond include_hidden
+struct named { };
+struct hashed;
+struct timed;
+/// @endcond
+
+/**
+ * \ingroup sync
+ * @brief Container for interests (application PIT)
+ */
+struct InterestContainer : public mi::multi_index_container<
+ Interest,
+ mi::indexed_by<
+ mi::hashed_unique<
+ mi::tag<named>,
+ BOOST_MULTI_INDEX_MEMBER(Interest, std::string, m_name)
+ >
+ ,
+
+ mi::hashed_non_unique<
+ mi::tag<hashed>,
+ BOOST_MULTI_INDEX_MEMBER(Interest, DigestConstPtr, m_digest),
+ DigestPtrHash,
+ DigestPtrEqual
+ >
+ ,
+
+ mi::ordered_non_unique<
+ mi::tag<timed>,
+ BOOST_MULTI_INDEX_MEMBER(Interest, TimeAbsolute, m_time)
+ >
+ >
+ >
+{
+};
+
+} // Sync
+
+#endif // SYNC_INTEREST_CONTAINER_H
diff --git a/model/sync-interest-table.cc b/model/sync-interest-table.cc
index 7b9ed35..a05dba3 100644
--- a/model/sync-interest-table.cc
+++ b/model/sync-interest-table.cc
@@ -30,9 +30,10 @@
namespace Sync
{
-SyncInterestTable::SyncInterestTable ()
+SyncInterestTable::SyncInterestTable (TimeDuration lifetime)
+ : m_entryLifetime (lifetime)
{
- m_scheduler.schedule (posix_time::seconds (4),
+ m_scheduler.schedule (TIME_SECONDS (m_checkPeriod),
bind (&SyncInterestTable::expireInterests, this),
0);
}
@@ -41,33 +42,36 @@
{
}
-vector<string>
-SyncInterestTable::fetchAll ()
+Interest
+SyncInterestTable::pop ()
{
expireInterests ();
recursive_mutex::scoped_lock lock (m_mutex);
-
- vector<string> entries;
- for (unordered_map<string, time_t>::iterator it = m_table.begin();
- it != m_table.end();
- ++it)
- {
- entries.push_back(it->first);
- }
- m_table.clear ();
- return entries;
+ if (m_table.size () == 0)
+ BOOST_THROW_EXCEPTION (Error::InterestTableIsEmpty ());
+
+ Interest ret = *m_table.begin ();
+ m_table.erase (m_table.begin ());
+
+ return ret;
}
bool
-SyncInterestTable::insert(const string &interest)
+SyncInterestTable::insert (DigestConstPtr digest, const string &name, bool unknownState/*=false*/)
{
+ bool existent = false;
+
recursive_mutex::scoped_lock lock (m_mutex);
- TableContainer::iterator it = m_table.find (interest);
+ InterestContainer::index<named>::type::iterator it = m_table.get<named> ().find (name);
if (it != m_table.end())
- m_table.erase(it);
- time_t currentTime = time(0);
- m_table.insert (make_pair(interest, currentTime));
+ {
+ existent = true;
+ m_table.erase (it);
+ }
+ m_table.insert (Interest (digest, name, unknownState));
+
+ return existent;
}
uint32_t
@@ -78,42 +82,56 @@
}
bool
-SyncInterestTable::remove (const std::string &interest)
+SyncInterestTable::remove (const string &name)
{
recursive_mutex::scoped_lock lock (m_mutex);
- TableContainer::iterator item = m_table.find (interest);
- if (item != m_table.end ())
+
+ InterestContainer::index<named>::type::iterator item = m_table.get<named> ().find (name);
+ if (item != m_table.get<named> ().end ())
{
- m_table.erase (item);
+ m_table.get<named> ().erase (name);
+ return true;
+ }
+
+ return false;
+}
+
+bool
+SyncInterestTable::remove (DigestConstPtr digest)
+{
+ recursive_mutex::scoped_lock lock (m_mutex);
+ InterestContainer::index<hashed>::type::iterator item = m_table.get<hashed> ().find (digest);
+ if (item != m_table.get<hashed> ().end ())
+ {
+ m_table.get<hashed> ().erase (digest); // erase all records associated with the digest
return true;
}
return false;
}
-
void SyncInterestTable::expireInterests ()
{
recursive_mutex::scoped_lock lock (m_mutex);
uint32_t count = 0;
- time_t currentTime = time(0);
- TableContainer::iterator it = m_table.begin ();
- while (it != m_table.end())
+ TimeAbsolute expireTime = TIME_NOW - m_entryLifetime;
+
+ while (m_table.size () > 0)
{
- time_t timestamp = it->second;
- _LOG_DEBUG ("expireInterests (): " << timestamp << ", " << currentTime);
- if (currentTime - timestamp > m_checkPeriod)
- {
- it = m_table.erase (it);
- count ++;
- }
- else
- ++it;
+ InterestContainer::index<timed>::type::iterator item = m_table.get<timed> ().begin ();
+
+ if (item->m_time < expireTime)
+ {
+ m_table.get<timed> ().erase (item);
+ count ++;
+ }
+ else
+ break;
}
_LOG_DEBUG ("expireInterests (): expired " << count);
- m_scheduler.schedule (posix_time::seconds (4),
+ m_scheduler.schedule (TIME_SECONDS (m_checkPeriod),
bind (&SyncInterestTable::expireInterests, this),
0);
}
diff --git a/model/sync-interest-table.h b/model/sync-interest-table.h
index 16119eb..824d1f9 100644
--- a/model/sync-interest-table.h
+++ b/model/sync-interest-table.h
@@ -22,17 +22,19 @@
#ifndef SYNC_INTEREST_TABLE_H
#define SYNC_INTEREST_TABLE_H
+
#include <string>
#include <vector>
-#include <boost/unordered_map.hpp>
-#include <boost/unordered_set.hpp>
#include <boost/thread/recursive_mutex.hpp>
#include <boost/thread/thread.hpp>
#include <ctime>
#include "sync-scheduler.h"
+#include "sync-digest.h"
+#include "sync-interest-container.h"
namespace Sync {
+
/**
* \ingroup sync
* @brief A table to keep unanswered Sync Interest
@@ -42,7 +44,7 @@
class SyncInterestTable
{
public:
- SyncInterestTable ();
+ SyncInterestTable (TimeDuration lifetime);
~SyncInterestTable ();
/**
@@ -50,19 +52,25 @@
* timestamp
*/
bool
- insert (const std::string &interest);
+ insert (DigestConstPtr interest, const std::string &name, bool unknownState=false);
/**
- * @brief Remove interest (e.g., when it was satisfied)
+ * @brief Remove interest by digest (e.g., when it was satisfied)
*/
bool
- remove (const std::string &interest);
+ remove (DigestConstPtr interest);
/**
- * @brief fetch all Interests and clear the table
+ * @brief Remove interest by name (e.g., when it was satisfied)
*/
- std::vector<std::string>
- fetchAll ();
+ bool
+ remove (const std::string &name);
+
+ /**
+ * @brief pop a non-expired Interest from PIT
+ */
+ Interest
+ pop ();
uint32_t
size () const;
@@ -75,15 +83,20 @@
expireInterests ();
private:
- typedef boost::unordered_map<std::string, time_t> TableContainer;
-
- static const int m_checkPeriod = 4;
- TableContainer m_table; // pit entries
+ static const int m_checkPeriod = 4; // seconds
+
+ TimeDuration m_entryLifetime;
+ InterestContainer m_table;
Scheduler m_scheduler;
mutable boost::recursive_mutex m_mutex;
};
+namespace Error {
+struct InterestTableIsEmpty : virtual boost::exception, virtual std::exception { };
+}
+
+
} // Sync
#endif // SYNC_INTEREST_TABLE_H
diff --git a/model/sync-log.cc b/model/sync-log.cc
deleted file mode 100644
index e80bfc8..0000000
--- a/model/sync-log.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2012 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
- * Chaoyi Bian <bcy@pku.edu.cn>
- * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- */
-
-#include "sync-log.h"
-
-#ifdef HAVE_LOG4CXX
-
-#include <log4cxx/logger.h>
-#include <log4cxx/basicconfigurator.h>
-#include <log4cxx/consoleappender.h>
-#include <log4cxx/patternlayout.h>
-#include <log4cxx/level.h>
-#include <log4cxx/propertyconfigurator.h>
-#include <log4cxx/defaultconfigurator.h>
-#include <log4cxx/helpers/exception.h>
-using namespace log4cxx;
-using namespace log4cxx::helpers;
-
-#include <unistd.h>
-
-void
-INIT_LOGGERS ()
-{
- static bool configured = false;
-
- if (configured) return;
-
- if (access ("log4cxx.properties", R_OK)==0)
- PropertyConfigurator::configureAndWatch ("log4cxx.properties");
- else
- {
- PatternLayoutPtr layout (new PatternLayout ("%d{HH:mm:ss} %p %c{1} - %m%n"));
- ConsoleAppenderPtr appender (new ConsoleAppender (layout));
-
- BasicConfigurator::configure( appender );
- Logger::getRootLogger()->setLevel (log4cxx::Level::getInfo ());
- }
-
- configured = true;
-}
-
-#endif
diff --git a/model/sync-log.h b/model/sync-log.h
deleted file mode 100644
index 9ab4843..0000000
--- a/model/sync-log.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2012 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
- * Chaoyi Bian <bcy@pku.edu.cn>
- * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- */
-
-#ifndef SYNC_LOG_H
-#define SYNC_LOG_H
-
-#ifdef HAVE_LOG4CXX
-
-#include <log4cxx/logger.h>
-
-#define INIT_LOGGER(name) \
- static log4cxx::LoggerPtr staticModuleLogger = log4cxx::Logger::getLogger (name);
-
-#define _LOG_DEBUG(x) \
- LOG4CXX_DEBUG(staticModuleLogger, x);
-
-#define _LOG_TRACE(x) \
- LOG4CXX_TRACE(staticModuleLogger, x);
-
-#define _LOG_FUNCTION(x) \
- LOG4CXX_TRACE(staticModuleLogger, __FUNCTION__ << "(" << x << ")");
-
-#define _LOG_FUNCTION_NOARGS \
- LOG4CXX_TRACE(staticModuleLogger, __FUNCTION__ << "()");
-
-void
-INIT_LOGGERS ();
-
-#else
-
-#define INIT_LOGGER(name)
-#define _LOG_FUNCTION(x)
-#define _LOG_FUNCTION_NOARGS
-#define _LOG_TRACE(x)
-#define INIT_LOGGERS(x)
-
-#ifdef _DEBUG
-
-#include <boost/thread/thread.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
-#include <iostream>
-
-#define _LOG_DEBUG(x) \
- std::clog << boost::get_system_time () << " " << boost::this_thread::get_id () << " " << x << endl;
-
-#else
-#define _LOG_DEBUG(x)
-#endif
-
-#endif // HAVE_LOG4CXX
-
-#endif // SYNC_LOG_H
diff --git a/model/sync-logic-event-container.h b/model/sync-logic-event-container.h
deleted file mode 100644
index 65c8ab2..0000000
--- a/model/sync-logic-event-container.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2012 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
- * Chaoyi Bian <bcy@pku.edu.cn>
- * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- */
-
-#ifndef SYNC_LOGIC_EVENT_CONTAINER_H
-#define SYNC_LOGIC_EVENT_CONTAINER_H
-
-#include <boost/function.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
-
-#include <boost/multi_index_container.hpp>
-// #include <boost/multi_index/tag.hpp>
-#include <boost/multi_index/ordered_index.hpp>
-// #include <boost/multi_index/composite_key.hpp>
-// #include <boost/multi_index/hashed_index.hpp>
-// #include <boost/multi_index/random_access_index.hpp>
-#include <boost/multi_index/member.hpp>
-// #include <boost/multi_index/mem_fun.hpp>
-
-namespace mi = boost::multi_index;
-
-namespace Sync
-{
-
-typedef boost::function< void ( ) > Event;
-
-struct LogicEvent
-{
- LogicEvent (const boost::system_time &_time, Event _event, uint32_t _label)
- : time (_time)
- , event (_event)
- , lbl (_label)
- { }
-
- boost::system_time time;
- Event event;
- uint32_t lbl;
-};
-
-/// @cond include_hidden
-struct byLabel { } ;
-/// @endcond
-
-/**
- * \ingroup sync
- * @brief ???
- */
-struct EventsContainer : public mi::multi_index_container<
- LogicEvent,
- mi::indexed_by<
-
- mi::ordered_non_unique<
- mi::member<LogicEvent, boost::system_time, &LogicEvent::time>
- >,
-
- mi::ordered_non_unique<
- mi::tag<byLabel>,
- mi::member<LogicEvent, uint32_t, &LogicEvent::lbl>
- >
- >
- >
-{
-};
-
-} // Sync
-
-#endif // SYNC_LOGIC_EVENT_CONTAINER_H
diff --git a/model/sync-logic.cc b/model/sync-logic.cc
index 6d56764..3bae752 100644
--- a/model/sync-logic.cc
+++ b/model/sync-logic.cc
@@ -20,6 +20,11 @@
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
+#ifdef NS3_MODULE
+#include <ns3/ccnx-pit.h>
+#include <ns3/ccnx.h>
+#endif
+
#include "sync-logic.h"
#include "sync-diff-leaf.h"
#include "sync-full-leaf.h"
@@ -28,7 +33,6 @@
#include <boost/make_shared.hpp>
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
#include <vector>
using namespace std;
@@ -36,103 +40,190 @@
INIT_LOGGER ("SyncLogic");
+#ifdef NS3_MODULE
+#define GET_RANDOM(var) var.GetValue ()
+#else
+#define GET_RANDOM(var) var ()
+#endif
+
+#define TIME_SECONDS_WITH_JITTER(sec) \
+ (TIME_SECONDS (sec) + TIME_MILLISECONDS (GET_RANDOM (m_reexpressionJitter)))
+
+#define TIME_MILLISECONDS_WITH_JITTER(ms) \
+ (TIME_MILLISECONDS (ms) + TIME_MILLISECONDS (GET_RANDOM (m_reexpressionJitter)))
+
+
namespace Sync
{
SyncLogic::SyncLogic (const std::string &syncPrefix,
LogicUpdateCallback onUpdate,
LogicRemoveCallback onRemove)
- : m_syncPrefix (syncPrefix)
+ : m_state (new FullState)
+ , m_syncInterestTable (TIME_SECONDS (m_syncInterestReexpress))
+ , m_syncPrefix (syncPrefix)
, m_onUpdate (onUpdate)
, m_onRemove (onRemove)
, m_ccnxHandle(new CcnxWrapper())
+ , m_recoveryRetransmissionInterval (m_defaultRecoveryRetransmitInterval)
+#ifndef NS3_MODULE
, m_randomGenerator (static_cast<unsigned int> (std::time (0)))
- , m_rangeUniformRandom (m_randomGenerator, uniform_int<> (20,80))
-{
-#ifdef _DEBUG
-#ifdef HAVE_LOG4CXX
- // _LOG_FUNCTION (syncPrefix);
- static int id = 0;
- staticModuleLogger = log4cxx::Logger::getLogger ("SyncLogic." + lexical_cast<string> (id));
- id ++;
+ , m_rangeUniformRandom (m_randomGenerator, uniform_int<> (200,1000))
+ , m_reexpressionJitter (m_randomGenerator, uniform_int<> (100,500))
+#else
+ , m_rangeUniformRandom (200,1000)
+ , m_reexpressionJitter (10,500)
#endif
-#endif
+{
+#ifndef NS3_MODULE
+ // In NS3 module these functions are moved to StartApplication method
m_ccnxHandle->setInterestFilter (m_syncPrefix,
bind (&SyncLogic::respondSyncInterest, this, _1));
- m_scheduler.schedule (posix_time::seconds (0),
+ m_scheduler.schedule (TIME_SECONDS (0), // no need to add jitter
bind (&SyncLogic::sendSyncInterest, this),
REEXPRESSING_INTEREST);
+#endif
}
SyncLogic::~SyncLogic ()
{
- // _LOG_FUNCTION (this);
- // cout << "SyncLogic::~SyncLogic ()" << endl;
-
m_ccnxHandle.reset ();
}
+#ifdef NS3_MODULE
void
-SyncLogic::respondSyncInterest (const string &interest)
+SyncLogic::StartApplication ()
{
- _LOG_TRACE ("<< I " << interest);
- //cout << "Respond Sync Interest" << endl;
- string hash = interest.substr(interest.find_last_of("/") + 1);
- // cout << "Received Sync Interest: " << hash << endl;
-
- DigestPtr digest = make_shared<Digest> ();
- try
- {
- istringstream is (hash);
- is >> *digest;
- }
- catch (Error::DigestCalculationError &e)
- {
- // log error. ignoring it for now, later we should log it
- return;
- }
+ m_ccnxHandle->SetNode (GetNode ());
+ m_ccnxHandle->StartApplication ();
- processSyncInterest (digest, interest, false);
+ m_ccnxHandle->setInterestFilter (m_syncPrefix,
+ bind (&SyncLogic::respondSyncInterest, this, _1));
+
+ m_scheduler.schedule (TIME_SECONDS (0), // need to send first interests at exactly the same time
+ bind (&SyncLogic::sendSyncInterest, this),
+ REEXPRESSING_INTEREST);
}
void
-SyncLogic::processSyncInterest (DigestConstPtr digest, const std::string &interestName, bool timedProcessing/*=false*/)
+SyncLogic::StopApplication ()
+{
+ m_ccnxHandle->clearInterestFilter (m_syncPrefix);
+ m_ccnxHandle->StopApplication ();
+ m_scheduler.cancel (REEXPRESSING_INTEREST);
+ m_scheduler.cancel (DELAYED_INTEREST_PROCESSING);
+}
+#endif
+
+/**
+ * Two types of intersts
+ *
+ * Normal name: .../<hash>
+ * Recovery name: .../recovery/<hash>
+ */
+boost::tuple<DigestConstPtr, std::string>
+SyncLogic::convertNameToDigestAndType (const std::string &name)
+{
+ BOOST_ASSERT (name.find (m_syncPrefix) == 0);
+
+ string hash = name.substr (m_syncPrefix.size (), name.size ()-m_syncPrefix.size ());
+ if (hash[0] == '/')
+ hash = hash.substr (1, hash.size ()-1);
+ string interestType = "normal";
+
+ size_t pos = hash.find ('/');
+ if (pos != string::npos)
+ {
+ interestType = hash.substr (0, pos);
+ hash = hash.substr (pos + 1);
+ }
+
+ _LOG_TRACE (hash << ", " << interestType);
+
+ DigestPtr digest = make_shared<Digest> ();
+ istringstream is (hash);
+ is >> *digest;
+
+ return make_tuple (digest, interestType);
+}
+
+void
+SyncLogic::respondSyncInterest (const string &name)
+{
+ try
+ {
+ _LOG_TRACE ("<< I " << name);
+
+ DigestConstPtr digest;
+ string type;
+ tie (digest, type) = convertNameToDigestAndType (name);
+
+ if (type == "normal") // kind of ineffective...
+ {
+ processSyncInterest (name, digest);
+ }
+ else if (type == "recovery")
+ {
+ processSyncRecoveryInterest (name, digest);
+ }
+ }
+ catch (Error::DigestCalculationError &e)
+ {
+ _LOG_TRACE ("Something fishy happened...");
+ // log error. ignoring it for now, later we should log it
+ return ;
+ }
+}
+
+void
+SyncLogic::respondSyncData (const std::string &name, const std::string &dataBuffer)
+{
+ try
+ {
+ _LOG_TRACE ("<< D " << name);
+
+ DigestConstPtr digest;
+ string type;
+ tie (digest, type) = convertNameToDigestAndType (name);
+
+ if (type == "normal")
+ {
+ processSyncData (name, digest, dataBuffer);
+ }
+ else
+ {
+ // timer is always restarted when we schedule recovery
+ m_scheduler.cancel (REEXPRESSING_RECOVERY_INTEREST);
+ processSyncData (name, digest, dataBuffer);
+ }
+ }
+ catch (Error::DigestCalculationError &e)
+ {
+ _LOG_TRACE ("Something fishy happened...");
+ // log error. ignoring it for now, later we should log it
+ return;
+ }
+}
+
+
+void
+SyncLogic::processSyncInterest (const std::string &name, DigestConstPtr digest, bool timedProcessing/*=false*/)
{
recursive_mutex::scoped_lock lock (m_stateMutex);
// Special case when state is not empty and we have received request with zero-root digest
- if (digest->isZero () && !m_state.getDigest()->isZero ())
+ if (digest->isZero () && !m_state->getDigest()->isZero ())
{
- _LOG_TRACE (">> D " << interestName << "/state" << " (zero)");
-
- m_syncInterestTable.remove (interestName + "/state");
- m_ccnxHandle->publishData (interestName + "/state",
- lexical_cast<string> (m_state),
- m_syncResponseFreshness);
- if (m_outstandingInterest == interestName)
- {
- m_scheduler.schedule (posix_time::seconds (0),
- bind (&SyncLogic::sendSyncInterest, this),
- REEXPRESSING_INTEREST);
- }
+ sendSyncData (name, digest, m_state);
return;
}
- if (*m_state.getDigest() == *digest)
+ if (*m_state->getDigest() == *digest)
{
- // cout << interestName << "\n";
- if (digest->isZero ())
- {
- _LOG_TRACE ("processSyncInterest (): Digest is zero, adding /state to PIT");
- m_syncInterestTable.insert (interestName + "/state");
- }
- else
- {
- _LOG_TRACE ("processSyncInterest (): Same state. Adding to PIT");
- m_syncInterestTable.insert (interestName);
- }
+ _LOG_TRACE ("processSyncInterest (): Same state. Adding to PIT");
+ m_syncInterestTable.insert (digest, name, false);
return;
}
@@ -141,82 +232,67 @@
if (stateInDiffLog != m_log.end ())
{
DiffStateConstPtr stateDiff = (*stateInDiffLog)->diff ();
- // string state = lexical_cast<string> (*stateDiff);
- // erase_all (state, "\n");
- // _LOG_TRACE (">> D " << interestName << ", state: " << state);
- // _LOG_DEBUG ("Log size: " << m_log.size ());
- // BOOST_FOREACH (DiffStateConstPtr ds, m_log.get<sequenced> ())
- // {
- // string state = lexical_cast<string> (*ds);
- // erase_all (state, "\n");
- // _LOG_DEBUG (" " << state << ", " << *ds->getDigest ());
- // }
-
- m_syncInterestTable.remove (interestName);
- m_ccnxHandle->publishData (interestName,
- lexical_cast<string> (*stateDiff),
- m_syncResponseFreshness);
- if (m_outstandingInterest == interestName)
- {
- m_scheduler.schedule (posix_time::seconds (0),
- bind (&SyncLogic::sendSyncInterest, this),
- REEXPRESSING_INTEREST);
- }
+ sendSyncData (name, digest, stateDiff);
return;
}
if (!timedProcessing)
{
- m_scheduler.schedule (posix_time::milliseconds (m_rangeUniformRandom ()) /*from 20 to 100ms*/,
- bind (&SyncLogic::processSyncInterest, this, digest, interestName, true),
+ bool exists = m_syncInterestTable.insert (digest, name, true);
+ if (exists) // somebody else replied, so restart random-game timer
+ {
+ _LOG_DEBUG ("Unknown digest, but somebody may have already replied, so restart our timer");
+ m_scheduler.cancel (DELAYED_INTEREST_PROCESSING);
+ }
+
+ uint32_t waitDelay = GET_RANDOM (m_rangeUniformRandom);
+ _LOG_DEBUG ("Digest is not in the log. Schedule processing after small delay: " << waitDelay << "ms");
+
+ m_scheduler.schedule (TIME_MILLISECONDS (waitDelay),
+ bind (&SyncLogic::processSyncInterest, this, name, digest, true),
DELAYED_INTEREST_PROCESSING);
-
}
else
{
- _LOG_TRACE (">> D " << interestName << "/state" << " (timed processing)");
-
- m_syncInterestTable.remove (interestName + "/state");
- m_ccnxHandle->publishData (interestName + "/state",
- lexical_cast<string> (m_state),
- m_syncResponseFreshness);
-
- if (m_outstandingInterest == interestName)
- {
- m_scheduler.schedule (posix_time::seconds (0),
- bind (&SyncLogic::sendSyncInterest, this),
- REEXPRESSING_INTEREST);
- }
+ _LOG_TRACE (" (timed processing)");
+
+ m_recoveryRetransmissionInterval = m_defaultRecoveryRetransmitInterval;
+ sendSyncRecoveryInterests (digest);
}
}
void
-SyncLogic::processSyncData (const string &name, const string &dataBuffer)
+SyncLogic::processSyncData (const std::string &name, DigestConstPtr digest, const string &dataBuffer)
{
- _LOG_TRACE ("<< D " << name);
DiffStatePtr diffLog = make_shared<DiffState> ();
+ bool ownInterestSatisfied = false;
try
{
recursive_mutex::scoped_lock lock (m_stateMutex);
-
- string last = name.substr(name.find_last_of("/") + 1);
- istringstream ss (dataBuffer);
- if (last == "state")
+ m_syncInterestTable.remove (name); // Remove satisfied interest from PIT
+
+ ownInterestSatisfied = (name == m_outstandingInterestName);
+
+ DiffState diff;
+ istringstream ss (dataBuffer);
+ ss >> diff;
+ BOOST_FOREACH (LeafConstPtr leaf, diff.getLeaves().get<ordered>())
{
- FullState full;
- ss >> full;
- BOOST_FOREACH (LeafConstPtr leaf, full.getLeaves()) // order doesn't matter
+ DiffLeafConstPtr diffLeaf = dynamic_pointer_cast<const DiffLeaf> (leaf);
+ BOOST_ASSERT (diffLeaf != 0);
+
+ NameInfoConstPtr info = diffLeaf->getInfo();
+ if (diffLeaf->getOperation() == UPDATE)
{
- NameInfoConstPtr info = leaf->getInfo ();
- SeqNo seq = leaf->getSeq ();
+ SeqNo seq = diffLeaf->getSeq();
bool inserted = false;
bool updated = false;
SeqNo oldSeq;
- tie (inserted, updated, oldSeq) = m_state.update (info, seq);
+ tie (inserted, updated, oldSeq) = m_state->update (info, seq);
if (inserted || updated)
{
@@ -224,44 +300,17 @@
m_onUpdate (info->toString (), seq, oldSeq);
}
}
- }
- else
- {
- DiffState diff;
- ss >> diff;
- BOOST_FOREACH (LeafConstPtr leaf, diff.getLeaves().get<ordered>())
+ else if (diffLeaf->getOperation() == REMOVE)
{
- DiffLeafConstPtr diffLeaf = dynamic_pointer_cast<const DiffLeaf> (leaf);
- BOOST_ASSERT (diffLeaf != 0);
-
- NameInfoConstPtr info = diffLeaf->getInfo();
- if (diffLeaf->getOperation() == UPDATE)
+ if (m_state->remove (info))
{
- SeqNo seq = diffLeaf->getSeq();
-
- bool inserted = false;
- bool updated = false;
- SeqNo oldSeq;
- tie (inserted, updated, oldSeq) = m_state.update (info, seq);
-
- if (inserted || updated)
- {
- diffLog->update (info, seq);
- m_onUpdate (info->toString (), seq, oldSeq);
- }
+ diffLog->remove (info);
+ m_onRemove (info->toString ());
}
- else if (diffLeaf->getOperation() == REMOVE)
- {
- if (m_state.remove (info))
- {
- diffLog->remove (info);
- m_onRemove (info->toString ());
- }
- }
- else
- {
- BOOST_ASSERT (false); // just in case
- }
+ }
+ else
+ {
+ BOOST_ASSERT (false); // just in case
}
}
@@ -269,75 +318,95 @@
}
catch (Error::SyncXmlDecodingFailure &e)
{
+ _LOG_TRACE ("Something really fishy happened during state decoding " <<
+ diagnostic_information (e));
diffLog.reset ();
// don't do anything
}
- // if state has changed, then it is safe to express a new interest
- if (diffLog->getLeaves ().size () > 0)
+ if ((diffLog != 0 && diffLog->getLeaves ().size () > 0) ||
+ ownInterestSatisfied)
{
- m_scheduler.schedule (posix_time::seconds (0),
- bind (&SyncLogic::sendSyncInterest, this),
- REEXPRESSING_INTEREST);
- }
- else
- {
- // should not reexpress the same interest. Need at least wait for data lifetime
- // Otherwise we will get immediate reply from the local daemon and there will be 100% utilization
+ // Do it only if everything went fine and state changed
+
+ // this is kind of wrong
+ // satisfyPendingSyncInterests (diffLog); // if there are interests in PIT, there is a point to satisfy them using new state
+
+ // if state has changed, then it is safe to express a new interest
m_scheduler.cancel (REEXPRESSING_INTEREST);
- // m_scheduler.schedule (posix_time::seconds (0),
- m_scheduler.schedule (posix_time::seconds (m_syncResponseFreshness) + posix_time::milliseconds (1),
+ m_scheduler.schedule (TIME_SECONDS_WITH_JITTER (0),
bind (&SyncLogic::sendSyncInterest, this),
REEXPRESSING_INTEREST);
}
}
void
-SyncLogic::satisfyPendingSyncInterests (DiffStatePtr diffLog)
+SyncLogic::processSyncRecoveryInterest (const std::string &name, DigestConstPtr digest)
{
- vector<string> pis = m_syncInterestTable.fetchAll ();
- if (pis.size () > 0)
+ recursive_mutex::scoped_lock lock (m_stateMutex);
+
+ DiffStateContainer::iterator stateInDiffLog = m_log.find (digest);
+
+ if (stateInDiffLog == m_log.end ())
{
- stringstream ss;
- ss << *diffLog;
- bool satisfiedOwnInterest = false;
-
- for (vector<string>::iterator ii = pis.begin(); ii != pis.end(); ++ii)
- {
- _LOG_TRACE (">> D " << *ii);
- m_ccnxHandle->publishData (*ii, ss.str(), m_syncResponseFreshness);
+ _LOG_TRACE ("Could not find " << *digest << " in digest log");
+ return;
+ }
- {
- recursive_mutex::scoped_lock lock (m_stateMutex);
- // _LOG_DEBUG (*ii << " == " << m_outstandingInterest << " = " << (*ii == m_outstandingInterest));
- satisfiedOwnInterest = satisfiedOwnInterest || (*ii == m_outstandingInterest) || (*ii == (m_outstandingInterest + "/state"));
- }
- }
+ sendSyncData (name, digest, m_state);
+}
- if (satisfiedOwnInterest)
+void
+SyncLogic::satisfyPendingSyncInterests (DiffStateConstPtr diffLog)
+{
+ DiffStatePtr fullStateLog = make_shared<DiffState> ();
+ {
+ recursive_mutex::scoped_lock lock (m_stateMutex);
+ BOOST_FOREACH (LeafConstPtr leaf, m_state->getLeaves ()/*.get<timed> ()*/)
+ {
+ fullStateLog->update (leaf->getInfo (), leaf->getSeq ());
+ /// @todo Impose limit on how many state info should be send out
+ }
+ }
+
+ try
+ {
+ uint32_t counter = 0;
+ while (m_syncInterestTable.size () > 0)
{
- _LOG_DEBUG ("Have satisfied our own interest. Scheduling interest reexpression");
- // we need to reexpress interest only if we satisfied our own interest
- m_scheduler.schedule (posix_time::milliseconds (0),
- bind (&SyncLogic::sendSyncInterest, this),
- REEXPRESSING_INTEREST);
+ Interest interest = m_syncInterestTable.pop ();
+
+ if (!interest.m_unknown)
+ {
+ _LOG_TRACE (">> D " << interest.m_name);
+ sendSyncData (interest.m_name, interest.m_digest, diffLog);
+ }
+ else
+ {
+ _LOG_TRACE (">> D (unknown)" << interest.m_name);
+ sendSyncData (interest.m_name, interest.m_digest, fullStateLog);
+ }
+ counter ++;
}
+ _LOG_DEBUG ("Satisfied " << counter << " pending interests");
+ }
+ catch (Error::InterestTableIsEmpty &e)
+ {
+ // ok. not really an error
}
}
void
SyncLogic::insertToDiffLog (DiffStatePtr diffLog)
{
- //cout << "Process Pending Interests" <<endl;
- diffLog->setDigest (m_state.getDigest());
+ diffLog->setDigest (m_state->getDigest());
if (m_log.size () > 0)
{
m_log.get<sequenced> ().front ()->setNext (diffLog);
}
- m_log.erase (m_state.getDigest()); // remove diff state with the same digest. next pointers are still valid
+ m_log.erase (m_state->getDigest()); // remove diff state with the same digest. next pointers are still valid
/// @todo Optimization
m_log.get<sequenced> ().push_front (diffLog);
- // _LOG_DEBUG (*diffLog->getDigest () << " " << m_log.size ());
}
void
@@ -349,10 +418,12 @@
recursive_mutex::scoped_lock lock (m_stateMutex);
NameInfoConstPtr info = StdNameInfo::FindOrCreate(prefix);
- SeqNo seqN (session, seq);
- m_state.update(info, seqN);
+ _LOG_DEBUG ("addLocalNames (): old state " << *m_state->getDigest ());
- _LOG_DEBUG ("addLocalNames (): new state " << *m_state.getDigest ());
+ SeqNo seqN (session, seq);
+ m_state->update(info, seqN);
+
+ _LOG_DEBUG ("addLocalNames (): new state " << *m_state->getDigest ());
diff = make_shared<DiffState>();
diff->update(info, seqN);
@@ -370,7 +441,7 @@
{
recursive_mutex::scoped_lock lock (m_stateMutex);
NameInfoConstPtr info = StdNameInfo::FindOrCreate(prefix);
- m_state.remove(info);
+ m_state->remove(info);
diff = make_shared<DiffState>();
diff->remove(info);
@@ -387,23 +458,71 @@
ostringstream os;
{
- // cout << "Sending Sync Interest" << endl;
recursive_mutex::scoped_lock lock (m_stateMutex);
- os << m_syncPrefix << "/" << *m_state.getDigest();
-
+ os << m_syncPrefix << "/" << *m_state->getDigest();
+ m_outstandingInterestName = os.str ();
_LOG_TRACE (">> I " << os.str ());
-
- m_outstandingInterest = os.str ();
}
-
- m_ccnxHandle->sendInterest (os.str (),
- bind (&SyncLogic::processSyncData, this, _1, _2));
m_scheduler.cancel (REEXPRESSING_INTEREST);
- m_scheduler.schedule (posix_time::seconds (4),
+ m_scheduler.schedule (TIME_SECONDS_WITH_JITTER (m_syncInterestReexpress),
bind (&SyncLogic::sendSyncInterest, this),
REEXPRESSING_INTEREST);
+
+ m_ccnxHandle->sendInterest (os.str (),
+ bind (&SyncLogic::respondSyncData, this, _1, _2));
}
+void
+SyncLogic::sendSyncRecoveryInterests (DigestConstPtr digest)
+{
+ ostringstream os;
+ os << m_syncPrefix << "/recovery/" << *digest;
+ _LOG_TRACE (">> I " << os.str ());
+
+ TimeDuration nextRetransmission = TIME_MILLISECONDS_WITH_JITTER (m_recoveryRetransmissionInterval);
+ m_recoveryRetransmissionInterval <<= 1;
+
+ m_scheduler.cancel (REEXPRESSING_RECOVERY_INTEREST);
+ if (m_recoveryRetransmissionInterval < 100*1000) // <100 seconds
+ {
+ m_scheduler.schedule (nextRetransmission,
+ bind (&SyncLogic::sendSyncRecoveryInterests, this, digest),
+ REEXPRESSING_RECOVERY_INTEREST);
+ }
+
+ m_ccnxHandle->sendInterest (os.str (),
+ bind (&SyncLogic::respondSyncData, this, _1, _2));
+}
+
+
+void
+SyncLogic::sendSyncData (const std::string &name, DigestConstPtr digest, StateConstPtr state)
+{
+ _LOG_TRACE (">> D " << name);
+ // sending
+ m_ccnxHandle->publishData (name,
+ lexical_cast<string> (*state),
+ m_syncResponseFreshness); // in NS-3 it doesn't have any effect... yet
+
+ // checking if our own interest got satisfied
+ bool satisfiedOwnInterest = false;
+ {
+ recursive_mutex::scoped_lock lock (m_stateMutex);
+ satisfiedOwnInterest = (m_outstandingInterestName == name);
+ }
+
+ if (satisfiedOwnInterest)
+ {
+ _LOG_TRACE ("Satisfied our own Interest. Re-expressing (hopefully with a new digest)");
+
+ m_scheduler.cancel (REEXPRESSING_INTEREST);
+ m_scheduler.schedule (TIME_SECONDS_WITH_JITTER (0),
+ bind (&SyncLogic::sendSyncInterest, this),
+ REEXPRESSING_INTEREST);
+ }
+}
+
+
}
diff --git a/model/sync-logic.h b/model/sync-logic.h
index ad0a208..e205fc0 100644
--- a/model/sync-logic.h
+++ b/model/sync-logic.h
@@ -43,6 +43,11 @@
#endif
#endif
+#ifdef NS3_MODULE
+#include <ns3/application.h>
+#include <ns3/random-variable.h>
+#endif
+
namespace Sync {
/**
@@ -51,6 +56,9 @@
* interests and data)
*/
class SyncLogic
+#ifdef NS3_MODULE
+ : public ns3::Application
+#endif
{
public:
typedef boost::function< void ( const std::string &/*prefix*/, const SeqNo &/*newSeq*/, const SeqNo &/*oldSeq*/ ) > LogicUpdateCallback;
@@ -86,7 +94,7 @@
* @param name the data name
* @param dataBuffer the sync data
*/
- void processSyncData (const std::string &name, const std::string &dataBuffer);
+ void respondSyncData (const std::string &name, const std::string &dataBuffer);
/**
* @brief remove a participant's subtree from the sync tree
@@ -98,29 +106,54 @@
Scheduler &
getScheduler () { return m_scheduler; }
#endif
+
+#ifdef NS3_MODULE
+public:
+ virtual void StartApplication ();
+ virtual void StopApplication ();
+#endif
private:
void
delayedChecksLoop ();
void
- processSyncInterest (DigestConstPtr digest, const std::string &interestname, bool timedProcessing=false);
+ processSyncInterest (const std::string &name,
+ DigestConstPtr digest, bool timedProcessing=false);
+
+ void
+ processSyncData (const std::string &name,
+ DigestConstPtr digest, const std::string &dataBuffer);
void
- sendSyncInterest ();
-
+ processSyncRecoveryInterest (const std::string &name,
+ DigestConstPtr digest);
+
void
insertToDiffLog (DiffStatePtr diff);
void
- satisfyPendingSyncInterests (DiffStatePtr diff);
+ satisfyPendingSyncInterests (DiffStateConstPtr diff);
+ boost::tuple<DigestConstPtr, std::string>
+ convertNameToDigestAndType (const std::string &name);
+
+ void
+ sendSyncInterest ();
+
+ void
+ sendSyncRecoveryInterests (DigestConstPtr digest);
+
+ void
+ sendSyncData (const std::string &name,
+ DigestConstPtr digest, StateConstPtr state);
+
private:
- FullState m_state;
+ FullStatePtr m_state;
DiffStateContainer m_log;
boost::recursive_mutex m_stateMutex;
- std::string m_outstandingInterest;
+ std::string m_outstandingInterestName;
SyncInterestTable m_syncInterestTable;
std::string m_syncPrefix;
@@ -130,22 +163,34 @@
Scheduler m_scheduler;
+#ifndef NS3_MODULE
boost::mt19937 m_randomGenerator;
boost::variate_generator<boost::mt19937&, boost::uniform_int<> > m_rangeUniformRandom;
-
- static const int m_syncResponseFreshness = 2;
+ boost::variate_generator<boost::mt19937&, boost::uniform_int<> > m_reexpressionJitter;
+#else
+ ns3::UniformVariable m_rangeUniformRandom;
+ ns3::UniformVariable m_reexpressionJitter;
+#endif
+ static const int m_unknownDigestStoreTime = 10; // seconds
+#ifdef NS3_MODULE
+ static const int m_syncResponseFreshness = 100; // milliseconds
+ static const int m_syncInterestReexpress = 10; // seconds
+ // don't forget to adjust value in SyncCcnxWrapper
+#else
+ static const int m_syncResponseFreshness = 2000;
+ static const int m_syncInterestReexpress = 4;
+#endif
+
+ static const int m_defaultRecoveryRetransmitInterval = 200; // milliseconds
+ uint32_t m_recoveryRetransmissionInterval; // milliseconds
+
enum EventLabels
{
DELAYED_INTEREST_PROCESSING = 1,
- REEXPRESSING_INTEREST = 2
+ REEXPRESSING_INTEREST = 2,
+ REEXPRESSING_RECOVERY_INTEREST = 3
};
-
-#ifdef _DEBUG
-#ifdef HAVE_LOG4CXX
- log4cxx::LoggerPtr staticModuleLogger;
-#endif
-#endif
};
diff --git a/model/sync-ns3-name-info.cc b/model/sync-ns3-name-info.cc
deleted file mode 100644
index b46d1f6..0000000
--- a/model/sync-ns3-name-info.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2012 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
- * Chaoyi Bian <bcy@pku.edu.cn>
- * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- */
-
-#ifndef STANDALONE
-
-#include "sync-ns3-name-info.h"
-#include "ns3/ccnx-name-components.h"
-
-#include <boost/foreach.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/make_shared.hpp>
-#include <utility>
-
-using namespace std;
-using namespace boost;
-
-namespace Sync {
-
-
-NameInfoConstPtr
-Ns3NameInfo::FindOrCreate (ns3::Ptr<const ns3::CcnxNameComponents> name)
-{
- string key = lexical_cast<string> (*name);
-
- NameMap::iterator item = m_names.find (key);
- if (item == m_names.end ())
- {
- NameInfoPtr value = NameInfoPtr (new Ns3NameInfo (name));
- pair<NameMap::iterator,bool> inserted =
- m_names.insert (make_pair (key, value));
- BOOST_ASSERT (inserted.second); // previous call has to insert value
- item = inserted.first;
- }
-
- return item->second;
-}
-
-Ns3NameInfo::Ns3NameInfo (ns3::Ptr<const ns3::CcnxNameComponents> name)
- : m_name (name)
-{
- m_id = m_ids ++; // set ID for a newly inserted element
- m_digest << *name;
- m_digest.getHash (); // finalize digest
-}
-
-string
-Ns3NameInfo::toString () const
-{
- return lexical_cast<std::string> (*m_name);
-}
-
-bool
-Ns3NameInfo::operator == (const NameInfo &info) const
-{
- try
- {
- return *m_name == *dynamic_cast<const Ns3NameInfo&> (info).m_name;
- }
- catch (...)
- {
- return false;
- }
-}
-
-Digest &
-operator << (Digest &digest, const ns3::CcnxNameComponents &name)
-{
- BOOST_FOREACH (const std::string &component, name.GetComponents ())
- {
- Digest subhash;
- subhash << component;
- subhash.getHash (); // finalize hash
-
- digest << subhash;
- }
-
- return digest;
-}
-
-
-} // Sync
-
-#endif
-
diff --git a/model/sync-ns3-name-info.h b/model/sync-ns3-name-info.h
deleted file mode 100644
index 9363665..0000000
--- a/model/sync-ns3-name-info.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2012 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
- * Chaoyi Bian <bcy@pku.edu.cn>
- * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- */
-
-#ifndef STANDALONE
-
-#ifndef SYNC_CCNX_NAME_INFO_H
-#define SYNC_CCNX_NAME_INFO_H
-
-#include "sync-name-info.h"
-#include "ns3/ptr.h"
-#include "ns3/ccnx-name-components.h"
-
-namespace Sync {
-
-class Ns3NameInfo : public NameInfo
-{
-public:
- /**
- * @brief Lookup existing or create new NameInfo object
- * @param name routable prefix
- */
- static NameInfoConstPtr
- FindOrCreate (ns3::Ptr<const ns3::CcnxNameComponents> name);
-
- virtual ~Ns3NameInfo () { };
-
- // from NameInfo
- virtual bool
- operator == (const NameInfo &info) const;
-
- virtual std::string
- toString () const;
-
-private:
- // implementing a singleton pattern.
- /**
- * @brief Disabled default constructor. NameInfo object should be created through FindOrCreate static call.
- */
-
- /**
- * @brief Disabled default
- */
- Ns3NameInfo () {}
- Ns3NameInfo& operator = (const Ns3NameInfo &info) { return *this; }
- Ns3NameInfo (ns3::Ptr<const ns3::CcnxNameComponents> name);
-
- ns3::Ptr<const ns3::CcnxNameComponents> m_name;
-};
-
-Digest &
-operator << (Digest &, const ns3::CcnxNameComponents &name);
-
-} // Sync
-
-#endif // SYNC_CCNX_NAME_INFO_H
-
-#endif // STANDALONE
diff --git a/model/sync-scheduler.cc b/model/sync-scheduler.cc
deleted file mode 100644
index 4f9e082..0000000
--- a/model/sync-scheduler.cc
+++ /dev/null
@@ -1,143 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2012 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
- * Chaoyi Bian <bcy@pku.edu.cn>
- * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- */
-
-#include "sync-scheduler.h"
-#include "sync-log.h"
-
-using namespace boost;
-using namespace std;
-
-INIT_LOGGER ("Scheduler");
-
-namespace Sync {
-
-Scheduler::Scheduler ()
- : m_threadRunning (true)
-{
- m_thread = thread (&Scheduler::threadLoop, this);
-}
-
-Scheduler::~Scheduler ()
-{
- m_threadRunning = false;
- // cout << "Requested stop" << this_thread::get_id () << endl;
- m_thread.interrupt ();
- m_thread.join ();
-}
-
-void
-Scheduler::threadLoop ()
-{
- _LOG_FUNCTION (this);
- while (m_threadRunning)
- {
- try
- {
- boost::system_time nextTime;
- {
- unique_lock<mutex> lock (m_eventsMutex);
- while (m_threadRunning && m_events.size () == 0)
- {
- m_eventsCondition.wait (lock);
- // cout << "Got something" << endl;
- }
-
- if (m_events.size () == 0) continue;
-
- nextTime = m_events.begin ()->time;
- }
-
- if (nextTime > get_system_time ())
- {
- this_thread::sleep (nextTime - get_system_time ());
-
- // sleeping
-
- if (nextTime > get_system_time ())
- {
- // cout << "expected here" << endl;
- continue; // something changes, try again
- }
- }
-
- if (!m_threadRunning) continue;
-
- Event event;
-
- {
- lock_guard<mutex> lock (m_eventsMutex);
-
- if (m_events.size () == 0)
- {
- // cout << "Here" << endl;
- continue;
- }
-
- event = m_events.begin ()->event;
- m_events.erase (m_events.begin ());
- }
-
- event (); // calling the event outside the locked mutex
- }
- catch (thread_interrupted &e)
- {
- // cout << "interrupted: " << this_thread::get_id () << endl;
- // do nothing
- }
- }
- // cout << "Exited...\n";
-}
-
-
-void
-Scheduler::schedule (const boost::system_time &abstime, Event event, uint32_t label)
-{
- {
- lock_guard<mutex> lock (m_eventsMutex);
- m_events.insert (LogicEvent (abstime, event, label));
- }
- m_eventsCondition.notify_one ();
- m_thread.interrupt (); // interrupt sleep, if currently sleeping
-}
-
-void
-Scheduler::schedule (const boost::posix_time::time_duration &reltime, Event event, uint32_t label)
-{
- // cout << reltime << endl;
- schedule (boost::get_system_time () + reltime, event, label);
-}
-
-void
-Scheduler::cancel (uint32_t label)
-{
- {
- // cout << "Canceling label " << label << " size: " << m_events.size () << endl;
- lock_guard<mutex> lock (m_eventsMutex);
- m_events.get<byLabel> ().erase (label);
- // cout << "Canceled label " << label << " size: " << m_events.size () << endl;
- }
- m_eventsCondition.notify_one ();
- m_thread.interrupt (); // interrupt sleep, if currently sleeping
-}
-
-
-} // Sync
diff --git a/model/sync-scheduler.h b/model/sync-scheduler.h
deleted file mode 100644
index 10ef210..0000000
--- a/model/sync-scheduler.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2012 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
- * Chaoyi Bian <bcy@pku.edu.cn>
- * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- */
-
-#ifndef SYNC_SCHEDULER_H
-#define SYNC_SCHEDULER_H
-
-#include <boost/thread/thread.hpp>
-#include <boost/thread/mutex.hpp>
-
-#include "sync-logic-event-container.h"
-
-namespace Sync {
-
-/**
- * @ingroup sync
- * @brief General purpose event scheduler
- *
- * This class internally runs a thread and events can be scheduled by specifying an absolute or relative time of the event
- */
-class Scheduler
-{
-public:
- /**
- * @brief Default constructor. Thread will be created
- */
- Scheduler ();
- /**
- * @brief Destructor. Thread will be nicely stopped
- */
- ~Scheduler ();
-
- /**
- * @brief Schedule an event at absolute time 'abstime'
- * @param abstime Absolute time
- * @param event function to be called at the time
- * @param label Label for the event
- */
- void
- schedule (const boost::system_time &abstime, Event event, uint32_t label);
-
- /**
- * @brief Schedule an event at relative time 'reltime'
- * @param reltime Relative time
- * @param event function to be called at the time
- * @param label Label for the event
- */
- void
- schedule (const boost::posix_time::time_duration &reltime, Event event, uint32_t label);
-
- /**
- * @brief Cancel all events for the label
- * @param label Label of the event that needs to be cancelled
- */
- void
- cancel (uint32_t label);
-
-#ifdef _DEBUG
- size_t
- getEventsSize ()
- {
- boost::lock_guard<boost::mutex> lock (m_eventsMutex);
- return m_events.size ();
- }
-#endif
-
-private:
- void
- threadLoop ();
-
-private:
- EventsContainer m_events;
- boost::condition_variable m_eventsCondition;
- boost::mutex m_eventsMutex;
-
- boost::thread m_thread;
- bool m_threadRunning;
-};
-
-}
-
-#endif // SYNC_SCHEDULER_H
diff --git a/model/sync-state.h b/model/sync-state.h
index faaad02..826e84d 100644
--- a/model/sync-state.h
+++ b/model/sync-state.h
@@ -34,6 +34,10 @@
*/
namespace Sync {
+class State;
+typedef boost::shared_ptr<State> StatePtr;
+typedef boost::shared_ptr<State> StateConstPtr;
+
/**
* \ingroup sync
* @brief Container for state leaves and definition of the abstract interface to work with State objects