You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/09/24 04:01:54 UTC
svn commit: r1000688 - in /subversion/branches/object-model/subversion:
bindings/c++/include/Types.h tests/libsvn++/util-test.cpp
Author: hwright
Date: Fri Sep 24 02:01:54 2010
New Revision: 1000688
URL: http://svn.apache.org/viewvc?rev=1000688&view=rev
Log:
On the object-model branch:
Attempt some reference-counting smart pointer magic to prevent pool
proliferation.
Note: This could probably stand with a bit of documentation.
* subversion/bindings/c++/include/Types.h
(RefCounter, CStructWrapper): New.
(CommitInfo): Use the CStructWrapper to hold the underlying commit_info
struct.
* subversion/tests/libsvn++/util-test.cpp
(test_struct_wrapping): New test.
(test_funcs): Run the new test.
Modified:
subversion/branches/object-model/subversion/bindings/c++/include/Types.h
subversion/branches/object-model/subversion/tests/libsvn++/util-test.cpp
Modified: subversion/branches/object-model/subversion/bindings/c++/include/Types.h
URL: http://svn.apache.org/viewvc/subversion/branches/object-model/subversion/bindings/c%2B%2B/include/Types.h?rev=1000688&r1=1000687&r2=1000688&view=diff
==============================================================================
--- subversion/branches/object-model/subversion/bindings/c++/include/Types.h (original)
+++ subversion/branches/object-model/subversion/bindings/c++/include/Types.h Fri Sep 24 02:01:54 2010
@@ -33,8 +33,10 @@
#include "svn_wc.h"
#include "svn_types.h"
+#include <stdlib.h>
#include <map>
#include <string>
+#include <iostream>
namespace SVN
{
@@ -42,34 +44,101 @@ namespace SVN
// Typedefs
typedef std::map<std::string, std::string> PropTable;
+namespace Private
+{
-// C-struct wrapper classes
-class CommitInfo
+// Magic
+template<typename C, typename T>
+class RefCounter
{
private:
Pool m_pool;
- svn_commit_info_t *m_info;
+ size_t count;
+ T *p;
public:
inline
- CommitInfo(const svn_commit_info_t *info)
- : m_pool()
+ RefCounter<C, T>(T *in)
+ : m_pool(),
+ count(1)
{
- m_info = svn_commit_info_dup(info, m_pool.pool());
+ p = C::dup(in, m_pool);
}
+ inline void inc_ref() { ++count; }
+ inline void dec_ref() { --count; }
+ inline T const *ptr() { return p; }
+ inline size_t refs() { return count; }
+
+ // The default destructor will destroy the Pool, and deallocate our object
+};
+
+template<typename C, typename T>
+class CStructWrapper
+{
+ private:
+ RefCounter<C, T> *m_data;
+
+ public:
inline
- CommitInfo(const CommitInfo &that)
- : m_pool()
+ CStructWrapper(T *data)
{
- m_info = svn_commit_info_dup(that.m_info, m_pool.pool());
+ m_data = new RefCounter<C, T>(data);
}
- inline CommitInfo&
- operator=(const CommitInfo &that)
+ inline
+ CStructWrapper(const CStructWrapper<C, T> &that)
+ {
+ m_data = that.m_data;
+ m_data->inc_ref();
+ }
+
+ inline CStructWrapper<C, T>&
+ operator= (const CStructWrapper<C, T> &that)
+ {
+ // Self assignment
+ if (&that == this)
+ return *this;
+
+ m_data->dec_ref();
+ if (m_data->refs() == 0)
+ delete m_data;
+ m_data = that.m_data;
+ m_data->inc_ref();
+
+ return *this;
+ }
+
+ inline ~CStructWrapper()
+ {
+ m_data->dec_ref();
+ if (m_data->refs() == 0)
+ delete m_data;
+ }
+
+ inline const T& operator* () const { return *m_data->ptr(); }
+ inline const T* operator-> () const { return m_data->ptr(); }
+};
+
+} // namespace Private
+
+// C-struct wrapper classes
+class CommitInfo
+{
+ private:
+ Private::CStructWrapper<CommitInfo, const svn_commit_info_t> m_info;
+
+ public:
+ inline static svn_commit_info_t *
+ dup(const svn_commit_info_t *info, Pool &pool)
+ {
+ return svn_commit_info_dup(info, pool.pool());
+ }
+
+ explicit inline
+ CommitInfo(const svn_commit_info_t *info)
+ : m_info(info)
{
- m_pool.clear();
- m_info = svn_commit_info_dup(that.m_info, m_pool.pool());
}
inline Revision
Modified: subversion/branches/object-model/subversion/tests/libsvn++/util-test.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/object-model/subversion/tests/libsvn%2B%2B/util-test.cpp?rev=1000688&r1=1000687&r2=1000688&view=diff
==============================================================================
--- subversion/branches/object-model/subversion/tests/libsvn++/util-test.cpp (original)
+++ subversion/branches/object-model/subversion/tests/libsvn++/util-test.cpp Fri Sep 24 02:01:54 2010
@@ -164,6 +164,37 @@ test_map_wrapping(apr_pool_t *p)
return SVN_NO_ERROR;
}
+static svn_error_t *
+test_struct_wrapping(apr_pool_t *p)
+{
+ apr_pool_t *subpool = svn_pool_create(p);
+ svn_commit_info_t *commit_info = svn_create_commit_info(subpool);
+
+ commit_info->author = "hwright";
+
+ CommitInfo info(commit_info);
+ svn_pool_destroy(subpool);
+
+ SVN_TEST_ASSERT(info.getAuthor() == "hwright");
+
+ CommitInfo info2(info);
+ SVN_TEST_ASSERT(info2.getAuthor() == "hwright");
+
+ CommitInfo *info3 = new CommitInfo(info2);
+ SVN_TEST_ASSERT(info3->getAuthor() == "hwright");
+
+ CommitInfo *info4 = new CommitInfo(*info3);
+ SVN_TEST_ASSERT(info4->getAuthor() == "hwright");
+
+ delete info3;
+ SVN_TEST_ASSERT(info.getAuthor() == "hwright");
+ SVN_TEST_ASSERT(info4->getAuthor() == "hwright");
+
+ delete info4;
+
+ return SVN_NO_ERROR;
+}
+
/* The test table. */
struct svn_test_descriptor_t test_funcs[] =
@@ -181,5 +212,7 @@ struct svn_test_descriptor_t test_funcs[
"test various vector to array transforms"),
SVN_TEST_PASS2(test_map_wrapping,
"test various map to hash transforms"),
+ SVN_TEST_PASS2(test_struct_wrapping,
+ "test our ref-counted struct wrappers"),
SVN_TEST_NULL
};