Checkpoint
diff --git a/model/sync-diff-leaf.cc b/model/sync-diff-leaf.cc
index 2680859..59e0fc1 100644
--- a/model/sync-diff-leaf.cc
+++ b/model/sync-diff-leaf.cc
@@ -19,3 +19,21 @@
* 卞超轶 Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
+
+#include "sync-diff-leaf.h"
+
+namespace Sync {
+
+DiffLeaf::DiffLeaf (NameInfoConstPtr info, const SeqNo &seq)
+ : Leaf (info, seq)
+ , m_op (UPDATE)
+{
+}
+
+DiffLeaf::DiffLeaf (NameInfoConstPtr info)
+ : Leaf (info, SeqNo (0,0))
+ , m_op (REMOVE)
+{
+}
+
+}
diff --git a/model/sync-diff-leaf.h b/model/sync-diff-leaf.h
index 4ebc6d5..084b5fc 100644
--- a/model/sync-diff-leaf.h
+++ b/model/sync-diff-leaf.h
@@ -49,11 +49,7 @@
* @param info Smart pointer to leaf's name
* @param seq Initial sequence number of the pointer
*/
- DiffLeaf (boost::shared_ptr<const NameInfo> info, const SeqNo &seq)
- : Leaf (info, seq)
- , m_op (UPDATE)
- {
- }
+ DiffLeaf (NameInfoConstPtr info, const SeqNo &seq);
/**
* @brief Constructor to create an REMOVE diff leaf
@@ -62,22 +58,16 @@
* This constructor creates a leaf with phony sequence number
* with 0 session ID and 0 sequence number
*/
- DiffLeaf (boost::shared_ptr<const NameInfo> info)
- : Leaf (info, SeqNo (0,0))
- , m_op (REMOVE)
- {
- }
+ DiffLeaf (NameInfoConstPtr info);
- virtual ~DiffLeaf ()
- {
- }
+ virtual ~DiffLeaf () { }
+ /**
+ * @brief Get diff leaf type
+ */
Operation
- getOperation () const
- {
- return m_op;
- }
-
+ getOperation () const { return m_op; }
+
private:
Operation m_op;
};
diff --git a/model/sync-digest.cc b/model/sync-digest.cc
index a499659..4004614 100644
--- a/model/sync-digest.cc
+++ b/model/sync-digest.cc
@@ -36,9 +36,7 @@
{
m_context = EVP_MD_CTX_create ();
- int ok = EVP_DigestInit_ex (m_context, EVP_sha1 (), 0);
- if (!ok)
- throw DigestCalculationError () << errinfo_at_line (__LINE__);
+ reset ();
}
Digest::~Digest ()
@@ -50,7 +48,22 @@
}
void
-Digest::Finalize ()
+Digest::reset ()
+{
+ if (m_buffer != 0)
+ {
+ delete [] m_buffer;
+ m_buffer = 0;
+ }
+
+ int ok = EVP_DigestInit_ex (m_context, EVP_sha1 (), 0);
+ if (!ok)
+ throw DigestCalculationError () << errinfo_at_line (__LINE__);
+}
+
+
+void
+Digest::finalize ()
{
if (m_buffer != 0) return;
@@ -66,7 +79,7 @@
Digest::getHash ()
{
if (m_buffer == 0)
- Finalize ();
+ finalize ();
NS_ASSERT (sizeof (std::size_t) <= m_hashLength);
@@ -79,10 +92,10 @@
Digest::operator == (Digest &digest)
{
if (m_buffer == 0)
- Finalize ();
+ finalize ();
if (digest.m_buffer == 0)
- digest.Finalize ();
+ digest.finalize ();
NS_ASSERT (m_hashLength == digest.m_hashLength);
@@ -90,16 +103,27 @@
}
+void
+Digest::update (const uint8_t *buffer, size_t size)
+{
+ // cannot update Digest when it has been finalized
+ if (m_buffer != 0)
+ throw DigestCalculationError () << errinfo_at_line (__LINE__);
+
+ bool ok = EVP_DigestUpdate (m_context, buffer, size);
+ if (!ok)
+ throw DigestCalculationError () << errinfo_at_line (__LINE__);
+}
+
+
Digest &
Digest::operator << (const Digest &src)
{
- if (src.m_buffer == 0)
+ if (src.m_buffer == 0)
throw DigestCalculationError () << errinfo_at_line (__LINE__);
- bool ok = EVP_DigestUpdate (m_context, src.m_buffer, src.m_hashLength);
- if (!ok)
- throw DigestCalculationError () << errinfo_at_line (__LINE__);
-
+ update (src.m_buffer, src.m_hashLength);
+
return *this;
}
diff --git a/model/sync-digest.h b/model/sync-digest.h
index fca9798..d0c76f5 100644
--- a/model/sync-digest.h
+++ b/model/sync-digest.h
@@ -44,6 +44,12 @@
Digest ();
/**
+ * @brief Reset digest to the initial state
+ */
+ void
+ reset ();
+
+ /**
* @brief Destructor
*/
~Digest ();
@@ -65,7 +71,7 @@
operator == (Digest &digest);
/**
- * @brief Combine digests
+ * @brief Add existing digest to digest calculation
* @param src digest to combine with
*
* The result of this combination is hash (hash (...))
@@ -73,14 +79,42 @@
Digest &
operator << (const Digest &src);
+ /**
+ * @brief Add string to digest calculation
+ * @param str string to put into digest
+ */
+ inline Digest &
+ operator << (const std::string &str);
-
+ inline Digest &
+ operator << (uint32_t value);
+
+ // /**
+ // * @brief Add integer to digest calculation
+ // * @param value the value to add to the digest
+ // */
+ // template<class INT>
+ // inline Digest &
+ // operator << (INT value);
private:
/**
+ * @brief Disabled copy operator
+ */
+ Digest &
+ operator = (Digest &digest) { return *this; }
+
+ /**
* @brief Finalize digest. All subsequent calls to "operator <<" will fire an exception
*/
- void Finalize ();
+ void
+ finalize ();
+
+ /**
+ * @brief Add size bytes of buffer to the hash
+ */
+ void
+ update (const uint8_t *buffer, size_t size);
private:
EVP_MD_CTX *m_context;
@@ -90,6 +124,30 @@
struct DigestCalculationError : virtual boost::exception { };
+
+Digest &
+Digest::operator << (const std::string &str)
+{
+ update (reinterpret_cast<const uint8_t*> (str.c_str ()), str.size ());
+ return *this;
+}
+
+inline Digest &
+Digest::operator << (uint32_t value)
+{
+ update (reinterpret_cast<const uint8_t*> (&value), sizeof (uint32_t));
+ return *this;
+}
+
+// template<class INT>
+// Digest &
+// Digest::operator << (INT value)
+// {
+// update (&value, sizeof (INT));
+// return *this;
+// }
+
+
} // Sync
#endif // SYNC_DIGEST_H
diff --git a/model/sync-full-leaf.cc b/model/sync-full-leaf.cc
new file mode 100644
index 0000000..f575056
--- /dev/null
+++ b/model/sync-full-leaf.cc
@@ -0,0 +1,51 @@
+/* -*- 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-full-leaf.h"
+#include <boost/ref.hpp>
+
+using namespace boost;
+
+namespace Sync {
+
+FullLeaf::FullLeaf (NameInfoConstPtr info, const SeqNo &seq)
+ : Leaf (info, seq)
+{
+ updateDigest ();
+}
+
+void
+FullLeaf::updateDigest ()
+{
+ m_digest.reset ();
+ m_digest << getInfo ().getDigest () << getSeq ().getDigest ();
+}
+
+// from Leaf
+void
+FullLeaf::setSeq (const SeqNo &seq)
+{
+ Leaf::setSeq (seq);
+ updateDigest ();
+}
+
+} // Sync
diff --git a/model/sync-full-leaf.h b/model/sync-full-leaf.h
new file mode 100644
index 0000000..2851c84
--- /dev/null
+++ b/model/sync-full-leaf.h
@@ -0,0 +1,70 @@
+/* -*- 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_FULL_LEAF_H
+#define SYNC_FULL_LEAF_H
+
+#include "sync-leaf.h"
+
+namespace Sync {
+
+/**
+ * @ingroup sync
+ * @brief SYNC leaf for the full state (with support of Digest calculation)
+ */
+class FullLeaf : public Leaf
+{
+public:
+ /**
+ * @brief Constructor to create an UPDATE diff leaf
+ * @param info Smart pointer to leaf's name
+ * @param seq Initial sequence number of the pointer
+ */
+ FullLeaf (NameInfoConstPtr info, const SeqNo &seq);
+ virtual ~FullLeaf () { }
+
+ /**
+ * @brief Get hash digest of the leaf
+ *
+ * The underlying Digest object is recalculated on every update or removal
+ * (including updates of child classes)
+ */
+ const Digest &
+ getDigest () const { return m_digest; }
+
+ // from Leaf
+ virtual void
+ setSeq (const SeqNo &seq);
+
+private:
+ void
+ updateDigest ();
+
+private:
+ Digest m_digest;
+};
+
+typedef boost::shared_ptr<FullLeaf> FullLeafPtr;
+
+} // Sync
+
+#endif // SYNC_FULL_LEAF_H
diff --git a/model/sync-leaf.cc b/model/sync-leaf.cc
index 2680859..6ff48bc 100644
--- a/model/sync-leaf.cc
+++ b/model/sync-leaf.cc
@@ -19,3 +19,21 @@
* 卞超轶 Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
+
+#include "sync-leaf.h"
+
+namespace Sync {
+
+Leaf::Leaf (NameInfoConstPtr info, const SeqNo &seq)
+ : m_info (info)
+ , m_seq (seq)
+{
+}
+
+void
+Leaf::setSeq (const SeqNo &seq)
+{
+ m_seq = std::max (m_seq, seq);
+}
+
+} // Sync
diff --git a/model/sync-leaf.h b/model/sync-leaf.h
index 79e6b45..a4c64cf 100644
--- a/model/sync-leaf.h
+++ b/model/sync-leaf.h
@@ -40,32 +40,20 @@
* @param info Smart pointer to leaf's name
* @param seq Initial sequence number of the pointer
*/
- Leaf (boost::shared_ptr<const NameInfo> info, const SeqNo &seq)
- : m_info (info)
- , m_seq (seq)
- { }
-
- virtual ~Leaf ()
- {
- }
+ Leaf (NameInfoConstPtr info, const SeqNo &seq);
+ virtual ~Leaf () { }
/**
* @brief Get name of the leaf
*/
const NameInfo &
- getInfo () const
- {
- return *m_info;
- }
+ getInfo () const { return *m_info; }
/**
* @brief Get sequence number of the leaf
*/
const SeqNo&
- getSeq () const
- {
- return m_seq;
- }
+ getSeq () const { return m_seq; }
/**
* @brief Update sequence number of the leaf
@@ -73,11 +61,8 @@
*
* Sequence number is updated to the largest value among this->m_seq and seq
*/
- void
- setSeq (const SeqNo &seq)
- {
- m_seq = std::max (m_seq, seq);
- }
+ virtual void
+ setSeq (const SeqNo &seq);
private:
NameInfoConstPtr m_info;
diff --git a/model/sync-ns3-name-info.cc b/model/sync-ns3-name-info.cc
index 459486f..dc3b561 100644
--- a/model/sync-ns3-name-info.cc
+++ b/model/sync-ns3-name-info.cc
@@ -23,6 +23,7 @@
#include "sync-ns3-name-info.h"
#include "ns3/ccnx-name-components.h"
+#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
#include <utility>
@@ -31,6 +32,7 @@
namespace Sync {
+
NameInfoConstPtr
Ns3NameInfo::FindOrCreate (ns3::Ptr<const ns3::CcnxNameComponents> name)
{
@@ -47,7 +49,8 @@
: m_name (name)
{
m_id = m_ids ++; // set ID for a newly inserted element
- // m_digest << *name;
+ m_digest << *name;
+ m_digest.getHash (); // finalize digest
}
string
@@ -69,5 +72,20 @@
}
}
+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
diff --git a/model/sync-ns3-name-info.h b/model/sync-ns3-name-info.h
index ffc26d5..3931c5b 100644
--- a/model/sync-ns3-name-info.h
+++ b/model/sync-ns3-name-info.h
@@ -64,6 +64,9 @@
ns3::Ptr<const ns3::CcnxNameComponents> m_name;
};
+Digest &
+operator << (Digest &, const ns3::CcnxNameComponents &name);
+
} // Sync
#endif // SYNC_CCNX_NAME_INFO_H
diff --git a/model/sync-seq-no.h b/model/sync-seq-no.h
index bc6fc0f..fb9e6b8 100644
--- a/model/sync-seq-no.h
+++ b/model/sync-seq-no.h
@@ -24,6 +24,7 @@
#define SYNC_SEQ_NO_H
#include <boost/cstdint.hpp>
+#include "sync-digest.h"
namespace Sync {
@@ -32,7 +33,7 @@
*
*
*/
-struct SeqNo
+class SeqNo
{
public:
/**
@@ -53,23 +54,9 @@
: m_session (session)
, m_seq (seq)
{ }
-
- /**
- * @brief Session ID (e.g., after crash, application will choose new session ID.
- *
- * Note that session IDs for the same name should always increase. So, the good choice
- * for the session ID is client's timestamp
- */
- uint32_t m_session;
- /**
- * @brief Sequence number
- *
- * Sequence number for a session always starts with 0 and goes to max value.
- *
- * For now, wrapping sequence number after max to zero is not supported
- */
- uint32_t m_seq;
+ inline Digest
+ getDigest () const;
/**
* @brief Compare if one sequence number is lower
@@ -94,8 +81,57 @@
{
return m_session == seq.m_session && m_seq == seq.m_seq;
}
+
+ SeqNo &
+ operator = (const SeqNo &seq)
+ {
+ m_session = seq.m_session;
+ m_seq = seq.m_seq;
+
+ return *this;
+ }
+
+private:
+ inline void
+ updateDigest ();
+
+private:
+ /**
+ * @brief Session ID (e.g., after crash, application will choose new session ID.
+ *
+ * Note that session IDs for the same name should always increase. So, the good choice
+ * for the session ID is client's timestamp
+ */
+ uint32_t m_session;
+
+ /**
+ * @brief Sequence number
+ *
+ * Sequence number for a session always starts with 0 and goes to max value.
+ *
+ * For now, wrapping sequence number after max to zero is not supported
+ */
+ uint32_t m_seq;
+
+ Digest m_digest;
};
+
+void
+SeqNo::updateDigest ()
+{
+ m_digest.reset ();
+ m_digest << m_session << m_seq;
+}
+
+Digest
+SeqNo::getDigest () const
+{
+ Digest digest;
+ return digest;
+}
+
+
} // Sync
#endif // SYNC_SEQ_NO_H