You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by be...@apache.org on 2014/10/27 06:34:18 UTC

[2/7] git commit: Added functionality to create SVN based diffs of arbitrary strings.

Added functionality to create SVN based diffs of arbitrary strings.

Review: https://reviews.apache.org/r/24535


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/3b3d60f0
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/3b3d60f0
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/3b3d60f0

Branch: refs/heads/master
Commit: 3b3d60f0dc605ff49a3eb2f0e546e4bbb2333b23
Parents: 61ce00f
Author: Benjamin Hindman <be...@gmail.com>
Authored: Sun Aug 10 11:15:56 2014 -0700
Committer: Benjamin Hindman <be...@gmail.com>
Committed: Sun Oct 26 22:33:32 2014 -0700

----------------------------------------------------------------------
 3rdparty/libprocess/3rdparty/Makefile.am        |   8 +-
 3rdparty/libprocess/3rdparty/stout/Makefile.am  |   1 +
 .../3rdparty/stout/include/Makefile.am          |   1 +
 .../3rdparty/stout/include/stout/svn.hpp        | 192 +++++++++++++++++++
 .../3rdparty/stout/tests/svn_tests.cpp          |  74 +++++++
 5 files changed, 275 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/3b3d60f0/3rdparty/libprocess/3rdparty/Makefile.am
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/Makefile.am b/3rdparty/libprocess/3rdparty/Makefile.am
index 1e24886..4c6b2f1 100644
--- a/3rdparty/libprocess/3rdparty/Makefile.am
+++ b/3rdparty/libprocess/3rdparty/Makefile.am
@@ -146,6 +146,7 @@ stout_tests_SOURCES =				\
   $(STOUT)/tests/base64_tests.cpp		\
   $(STOUT)/tests/bytes_tests.cpp		\
   $(STOUT)/tests/cache_tests.cpp		\
+  $(STOUT)/tests/svn_tests.cpp			\
   $(STOUT)/tests/duration_tests.cpp		\
   $(STOUT)/tests/dynamiclibrary_tests.cpp	\
   $(STOUT)/tests/error_tests.cpp		\
@@ -185,6 +186,8 @@ endif
 stout_tests_CPPFLAGS =				\
   -I$(srcdir)/$(STOUT)/include			\
   -I$(PROTOBUF)/src				\
+  -I/usr/include/subversion-1			\
+  -I/usr/include/apr-1				\
   $(AM_CPPFLAGS)
 
 if WITH_BUNDLED_GMOCK
@@ -211,7 +214,10 @@ stout_tests_LDADD =			\
   libgmock.la				\
   $(LIBGLOG)				\
   $(LIBPROTOBUF)			\
-  -ldl
+  -ldl					\
+  -lsvn_subr-1				\
+  -lsvn_delta-1				\
+  -lapr-1
 
 # We use a check-local target for now to avoid the parallel test
 # runner that ships with newer versions of autotools.

http://git-wip-us.apache.org/repos/asf/mesos/blob/3b3d60f0/3rdparty/libprocess/3rdparty/stout/Makefile.am
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/Makefile.am b/3rdparty/libprocess/3rdparty/stout/Makefile.am
index 4136062..e0a7838 100644
--- a/3rdparty/libprocess/3rdparty/stout/Makefile.am
+++ b/3rdparty/libprocess/3rdparty/stout/Makefile.am
@@ -43,6 +43,7 @@ EXTRA_DIST =					\
   tests/some_tests.cpp				\
   tests/strings_tests.cpp			\
   tests/subcommand_tests.cpp			\
+  tests/svn_tests.cpp				\
   tests/thread_tests.cpp			\
   tests/uuid_tests.cpp				\
   tests/version_tests.cpp

http://git-wip-us.apache.org/repos/asf/mesos/blob/3b3d60f0/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/Makefile.am b/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
index d529013..3048e84 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
+++ b/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
@@ -67,6 +67,7 @@ nobase_include_HEADERS =		\
   stout/stringify.hpp			\
   stout/strings.hpp			\
   stout/subcommand.hpp			\
+  stout/svn.hpp				\
   stout/tests/utils.hpp			\
   stout/thread.hpp			\
   stout/try.hpp				\

http://git-wip-us.apache.org/repos/asf/mesos/blob/3b3d60f0/3rdparty/libprocess/3rdparty/stout/include/stout/svn.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/svn.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/svn.hpp
new file mode 100644
index 0000000..db0e7e2
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/svn.hpp
@@ -0,0 +1,192 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_SVN_HPP__
+#define __STOUT_SVN_HPP__
+
+#include <apr_pools.h>
+
+#include <stdlib.h>
+
+#include <svn_delta.h>
+#include <svn_error.h>
+#include <svn_pools.h>
+
+#include <string>
+
+#include <stout/try.hpp>
+
+namespace svn {
+
+struct Diff
+{
+  Diff(const std::string& data) : data(data) {}
+
+  std::string data;
+};
+
+
+// Note, this function is exposed publicly in the event that someone
+// wants to coordinate the intialization of APR done automatically by
+// calls to svn::diff, svn::patch, etc. That is, if you're using the
+// svn::* functions in your code and you're also using APR you can
+// initialize the APR before you start doing things with threads that
+// might call svn::* functions.
+inline void initialize()
+{
+  // We use a static variable to initialize the Apache Portable
+  // Runtime (APR) library in a thread-safe way (at least with respect
+  // to calls within svn::* since there is no way to guarantee that
+  // another library isn't concurrently initializing the APR). Thread
+  // safety is provided by the fact that the static variable 'apr'
+  // should get constructed (i.e., the APR constructor invoked) and
+  // destructed in a thread safe way (as of GCC 4.3 and required for
+  // C++11).
+  struct APR
+  {
+    APR()
+    {
+      apr_initialize();
+    }
+
+    ~APR()
+    {
+      apr_terminate();
+    }
+  };
+
+  static APR apr;
+}
+
+
+inline Try<Diff> diff(const std::string& from, const std::string& to)
+{
+  // Initialize the Apache Portable Runtime subsystem, as necessary
+  // for using the svn library.
+  initialize();
+
+  // Note that svn_pool_create wraps apr_pool_create_ex, which is
+  // thread safe, see: http://goo.gl/NX0hps.
+  apr_pool_t* pool = svn_pool_create(NULL);
+
+  // First we need to produce a text delta stream by diffing 'source'
+  // against 'target'.
+  svn_string_t source;
+  source.data = from.data();
+  source.len = from.length();
+
+  svn_string_t target;
+  target.data = to.data();
+  target.len = to.length();
+
+  svn_txdelta_stream_t* delta;
+  svn_txdelta(
+      &delta,
+      svn_stream_from_string(&source, pool),
+      svn_stream_from_string(&target, pool),
+      pool);
+
+  // Now we want to convert this text delta stream into an svndiff
+  // format based diff. Setup the handler that will consume the text
+  // delta and produce the svndiff.
+  svn_txdelta_window_handler_t handler;
+  void* baton = NULL;
+  svn_stringbuf_t* diff = svn_stringbuf_create_ensure(1024, pool);
+
+  svn_txdelta_to_svndiff2(
+      &handler,
+      &baton,
+      svn_stream_from_stringbuf(diff, pool),
+      0,
+      pool);
+
+  // Now feed the text delta to the handler.
+  svn_error_t* error = svn_txdelta_send_txstream(delta, handler, baton, pool);
+
+  if (error != NULL) {
+    char buffer[1024];
+    std::string message(svn_err_best_message(error, buffer, 1024));
+    svn_pool_destroy(pool);
+    return Error(message);
+  }
+
+  Diff d(std::string(diff->data, diff->len));
+
+  svn_pool_destroy(pool);
+
+  return d;
+}
+
+
+inline Try<std::string> patch(const std::string& s, const Diff& diff)
+{
+  // Initialize the Apache Portable Runtime subsystem, as necessary
+  // for using the svn library.
+  initialize();
+
+  // Note that svn_pool_create wraps apr_pool_create_ex, which is
+  // thread safe, see: http://goo.gl/NX0hps.
+  apr_pool_t* pool = svn_pool_create(NULL);
+
+  // We want to apply the svndiff format diff to the source trying to
+  // produce a result. First setup a handler for applying a text delta
+  // to the source stream.
+  svn_string_t source;
+  source.data = s.data();
+  source.len = s.length();
+
+  svn_txdelta_window_handler_t handler;
+  void* baton = NULL;
+
+  svn_stringbuf_t* patched = svn_stringbuf_create_ensure(s.length(), pool);
+
+  svn_txdelta_apply(
+      svn_stream_from_string(&source, pool),
+      svn_stream_from_stringbuf(patched, pool),
+      NULL,
+      NULL,
+      pool,
+      &handler,
+      &baton);
+
+  // Setup a stream that converts an svndiff format diff to a text
+  // delta, so that we can use our handler to patch the source string.
+  svn_stream_t* stream = svn_txdelta_parse_svndiff(
+      handler,
+      baton,
+      TRUE,
+      pool);
+
+  // Now feed the diff into the stream to compute the patched result.
+  const char* data = diff.data.data();
+  apr_size_t length = diff.data.length();
+
+  svn_error_t* error = svn_stream_write(stream, data, &length);
+
+  if (error != NULL) {
+    char buffer[1024];
+    std::string message(svn_err_best_message(error, buffer, 1024));
+    svn_pool_destroy(pool);
+    return Error(message);
+  }
+
+  std::string result(patched->data, patched->len);
+
+  svn_pool_destroy(pool);
+
+  return result;
+}
+
+} // namespace svn {
+
+#endif // __STOUT_SVN_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/3b3d60f0/3rdparty/libprocess/3rdparty/stout/tests/svn_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/svn_tests.cpp b/3rdparty/libprocess/3rdparty/stout/tests/svn_tests.cpp
new file mode 100644
index 0000000..d5e0f6e
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/tests/svn_tests.cpp
@@ -0,0 +1,74 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <cstdlib> // For rand().
+#include <string>
+
+#include <stout/bytes.hpp>
+#include <stout/gtest.hpp>
+#include <stout/svn.hpp>
+
+using std::string;
+
+
+TEST(SVN, DiffPatch)
+{
+  string source;
+
+  while (Bytes(source.size()) < Megabytes(1)) {
+    source += (char) rand() % 256;
+  }
+
+  // Make the target string have 512 different bytes in the middle.
+  string target = source;
+
+  for (size_t index = 0; index < 512; index++) {
+    target[1024 + index] = (char) rand() % 256;
+  }
+
+  ASSERT_NE(source, target);
+
+  Try<svn::Diff> diff = svn::diff(source, target);
+
+  ASSERT_SOME(diff);
+
+  Try<string> result = svn::patch(source, diff.get());
+
+  ASSERT_SOME_EQ(target, result);
+  ASSERT_SOME_NE(source, result);
+}
+
+
+TEST(SVN, EmptyDiffPatch)
+{
+  string source;
+
+  while (Bytes(source.size()) < Megabytes(1)) {
+    source += (char) rand() % 256;
+  }
+
+  // Make the target string equal the source string.
+  string target = source;
+
+  Try<svn::Diff> diff = svn::diff(source, target);
+
+  ASSERT_SOME(diff);
+
+  Try<string> result = svn::patch(source, diff.get());
+
+  ASSERT_SOME_EQ(target, result);
+  ASSERT_SOME_EQ(source, result);
+}