avro-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dcrea...@apache.org
Subject svn commit: r1183637 - in /avro/trunk: CHANGES.txt lang/c/src/avro/data.h lang/c/src/wrapped-buffer.c
Date Sat, 15 Oct 2011 13:36:40 GMT
Author: dcreager
Date: Sat Oct 15 13:36:40 2011
New Revision: 1183637

URL: http://svn.apache.org/viewvc?rev=1183637&view=rev
Log:
AVRO-921. C: Default wrapped buffer implementation is zero-copy

The avro_wrapped_buffer_new_copy function creates a default
implementation of the wrapped buffer interface.  It creates a copy of
the data pointer that's passed in, which the wrapped buffer has full
control over.  Before, the wrapped buffer implementation would create
futher copies of the underlying buffer whenever the copy() method was
called.  Now, the wrapped buffer's copy is reference counted, and the
copy() and free() methods avoid making extra copies.

Modified:
    avro/trunk/CHANGES.txt
    avro/trunk/lang/c/src/avro/data.h
    avro/trunk/lang/c/src/wrapped-buffer.c

Modified: avro/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/avro/trunk/CHANGES.txt?rev=1183637&r1=1183636&r2=1183637&view=diff
==============================================================================
--- avro/trunk/CHANGES.txt (original)
+++ avro/trunk/CHANGES.txt Sat Oct 15 13:36:40 2011
@@ -30,6 +30,9 @@ Avro 1.6.0 (unreleased)
 
     AVRO-920. C: Memory readers and writers are now reusable. (dcreager)
 
+    AVRO-921. C: Default wrapped buffer implementation is zero-copy.
+    (dcreager)
+
     AVRO-890: Java: Add Maven archetype for creating Avro service
     projects.  (Stephen Gargan via cutting)
 

Modified: avro/trunk/lang/c/src/avro/data.h
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/avro/data.h?rev=1183637&r1=1183636&r2=1183637&view=diff
==============================================================================
--- avro/trunk/lang/c/src/avro/data.h (original)
+++ avro/trunk/lang/c/src/avro/data.h Sat Oct 15 13:36:40 2011
@@ -329,8 +329,11 @@ avro_wrapped_buffer_slice(avro_wrapped_b
 			  size_t offset, size_t length);
 
 /**
- * Creates a new wrapped buffer wrapping the given memory region.  The
- * wrapped buffer's copy method will create an actual copy.
+ * Creates a new wrapped buffer wrapping the given memory region.  You
+ * have to ensure that buf stays around for as long as you need to new
+ * wrapped buffer.  If you copy the wrapped buffer (using
+ * avro_wrapped_buffer_copy), this will create a copy of the data.
+ * Additional copies will reuse this new copy.
  */
 
 int
@@ -346,7 +349,9 @@ avro_wrapped_buffer_new(avro_wrapped_buf
 
 /**
  * Creates a new wrapped buffer containing a copy of the given memory
- * region.  The wrapped buffer's copy method will create further copies.
+ * region.  This new copy will be reference counted; if you copy it
+ * further (using avro_wrapped_buffer_copy), the new copies will share a
+ * single underlying buffer.
  */
 
 int

Modified: avro/trunk/lang/c/src/wrapped-buffer.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/wrapped-buffer.c?rev=1183637&r1=1183636&r2=1183637&view=diff
==============================================================================
--- avro/trunk/lang/c/src/wrapped-buffer.c (original)
+++ avro/trunk/lang/c/src/wrapped-buffer.c Sat Oct 15 13:36:40 2011
@@ -22,8 +22,10 @@
 #include "avro_private.h"
 #include "avro/allocation.h"
 #include "avro/data.h"
+#include "avro/refcount.h"
 
 struct avro_wrapped_copy {
+	volatile int  refcount;
 	size_t  allocated_size;
 };
 
@@ -31,7 +33,25 @@ static void
 avro_wrapped_copy_free(avro_wrapped_buffer_t *self)
 {
 	struct avro_wrapped_copy  *copy = self->user_data;
-	avro_free(copy, copy->allocated_size);
+	if (avro_refcount_dec(&copy->refcount)) {
+		avro_free(copy, copy->allocated_size);
+	}
+}
+
+static int
+avro_wrapped_copy_copy(avro_wrapped_buffer_t *dest,
+		       const avro_wrapped_buffer_t *src,
+		       size_t offset, size_t length)
+{
+	struct avro_wrapped_copy  *copy = src->user_data;
+	avro_refcount_inc(&copy->refcount);
+	dest->buf = src->buf + offset;
+	dest->size = length;
+	dest->user_data = copy;
+	dest->free = avro_wrapped_copy_free;
+	dest->copy = avro_wrapped_copy_copy;
+	dest->slice = NULL;
+	return 0;
 }
 
 int
@@ -48,9 +68,10 @@ avro_wrapped_buffer_new_copy(avro_wrappe
 	dest->size = length;
 	dest->user_data = copy;
 	dest->free = avro_wrapped_copy_free;
-	dest->copy = NULL;
+	dest->copy = avro_wrapped_copy_copy;
 	dest->slice = NULL;
 
+	avro_refcount_set(&copy->refcount, 1);
 	copy->allocated_size = allocated_size;
 	memcpy((void *) dest->buf, buf, length);
 	return 0;
@@ -83,7 +104,7 @@ avro_wrapped_buffer_copy(avro_wrapped_bu
 			 const avro_wrapped_buffer_t *src,
 			 size_t offset, size_t length)
 {
-	if (offset >= src->size) {
+	if (offset > src->size) {
 		avro_set_error("Invalid offset when slicing buffer");
 		return EINVAL;
 	}
@@ -104,7 +125,7 @@ int
 avro_wrapped_buffer_slice(avro_wrapped_buffer_t *self,
 			  size_t offset, size_t length)
 {
-	if (offset >= self->size) {
+	if (offset > self->size) {
 		avro_set_error("Invalid offset when slicing buffer");
 		return EINVAL;
 	}



Mime
View raw message