Merge branch 'master' of git.irl.cs.ucla.edu:ndn/sync
diff --git a/include/sync-logic.h b/include/sync-logic.h
index 551cb06..5e32918 100644
--- a/include/sync-logic.h
+++ b/include/sync-logic.h
@@ -101,7 +101,7 @@
* @param name the data name
* @param dataBuffer the sync data
*/
- void respondSyncData (const std::string &name, const std::string &dataBuffer);
+ void respondSyncData (const std::string &name, const char *wireData, size_t len);
/**
* @brief remove a participant's subtree from the sync tree
@@ -133,7 +133,7 @@
void
processSyncData (const std::string &name,
- DigestConstPtr digest, const std::string &dataBuffer);
+ DigestConstPtr digest, const char *wireData, size_t len);
void
processSyncRecoveryInterest (const std::string &name,
diff --git a/include/sync-state.h b/include/sync-state.h
index 826e84d..84c2400 100644
--- a/include/sync-state.h
+++ b/include/sync-state.h
@@ -26,6 +26,7 @@
#include "sync-state-leaf-container.h"
#include <boost/exception/all.hpp>
#include "boost/tuple/tuple.hpp"
+#include "sync-state.pb.h"
/**
* \defgroup sync SYNC protocol
@@ -74,29 +75,31 @@
LeafContainer m_leaves;
};
-/**
- * @brief Formats an XML representation of the state
- * @param os output stream
- * @param state state
- * @returns output stream
- */
-std::ostream &
-operator << (std::ostream &os, const State &state);
/**
- * @brief Parses an XML representation to the state
- * @param in input data stream
+ * @brief Formats a protobuf SyncStateMsg msg
+ * @param oss output SyncStateMsg msg
* @param state state
- * @returns input stream
+ * @returns output SyncStateMsg msg
*/
-std::istream &
-operator >> (std::istream &in, State &state);
+SyncStateMsg &
+operator << (SyncStateMsg &ossm, const State &state);
+
+
+/**
+ * @brief Parse a protobuf SyncStateMsg msg
+ * @param iss input SyncStateMsg msg
+ * @param state state
+ * @returns SyncStateMsg msg
+ */
+SyncStateMsg &
+operator >> (SyncStateMsg &issm, State &state);
namespace Error {
/**
- * @brief Will be thrown when XML cannot be properly decoded to State
+ * @brief Will be thrown when data cannot be properly decoded to SyncStateMsg
*/
-struct SyncXmlDecodingFailure : virtual boost::exception, virtual std::exception { };
+struct SyncStateMsgDecodingFailure : virtual boost::exception, virtual std::exception { };
}
} // Sync
diff --git a/model/sync-logic.cc b/model/sync-logic.cc
index 860f119..b72a061 100644
--- a/model/sync-logic.cc
+++ b/model/sync-logic.cc
@@ -29,6 +29,7 @@
#include "sync-diff-leaf.h"
#include "sync-full-leaf.h"
#include "sync-log.h"
+#include "sync-state.h"
#include <boost/make_shared.hpp>
#include <boost/foreach.hpp>
@@ -178,7 +179,7 @@
}
void
-SyncLogic::respondSyncData (const std::string &name, const std::string &dataBuffer)
+SyncLogic::respondSyncData (const std::string &name, const char *wireData, size_t len)
{
try
{
@@ -190,13 +191,13 @@
if (type == "normal")
{
- processSyncData (name, digest, dataBuffer);
+ processSyncData (name, digest, wireData, len);
}
else
{
// timer is always restarted when we schedule recovery
m_scheduler.cancel (REEXPRESSING_RECOVERY_INTEREST);
- processSyncData (name, digest, dataBuffer);
+ processSyncData (name, digest, wireData, len);
}
}
catch (Error::DigestCalculationError &e)
@@ -263,7 +264,7 @@
}
void
-SyncLogic::processSyncData (const std::string &name, DigestConstPtr digest, const string &dataBuffer)
+SyncLogic::processSyncData (const std::string &name, DigestConstPtr digest, const char *wireData, size_t len)
{
DiffStatePtr diffLog = make_shared<DiffState> ();
bool ownInterestSatisfied = false;
@@ -277,8 +278,14 @@
ownInterestSatisfied = (name == m_outstandingInterestName);
DiffState diff;
- istringstream ss (dataBuffer);
- ss >> diff;
+ SyncStateMsg msg;
+ if (!msg.ParseFromArray(wireData, len) || !msg.IsInitialized())
+ {
+ //Throw
+ BOOST_THROW_EXCEPTION (Error::SyncStateMsgDecodingFailure () );
+ }
+ msg >> diff;
+
vector<MissingDataInfo> v;
BOOST_FOREACH (LeafConstPtr leaf, diff.getLeaves().get<ordered>())
{
@@ -332,7 +339,7 @@
insertToDiffLog (diffLog);
}
- catch (Error::SyncXmlDecodingFailure &e)
+ catch (Error::SyncStateMsgDecodingFailure &e)
{
_LOG_TRACE ("Something really fishy happened during state decoding " <<
diagnostic_information (e));
@@ -486,8 +493,8 @@
bind (&SyncLogic::sendSyncInterest, this),
REEXPRESSING_INTEREST);
- m_ccnxHandle->sendInterestForString (os.str (),
- bind (&SyncLogic::respondSyncData, this, _1, _2));
+ m_ccnxHandle->sendInterest (os.str (),
+ bind (&SyncLogic::respondSyncData, this, _1, _2, _3));
}
void
@@ -508,8 +515,8 @@
REEXPRESSING_RECOVERY_INTEREST);
}
- m_ccnxHandle->sendInterestForString (os.str (),
- bind (&SyncLogic::respondSyncData, this, _1, _2));
+ m_ccnxHandle->sendInterest (os.str (),
+ bind (&SyncLogic::respondSyncData, this, _1, _2, _3));
}
@@ -518,9 +525,16 @@
{
_LOG_TRACE (">> D " << name);
// sending
- m_ccnxHandle->publishStringData (name,
- lexical_cast<string> (*state),
+ SyncStateMsg ssm;
+ ssm << (*state);
+ int size = ssm.ByteSize();
+ char *wireData = new char[size];
+ ssm.SerializeToArray(wireData, size);
+ m_ccnxHandle->publishRawData (name,
+ wireData,
+ size,
m_syncResponseFreshness); // in NS-3 it doesn't have any effect... yet
+ delete wireData;
// checking if our own interest got satisfied
bool satisfiedOwnInterest = false;
diff --git a/model/sync-state.cc b/model/sync-state.cc
index f6db146..137e8b0 100644
--- a/model/sync-state.cc
+++ b/model/sync-state.cc
@@ -30,7 +30,6 @@
#include <boost/throw_exception.hpp>
#include <boost/lexical_cast.hpp>
-#define TIXML_USE_STL
#include <tinyxml.h>
using namespace std;
@@ -42,12 +41,7 @@
namespace Sync {
-#ifdef _DEBUG
-#define DEBUG_ENDL os << "\n";
-#else
-#define DEBUG_ENDL
-#endif
-
+/*
std::ostream &
operator << (std::ostream &os, const State &state)
{
@@ -73,7 +67,39 @@
}
os << "</state>";
}
+*/
+SyncStateMsg &
+operator << (SyncStateMsg &ossm, const State &state)
+{
+ BOOST_FOREACH (shared_ptr<const Leaf> leaf, state.getLeaves ().get<ordered> ())
+ {
+ SyncState *oss = ossm.add_ss();
+ shared_ptr<const DiffLeaf> diffLeaf = dynamic_pointer_cast<const DiffLeaf> (leaf);
+ if (diffLeaf != 0 && diffLeaf->getOperation() != UPDATE)
+ {
+ oss->set_type(SyncState::DELETE);
+ }
+ else
+ {
+ oss->set_type(SyncState::UPDATE);
+ }
+
+ std::ostringstream os;
+ os << *leaf->getInfo();
+ oss->set_name(os.str());
+
+ if (diffLeaf == 0 || (diffLeaf != 0 && diffLeaf->getOperation () == UPDATE))
+ {
+ SyncState::SeqNo *seqNo = oss->mutable_seqno();
+ seqNo->set_session(leaf->getSeq().getSession());
+ seqNo->set_seq(leaf->getSeq().getSeq());
+ }
+ }
+ return ossm;
+}
+
+/*
std::istream &
operator >> (std::istream &in, State &state)
{
@@ -120,5 +146,29 @@
return in;
}
+*/
+
+SyncStateMsg &
+operator >> (SyncStateMsg &issm, State &state)
+{
+ int n = issm.ss_size();
+ for (int i = 0; i < n; i++)
+ {
+ const SyncState &ss = issm.ss(i);
+ NameInfoConstPtr info = StdNameInfo::FindOrCreate (ss.name());
+ if (ss.type() == SyncState::UPDATE)
+ {
+ uint32_t session = lexical_cast<uint32_t>(ss.seqno().session());
+ uint32_t seq = lexical_cast<uint32_t>(ss.seqno().seq());
+ SeqNo seqNo(session, seq);
+ state.update(info, seqNo);
+ }
+ else
+ {
+ state.remove(info);
+ }
+ }
+ return issm;
+}
}
diff --git a/sync-state.proto b/sync-state.proto
new file mode 100644
index 0000000..18892fb
--- /dev/null
+++ b/sync-state.proto
@@ -0,0 +1,24 @@
+package Sync;
+
+message SyncState
+{
+ required string name = 1;
+ enum ActionType
+ {
+ UPDATE = 0;
+ DELETE = 1;
+ OTHER = 2;
+ }
+ required ActionType type = 2;
+ message SeqNo
+ {
+ required uint32 seq = 1;
+ required uint32 session = 2;
+ }
+ optional SeqNo seqno = 3;
+}
+
+message SyncStateMsg
+{
+ repeated SyncState ss = 1;
+}
diff --git a/test/test_app_socket.cc b/test/test_app_socket.cc
index df3a3a8..473d117 100644
--- a/test/test_app_socket.cc
+++ b/test/test_app_socket.cc
@@ -211,7 +211,7 @@
s4.publishRaw(p4, 0,(const char *) num, sizeof(num), 10);
a1.setNum(p4, (const char *) num, sizeof (num));
- this_thread::sleep (posix_time::milliseconds (200));
+ this_thread::sleep (posix_time::milliseconds (1000));
BOOST_CHECK(a1.sum == a2.sum && a1.sum == 10);
int newNum[5] = {9, 7, 2, 1, 1};
diff --git a/test/test_state.cc b/test/test_state.cc.outdated
similarity index 100%
rename from test/test_state.cc
rename to test/test_state.cc.outdated
diff --git a/waf-tools/protobuf.py b/waf-tools/protobuf.py
new file mode 100644
index 0000000..71d8bdf
--- /dev/null
+++ b/waf-tools/protobuf.py
@@ -0,0 +1,76 @@
+#! /usr/bin/env python
+# encoding: utf-8
+
+'''
+
+When using this tool, the wscript will look like:
+
+ def options(opt):
+ opt.tool_options('protobuf', tooldir=["waf-tools"])
+
+ def configure(conf):
+ conf.load('compiler_cxx protobuf')
+
+ def build(bld):
+ bld(source='main.cpp', target='app', use='PROTOBUF')
+
+Options are generated, in order to specify the location of protobuf includes/libraries.
+
+
+'''
+import sys
+import re
+from waflib import Utils,Logs,Errors
+from waflib.Configure import conf
+PROTOBUF_DIR=['/usr','/usr/local','/opt/local','/sw']
+PROTOBUF_VERSION_FILE='google/protobuf/stubs/common.h'
+PROTOBUF_VERSION_CODE='''
+#include <iostream>
+#include <google/protobuf/stubs/common.h>
+int main() { std::cout << GOOGLE_PROTOBUF_VERSION ;}
+'''
+
+def options(opt):
+ opt.add_option('--protobuf',type='string',default='',dest='protobuf_dir',help='''path to where protobuf is installed, e.g. /usr/local''')
+@conf
+def __protobuf_get_version_file(self,dir):
+ try:
+ return self.root.find_dir(dir).find_node('%s/%s' % ('include', PROTOBUF_VERSION_FILE))
+ except:
+ return None
+@conf
+def protobuf_get_version(self,dir):
+ val=self.check_cxx(fragment=PROTOBUF_VERSION_CODE,includes=['%s/%s' % (dir, 'include')], execute=True, define_ret = True, mandatory=True)
+ return val
+@conf
+def protobuf_get_root(self,*k,**kw):
+ root=k and k[0]or kw.get('path',None)
+ # Logs.pprint ('RED', ' %s' %root)
+ if root and self.__protobuf_get_version_file(root):
+ return root
+ for dir in PROTOBUF_DIR:
+ if self.__protobuf_get_version_file(dir):
+ return dir
+ if root:
+ self.fatal('Protobuf not found in %s'%root)
+ else:
+ self.fatal('Protobuf not found, please provide a --protobuf argument (see help)')
+@conf
+def check_protobuf(self,*k,**kw):
+ if not self.env['CXX']:
+ self.fatal('load a c++ compiler first, conf.load("compiler_cxx")')
+
+ var=kw.get('uselib_store','PROTOBUF')
+ self.start_msg('Checking Protocol Buffer')
+ root = self.protobuf_get_root(*k,**kw);
+ self.env.PROTOBUF_VERSION=self.protobuf_get_version(root)
+
+ self.env['INCLUDES_%s'%var]= '%s/%s' % (root, "include");
+ self.env['LIB_%s'%var] = "protobuf"
+ self.env['LIBPATH_%s'%var] = '%s/%s' % (root, "lib")
+
+ self.end_msg(self.env.PROTOBUF_VERSION)
+ if Logs.verbose:
+ Logs.pprint('CYAN',' Protocol Buffer include : %s'%self.env['INCLUDES_%s'%var])
+ Logs.pprint('CYAN',' Protocol Buffer lib : %s'%self.env['LIB_%s'%var])
+ Logs.pprint('CYAN',' Protocol Buffer libpath : %s'%self.env['LIBPATH_%s'%var])
diff --git a/waf-tools/tinyxml.py b/waf-tools/tinyxml.py
deleted file mode 100644
index 3908b38..0000000
--- a/waf-tools/tinyxml.py
+++ /dev/null
@@ -1,76 +0,0 @@
-#! /usr/bin/env python
-# encoding: utf-8
-
-'''
-
-When using this tool, the wscript will look like:
-
- def options(opt):
- opt.tool_options('tinyxml', tooldir=["waf-tools"])
-
- def configure(conf):
- conf.load('compiler_cxx tiny')
-
- def build(bld):
- bld(source='main.cpp', target='app', use='TINYXML')
-
-Options are generated, in order to specify the location of tinyxml includes/libraries.
-
-
-'''
-import sys
-import re
-from waflib import Utils,Logs,Errors
-from waflib.Configure import conf
-TINYXML_DIR=['/usr','/usr/local','/opt/local','/sw']
-TINYXML_VERSION_FILE='tinyxml.h'
-TINYXML_VERSION_CODE='''
-#include <iostream>
-#include <tinyxml.h>
-int main() { std::cout << TIXML_MAJOR_VERSION << "." << TIXML_MINOR_VERSION << "." << TIXML_PATCH_VERSION; }
-'''
-
-def options(opt):
- opt.add_option('--tinyxml',type='string',default='',dest='tinyxml_dir',help='''path to where TinyXML is installed, e.g. /usr/local''')
-@conf
-def __tinyxml_get_version_file(self,dir):
- try:
- return self.root.find_dir(dir).find_node('%s/%s' % ('include', TINYXML_VERSION_FILE))
- except:
- return None
-@conf
-def tinyxml_get_version(self,dir):
- val=self.check_cxx(fragment=TINYXML_VERSION_CODE,includes=['%s/%s' % (dir, 'include')], execute=True, define_ret = True, mandatory=True)
- return val
-@conf
-def tinyxml_get_root(self,*k,**kw):
- root=k and k[0]or kw.get('path',None)
- # Logs.pprint ('RED', ' %s' %root)
- if root and self.__tinyxml_get_version_file(root):
- return root
- for dir in TINYXML_DIR:
- if self.__tinyxml_get_version_file(dir):
- return dir
- if root:
- self.fatal('TinyXML not found in %s'%root)
- else:
- self.fatal('TinyXML not found, please provide a --tinyxml argument (see help)')
-@conf
-def check_tinyxml(self,*k,**kw):
- if not self.env['CXX']:
- self.fatal('load a c++ compiler first, conf.load("compiler_cxx")')
-
- var=kw.get('uselib_store','TINYXML')
- self.start_msg('Checking TinyXML')
- root = self.tinyxml_get_root(*k,**kw);
- self.env.TINYXML_VERSION=self.tinyxml_get_version(root)
-
- self.env['INCLUDES_%s'%var]= '%s/%s' % (root, "include");
- self.env['LIB_%s'%var] = "tinyxml"
- self.env['LIBPATH_%s'%var] = '%s/%s' % (root, "lib")
-
- self.end_msg(self.env.TINYXML_VERSION)
- if Logs.verbose:
- Logs.pprint('CYAN',' TinyXML include : %s'%self.env['INCLUDES_%s'%var])
- Logs.pprint('CYAN',' TinyXML lib : %s'%self.env['LIB_%s'%var])
- Logs.pprint('CYAN',' TinyXML libpath : %s'%self.env['LIBPATH_%s'%var])
diff --git a/wscript b/wscript
index df97940..c87bf89 100644
--- a/wscript
+++ b/wscript
@@ -13,7 +13,7 @@
opt.load('compiler_cxx')
opt.load('boost')
opt.load('doxygen')
- opt.load('ccnx tinyxml ns3', tooldir=["waf-tools"])
+ opt.load('ccnx protobuf ns3', tooldir=["waf-tools"])
def configure(conf):
conf.load("compiler_cxx")
@@ -61,10 +61,18 @@
except:
pass
- conf.load('tinyxml')
- conf.check_tinyxml ()
+ conf.load('protobuf')
+ conf.check_protobuf (path=conf.options.protobuf_dir)
+
+def pre(bld):
+ bld.exec_command('protoc --cpp_out=. sync-state.proto')
+ bld.exec_command('mv sync-state.pb.h include/')
+ bld.exec_command('mv sync-state.pb.cc model/')
+
def build (bld):
+ bld.add_pre_fun(pre)
+
if bld.get_define ("NS3_MODULE"):
sync_ns3 = bld.shlib (
target = "sync-ns3",
@@ -91,8 +99,9 @@
'model/sync-seq-no.cc',
'model/sync-state.cc',
'model/sync-std-name-info.cc',
+ 'model/sync-state.pb.cc',
],
- use = 'BOOST BOOST_IOSTREAMS SSL TINYXML ' + ' '.join (['ns3_'+dep for dep in ['core', 'network', 'internet', 'NDNabstraction']]).upper (),
+ use = 'BOOST BOOST_IOSTREAMS SSL PROTOBUF ' + ' '.join (['ns3_'+dep for dep in ['core', 'network', 'internet', 'NDNabstraction']]).upper (),
includes = ['include', 'include/ns3', 'helper'],
)
@@ -139,8 +148,9 @@
'model/sync-seq-no.cc',
'model/sync-state.cc',
'model/sync-std-name-info.cc',
+ 'model/sync-state.pb.cc',
],
- use = 'BOOST BOOST_IOSTREAMS BOOST_THREAD SSL TINYXML CCNX',
+ use = 'BOOST BOOST_IOSTREAMS BOOST_THREAD SSL PROTOBUF CCNX',
includes = ['include', 'helper'],
)