You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by tr...@apache.org on 2020/08/04 18:58:11 UTC

[qpid-dispatch] 25/32: Dataplane - Added qd_buffer_list_append function to efficiently accumulate data in buffer lists.

This is an automated email from the ASF dual-hosted git repository.

tross pushed a commit to branch dev-protocol-adaptors
in repository https://gitbox.apache.org/repos/asf/qpid-dispatch.git

commit febda9e0598da7566fefee940289586ab6703993
Author: Ted Ross <tr...@apache.org>
AuthorDate: Fri Jun 26 16:30:28 2020 -0400

    Dataplane - Added qd_buffer_list_append function to efficiently accumulate data in buffer lists.
---
 include/qpid/dispatch/buffer.h | 16 ++++++++++++++--
 src/buffer.c                   | 34 ++++++++++++++++++++++++++++++++++
 tests/buffer_test.c            | 35 +++++++++++++++++++++++++++++++++++
 3 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/include/qpid/dispatch/buffer.h b/include/qpid/dispatch/buffer.h
index e93b5df..715c813 100644
--- a/include/qpid/dispatch/buffer.h
+++ b/include/qpid/dispatch/buffer.h
@@ -38,8 +38,8 @@ extern size_t BUFFER_SIZE;
 /** A raw byte buffer .*/
 struct qd_buffer_t {
     DEQ_LINKS(qd_buffer_t);
-    unsigned int size;          ///< Size of data content
-    sys_atomic_t bfanout;        // The number of receivers for this buffer
+    unsigned int size;     ///< Size of data content
+    sys_atomic_t bfanout;  ///< The number of receivers for this buffer
 };
 
 /**
@@ -185,6 +185,18 @@ static inline unsigned char *qd_buffer_at(const qd_buffer_t *buf, size_t len)
 }
 
 
+/**
+ * qd_buffer_list_append
+ *
+ * Append new data to a buffer list using freespace efficiently and adding new buffers when necessary.
+ *
+ * @param buflist Pointer to a buffer list that will possibly be changed by adding new buffers
+ * @param data Pointer to raw binary data to be added to the buffer list
+ * @param len The number of bytes of data to append
+ */
+void qd_buffer_list_append(qd_buffer_list_t *buflist, uint8_t *data, size_t len);
+
+
 ///@}
 
 #endif
diff --git a/src/buffer.c b/src/buffer.c
index 40af6c2..66a4af2 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -106,3 +106,37 @@ unsigned int qd_buffer_list_length(const qd_buffer_list_t *list)
     }
     return len;
 }
+
+
+void qd_buffer_list_append(qd_buffer_list_t *buflist, uint8_t *data, size_t len)
+{
+    //
+    // If len is zero, there's no work to do.
+    //
+    if (len == 0)
+        return;
+
+    //
+    // If the buffer list is empty and there's some data, add one empty buffer before we begin.
+    //
+    if (DEQ_SIZE(*buflist) == 0) {
+        qd_buffer_t *buf = qd_buffer();
+        DEQ_INSERT_TAIL(*buflist, buf);
+    }
+
+    qd_buffer_t *tail = DEQ_TAIL(*buflist);
+
+    while (len > 0) {
+        size_t to_copy = MIN(len, qd_buffer_capacity(tail));
+        if (to_copy > 0) {
+            memcpy(qd_buffer_cursor(tail), data, to_copy);
+            qd_buffer_insert(tail, to_copy);
+            data += to_copy;
+            len  -= to_copy;
+        }
+        if (len > 0) {
+            tail = qd_buffer();
+            DEQ_INSERT_TAIL(*buflist, tail);
+        }
+    }
+}
diff --git a/tests/buffer_test.c b/tests/buffer_test.c
index 6dd61f6..4b15450 100644
--- a/tests/buffer_test.c
+++ b/tests/buffer_test.c
@@ -87,12 +87,47 @@ static char *test_buffer_list_clone(void *context)
 }
 
 
+static char *test_buffer_list_append(void *context)
+{
+    qd_buffer_list_t list;
+    qd_buffer_t *buf = qd_buffer();
+    size_t buffer_size = qd_buffer_capacity(buf);
+    qd_buffer_free(buf);
+
+    DEQ_INIT(list);
+
+    qd_buffer_list_append(&list, (uint8_t*) "", 0);
+    if (DEQ_SIZE(list) > 0) return "Buffer list should be empty";
+
+    qd_buffer_list_append(&list, (uint8_t*) "ABCDEFGHIJ", 10);
+    if (DEQ_SIZE(list) != (10 / buffer_size) + ((10 % buffer_size) ? 1 : 0)) return "Incorrect buffer count for size 10";
+
+    qd_buffer_list_append(&list, (uint8_t*) "KLMNOPQRSTUVWXYZ", 16);
+    if (DEQ_SIZE(list) != (26 / buffer_size) + ((26 % buffer_size) ? 1 : 0)) return "Incorrect buffer count for size 26";
+
+    size_t list_len = 0;
+    buf = DEQ_HEAD(list);
+    while (buf) {
+        list_len += qd_buffer_size(buf);
+        buf = DEQ_NEXT(buf);
+    }
+    if (list_len != 26) {
+        static char error[100];
+        sprintf(error, "Incorrect accumulated buffer size: %ld", list_len);
+        return error;
+    }
+
+    return 0;
+}
+
+
 int buffer_tests()
 {
     int result = 0;
     char *test_group = "buffer_tests";
 
     TEST_CASE(test_buffer_list_clone, 0);
+    TEST_CASE(test_buffer_list_append, 0);
 
     return result;
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org