#
#
# add_file "intrusive_ptr.hh"
# content [fab77279c4bd359d34092b0386576cfe7a274ac2]
#
# patch "database.cc"
# from [45a853c398d98224ff998f8769cf4dcbbb0a7d40]
# to [c6ab3d8eaef1299724b739a97b07ffb1d3a3cb7b]
#
# patch "pcrewrap.hh"
# from [bcb9af0ef76ffbf353ee409ba9f071971584e157]
# to [fb737d8451af1743d4f880a1488c23a59107a481]
#
# patch "unit-tests/xdelta.cc"
# from [a0183bed5c69963c3a39531792657ba3b97b763b]
# to [f3ed971854fb0b36336c9628a550f97dbacfc2b8]
#
# patch "xdelta.cc"
# from [5094e62fb1c7881a0b8da6331f2fc7488a342146]
# to [7bb0ace9b1deb1fff95ac7aca6a95514d48a09e3]
#
# patch "xdelta.hh"
# from [59ad94776aa99040452c7f678b9c642ccbb29ec0]
# to [8b260b196ba13de6bc65c166cc235890c40cc5b7]
#
============================================================
--- intrusive_ptr.hh fab77279c4bd359d34092b0386576cfe7a274ac2
+++ intrusive_ptr.hh fab77279c4bd359d34092b0386576cfe7a274ac2
@@ -0,0 +1,52 @@
+// Copyright (C) 2009 Zack Weinberg
+//
+// This program is made available under the GNU GPL version 2.0 or
+// greater. See the accompanying file COPYING for details.
+//
+// This program is distributed WITHOUT ANY WARRANTY; without even the
+// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE.
+
+#ifndef __INTRUSIVE_PTR_HH__
+#define __INTRUSIVE_PTR_HH__
+
+#include
+#include "sanity.hh"
+
+// By convention, intrusively reference-counted objects should have a
+// private member of type intrusive_refcnt_t, named "refcnt", and be
+// friends with these functions. Since monotone is single-threaded,
+// we do not worry about locking.
+
+typedef long intrusive_refcnt_t;
+
+template inline void intrusive_ptr_add_ref(T * ptr)
+{
+ ptr->refcnt++;
+ I(ptr->refcnt > 0);
+}
+
+template inline void intrusive_ptr_release(T * ptr)
+{
+ ptr->refcnt--;
+ I(ptr->refcnt >= 0);
+ if (ptr->refcnt == 0)
+ delete ptr;
+}
+
+// This base class takes care of the above conventions for you.
+// Note that intrusive_ptr_add_ref/release still need to be template
+// functions, as one must apply delete to a pointer with the true type
+// of the object.
+
+class intrusively_refcounted
+{
+ intrusive_refcnt_t refcnt;
+ // sadly, no way to say "any subclass of this"
+ template friend void intrusive_ptr_add_ref(T *);
+ template friend void intrusive_ptr_release(T *);
+public:
+ intrusively_refcounted() : refcnt(0) {}
+};
+
+#endif // intrusive_ptr.hh
============================================================
--- database.cc 45a853c398d98224ff998f8769cf4dcbbb0a7d40
+++ database.cc c6ab3d8eaef1299724b739a97b07ffb1d3a3cb7b
@@ -86,6 +86,7 @@ using std::accumulate;
using std::vector;
using std::accumulate;
+using boost::intrusive_ptr;
using boost::shared_ptr;
using boost::shared_dynamic_cast;
using boost::lexical_cast;
@@ -1828,7 +1829,7 @@ database_impl::get_version(id const & id
else
get_file_or_manifest_base_unchecked(curr, begin, data_table);
- shared_ptr appl = new_piecewise_applicator();
+ intrusive_ptr appl = new_piecewise_applicator();
appl->begin(begin());
for (reconstruction_path::reverse_iterator i = selected_path.rbegin();
============================================================
--- pcrewrap.hh bcb9af0ef76ffbf353ee409ba9f071971584e157
+++ pcrewrap.hh fb737d8451af1743d4f880a1488c23a59107a481
@@ -53,8 +53,7 @@ namespace pcre
{
private:
// disable the default and copy constructors - we never need to copy
- // these, and this lets us use bare pointers below instead of
- // boost::shared_ptr.
+ // these. This makes it safe to use bare pointers below.
regex();
regex(regex const &);
regex & operator=(regex const &);
============================================================
--- unit-tests/xdelta.cc a0183bed5c69963c3a39531792657ba3b97b763b
+++ unit-tests/xdelta.cc f3ed971854fb0b36336c9628a550f97dbacfc2b8
@@ -21,7 +21,7 @@ using std::string;
boost::uniform_smallint xdelta_lengen(1, 256);
using std::string;
-using boost::shared_ptr;
+using boost::intrusive_ptr;
UNIT_TEST(basic)
{
@@ -48,7 +48,7 @@ apply_via_piecewise(string const & base,
static string
apply_via_piecewise(string const & base, string const & delta)
{
- shared_ptr appl = new_piecewise_applicator();
+ intrusive_ptr appl = new_piecewise_applicator();
appl->begin(base);
apply_delta(appl, delta);
appl->next();
@@ -170,7 +170,7 @@ UNIT_TEST(random_piecewise_delta)
{
string prev, next, got;
xdelta_random_string(prev);
- shared_ptr appl = new_piecewise_applicator();
+ intrusive_ptr appl = new_piecewise_applicator();
appl->begin(prev);
for (int j = 0; j < 5; ++j)
{
============================================================
--- xdelta.cc 5094e62fb1c7881a0b8da6331f2fc7488a342146
+++ xdelta.cc 7bb0ace9b1deb1fff95ac7aca6a95514d48a09e3
@@ -51,6 +51,7 @@ using std::lower_bound;
using std::memcmp;
using std::lower_bound;
+using boost::intrusive_ptr;
using boost::shared_ptr;
struct identity {size_t operator()(u32 const & v) const { return static_cast(v);}};
@@ -398,7 +399,7 @@ void
}
void
-apply_delta(shared_ptr da,
+apply_delta(intrusive_ptr da,
string const & delta)
{
string::const_iterator i = delta.begin();
@@ -444,7 +445,7 @@ apply_delta(string const & a,
string const & delta,
string & b)
{
- shared_ptr da(new simple_applicator());
+ intrusive_ptr da(new simple_applicator());
da->begin(a);
apply_delta(da, delta);
da->next();
@@ -695,16 +696,16 @@ piecewise_applicator
// these just hide our implementation types from outside
-shared_ptr
+intrusive_ptr
new_simple_applicator()
{
- return shared_ptr(new simple_applicator());
+ return intrusive_ptr(new simple_applicator());
}
-shared_ptr
+intrusive_ptr
new_piecewise_applicator()
{
- return shared_ptr(new piecewise_applicator());
+ return intrusive_ptr(new piecewise_applicator());
}
@@ -813,7 +814,8 @@ invert_xdelta(string const & old_str,
string const & delta,
string & delta_inverse)
{
- shared_ptr da(new inverse_delta_writing_applicator(old_str));
+ intrusive_ptr
+ da(new inverse_delta_writing_applicator(old_str));
apply_delta(da, delta);
da->finish(delta_inverse);
}
============================================================
--- xdelta.hh 59ad94776aa99040452c7f678b9c642ccbb29ec0
+++ xdelta.hh 8b260b196ba13de6bc65c166cc235890c40cc5b7
@@ -10,7 +10,7 @@
#ifndef __XDELTA_HH__
#define __XDELTA_HH__
-#include
+#include "intrusive_ptr.hh"
#include "vocab.hh"
void
@@ -35,7 +35,7 @@ void patch(data const & olddata,
data & newdata);
-struct delta_applicator
+struct delta_applicator : intrusively_refcounted
{
virtual ~delta_applicator () {}
virtual void begin(std::string const & base) = 0;
@@ -46,10 +46,10 @@ struct delta_applicator
virtual void insert(std::string const & str) = 0;
};
-boost::shared_ptr new_simple_applicator();
-boost::shared_ptr new_piecewise_applicator();
+boost::intrusive_ptr new_simple_applicator();
+boost::intrusive_ptr new_piecewise_applicator();
-void apply_delta(boost::shared_ptr da,
+void apply_delta(boost::intrusive_ptr da,
std::string const & delta);
u64 measure_delta_target_size(std::string const & delta);