Adding experimental (and optional) support of log4cxx logging.

Also, adding a sample logging configuration
diff --git a/model/sync-ccnx-wrapper.cc b/model/sync-ccnx-wrapper.cc
index d531971..0fdff74 100644
--- a/model/sync-ccnx-wrapper.cc
+++ b/model/sync-ccnx-wrapper.cc
@@ -21,14 +21,19 @@
  */
 
 #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_      
@@ -113,6 +118,7 @@
 void
 CcnxWrapper::ccnLoop ()
 {
+  _LOG_FUNCTION (this);
 
   while (m_running)
     {
diff --git a/model/sync-diff-state-container.h b/model/sync-diff-state-container.h
index 9349e76..a5e5392 100644
--- a/model/sync-diff-state-container.h
+++ b/model/sync-diff-state-container.h
@@ -45,6 +45,7 @@
   std::size_t
   operator() (DigestConstPtr digest) const
   {
+    // std::cout << "digest->getHash: " << digest->getHash () << " (" << *digest << ")" << std::endl;
     return digest->getHash ();
   }
 };
@@ -54,6 +55,7 @@
   bool
   operator() (DigestConstPtr digest1, DigestConstPtr digest2) const
   {
+    // std::cout << boost::cref(*digest1) << " == " << boost::cref(*digest2) << " : " << (*digest1 == *digest2) << std::endl;
     return *digest1 == *digest2;
   }
 };
diff --git a/model/sync-log.cc b/model/sync-log.cc
new file mode 100644
index 0000000..0ddd95c
--- /dev/null
+++ b/model/sync-log.cc
@@ -0,0 +1,61 @@
+/* -*- 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
new file mode 100644
index 0000000..a2fcd70
--- /dev/null
+++ b/model/sync-log.h
@@ -0,0 +1,71 @@
+/* -*- 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.cc b/model/sync-logic.cc
index c81f2f1..088f8e3 100644
--- a/model/sync-logic.cc
+++ b/model/sync-logic.cc
@@ -23,6 +23,8 @@
 #include "sync-logic.h"
 #include "sync-diff-leaf.h"
 #include "sync-full-leaf.h"
+#include "sync-log.h"
+
 #include <boost/make_shared.hpp>
 #include <boost/foreach.hpp>
 #include <boost/lexical_cast.hpp>
@@ -32,6 +34,8 @@
 using namespace std;
 using namespace boost;
 
+INIT_LOGGER ("SyncLogic");
+
 namespace Sync
 {
 
@@ -43,16 +47,21 @@
   , m_onRemove (onRemove)
   , m_ccnxHandle(new CcnxWrapper())
   , m_randomGenerator (static_cast<unsigned int> (std::time (0)))
-  , m_rangeUniformRandom (m_randomGenerator, uniform_int<> (20,100))
+  , m_rangeUniformRandom (m_randomGenerator, uniform_int<> (10,50))
 {
+  _LOG_FUNCTION (syncPrefix);
+  
   m_ccnxHandle->setInterestFilter (m_syncPrefix,
                                    bind (&SyncLogic::respondSyncInterest, this, _1));
 
-  sendSyncInterest ();
+  m_scheduler.schedule (posix_time::seconds (0),
+                        bind (&SyncLogic::sendSyncInterest, this),
+                        REEXPRESSING_INTEREST);
 }
 
 SyncLogic::~SyncLogic ()
 {
+  _LOG_FUNCTION (this);
   // cout << "SyncLogic::~SyncLogic ()" << endl;
 
   m_ccnxHandle.reset ();
@@ -61,6 +70,7 @@
 void
 SyncLogic::respondSyncInterest (const string &interest)
 {
+  _LOG_TRACE ("<< I " << interest);
   //cout << "Respond Sync Interest" << endl;
   string hash = interest.substr(interest.find_last_of("/") + 1);
   // cout << "Received Sync Interest: " << hash << endl;
@@ -77,36 +87,47 @@
       return;
     }
 
-  processSyncInterest (digest, interest);
+  processSyncInterest (digest, interest, false);
 }
 
 void
 SyncLogic::processSyncInterest (DigestConstPtr digest, const std::string &interestName, bool timedProcessing/*=false*/)
 {
-  // cout << "SyncLogic::processSyncInterest " << timedProcessing << endl;
   recursive_mutex::scoped_lock lock (m_stateMutex);
 
-  if (*m_state.getDigest() == *digest)
-    {
-      // cout << interestName << "\n";
-      m_syncInterestTable.insert (interestName);
-      return;
-    }
-
   // Special case when state is not empty and we have received request with zero-root digest
-  if (digest->isZero ())
+  if (digest->isZero () && !m_state.getDigest()->isZero ())
     {
+      _LOG_TRACE (">> D " << interestName << "/state" << " (zero)");
+
       m_ccnxHandle->publishData (interestName + "/state",
                                  lexical_cast<string> (m_state),
                                  m_syncResponseFreshness);
       return;
     }
 
+  if (*m_state.getDigest() == *digest)
+    {
+      // cout << interestName << "\n";
+      if (digest->isZero ())
+        {
+          _LOG_TRACE ("Digest is zero, adding /state to PIT");
+          m_syncInterestTable.insert (interestName + "/state");
+        }
+      else
+        {
+          _LOG_TRACE ("Same state. Adding to PIT");
+          m_syncInterestTable.insert (interestName);
+        }
+      return;
+    }
   
   DiffStateContainer::iterator stateInDiffLog = m_log.find (digest);
 
   if (stateInDiffLog != m_log.end ())
   {
+    _LOG_TRACE (">> D " << interestName);
+    
     m_ccnxHandle->publishData (interestName,
                                lexical_cast<string> (*(*stateInDiffLog)->diff ()),
                                m_syncResponseFreshness);
@@ -115,6 +136,7 @@
 
   if (!timedProcessing)
     {
+      _LOG_DEBUG ("hmm");
       m_scheduler.schedule (posix_time::milliseconds (m_rangeUniformRandom ()) /*from 20 to 100ms*/,
                             bind (&SyncLogic::processSyncInterest, this, digest, interestName, true),
                             DELAYED_INTEREST_PROCESSING);
@@ -122,6 +144,8 @@
     }
   else
     {
+      _LOG_TRACE (">> D " << interestName << "/state" << " (timed processing)");
+      
       m_ccnxHandle->publishData (interestName + "/state",
                                  lexical_cast<string> (m_state),
                                  m_syncResponseFreshness);
@@ -131,7 +155,7 @@
 void
 SyncLogic::processSyncData (const string &name, const string &dataBuffer)
 {
-  // cout << "Process Sync Data" << endl;
+  _LOG_TRACE ("<< D " << name);
   DiffStatePtr diffLog = make_shared<DiffState> ();
   
   try
@@ -243,6 +267,7 @@
       ss << *diffLog;
       for (vector<string>::iterator ii = pis.begin(); ii != pis.end(); ++ii)
         {
+          _LOG_TRACE (">> D " << *ii);
           m_ccnxHandle->publishData (*ii, ss.str(), m_syncResponseFreshness);
         }
     }
@@ -260,6 +285,7 @@
   m_log.erase (m_state.getDigest()); // remove diff state with the same digest.  next pointers are still valid
   /// @todo Optimization
   m_log.insert (diffLog);
+  _LOG_DEBUG (*diffLog->getDigest () << " " << m_log.size ());
 }
 
 void
@@ -303,12 +329,14 @@
 void
 SyncLogic::sendSyncInterest ()
 {
-	//cout << "Sending Sync Interest" << endl;
+  // cout << "Sending Sync Interest" << endl;
   recursive_mutex::scoped_lock lock (m_stateMutex);
 
   ostringstream os;
   os << m_syncPrefix << "/" << *m_state.getDigest();
 
+  _LOG_TRACE (">> I " << os.str ());
+
   m_ccnxHandle->sendInterest (os.str (),
                               bind (&SyncLogic::processSyncData, this, _1, _2));
 
diff --git a/model/sync-scheduler.cc b/model/sync-scheduler.cc
index c5f1ca0..f54f91f 100644
--- a/model/sync-scheduler.cc
+++ b/model/sync-scheduler.cc
@@ -21,11 +21,13 @@
  */
 
 #include "sync-scheduler.h"
-#include <boost/date_time/posix_time/posix_time.hpp>
+#include "sync-log.h"
 
 using namespace boost;
 using namespace std;
 
+INIT_LOGGER ("Scheduler");
+
 namespace Sync {
 
 Scheduler::Scheduler ()
@@ -45,6 +47,7 @@
 void
 Scheduler::threadLoop ()
 {
+  _LOG_FUNCTION (this);
   while (m_threadRunning)
     {
       try