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