Gitweb links:

...log 
http://git.netsurf-browser.org/libparserutils.git/shortlog/d101b2bb6dc98050f8f1b04d9d2bfeeff5a120c7
...commit 
http://git.netsurf-browser.org/libparserutils.git/commit/d101b2bb6dc98050f8f1b04d9d2bfeeff5a120c7
...tree 
http://git.netsurf-browser.org/libparserutils.git/tree/d101b2bb6dc98050f8f1b04d9d2bfeeff5a120c7

The branch, master has been updated
       via  d101b2bb6dc98050f8f1b04d9d2bfeeff5a120c7 (commit)
      from  269b0047aa506be93637e93d109a34f4bd7cefc4 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commitdiff 
http://git.netsurf-browser.org/libparserutils.git/commit/?id=d101b2bb6dc98050f8f1b04d9d2bfeeff5a120c7
commit d101b2bb6dc98050f8f1b04d9d2bfeeff5a120c7
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <michael.dr...@codethink.co.uk>

    Buffer: Optimise to minimise memmove shuffles.
    
    Previously the data in the linear buffer was always stored at
    the start of the allocation, pointed to by `buffer->data`.
    This was achieved by memmoving every time data was consumed
    from the front.
    
    Now the allocation is pointed to by `buffer->alloc`, and the
    start of the data is pointed to by `buffer->data` (as before).
    
    This means client code does not need to change to get at the
    data.
    
    The advantage comes when we discard the from the start of the
    buffer, when some data is consumed.  We now simply advance the
    data pointer by the number of bytes to be discarded, and reduce
    the buffer length by the same amount.
    
    If the used portion of the buffer now fits between the start
    of the allocation and the current start of the data, it is
    memcpyed to the allocation start, otherwise it is left alone.
    
    This is a significant optimisation when the size of the chunk
    is large, such as when loading from disc. (When the first
    (only) "chunk" is just the whole file.

diff --git a/include/parserutils/utils/buffer.h 
b/include/parserutils/utils/buffer.h
index 9425070..5f8f696 100644
--- a/include/parserutils/utils/buffer.h
+++ b/include/parserutils/utils/buffer.h
@@ -18,6 +18,7 @@ extern "C"
 
 struct parserutils_buffer
 {
+       uint8_t *alloc;
        uint8_t *data;
        size_t length;
        size_t allocated;
diff --git a/src/utils/buffer.c b/src/utils/buffer.c
index 716e67c..5e0f58c 100644
--- a/src/utils/buffer.c
+++ b/src/utils/buffer.c
@@ -30,12 +30,13 @@ parserutils_error 
parserutils_buffer_create(parserutils_buffer **buffer)
        if (b == NULL)
                return PARSERUTILS_NOMEM;
 
-       b->data = malloc(DEFAULT_SIZE);
-       if (b->data == NULL) {
+       b->alloc = malloc(DEFAULT_SIZE);
+       if (b->alloc == NULL) {
                free(b);
                return PARSERUTILS_NOMEM;
        }
 
+       b->data = b->alloc;
        b->length = 0;
        b->allocated = DEFAULT_SIZE;
 
@@ -55,13 +56,59 @@ parserutils_error 
parserutils_buffer_destroy(parserutils_buffer *buffer)
        if (buffer == NULL)
                return PARSERUTILS_BADPARM;
 
-       free(buffer->data);
+       free(buffer->alloc);
        free(buffer);
 
        return PARSERUTILS_OK;
 }
 
 /**
+ * Get current data offset within buffer's allocation.
+ *
+ * \param[in]  buffer  The buffer object.
+ * \return data offset in bytes.
+ */
+static inline size_t get_offset(parserutils_buffer *buffer)
+{
+       return buffer->data - buffer->alloc;
+}
+
+/**
+ * Try moving the data to the start of the allocation.
+ *
+ * \param[in]  buffer  The buffer object.
+ */
+static inline void try_rebase(parserutils_buffer *buffer)
+{
+       if (get_offset(buffer) >= buffer->length) {
+               memcpy(buffer->alloc, buffer->data, buffer->length);
+               buffer->data = buffer->alloc;
+       }
+}
+
+/**
+ * Ensure that the buffer has enough space at the end to add len bytes.
+ *
+ * \param[in]  buffer  The buffer object.
+ * \param[in]  len     Number of bytes to ensure there is space for.
+ * \return PARSERUTILS_OK on success, appropriate error otherwise.
+ */
+static inline parserutils_error ensure_space(
+               parserutils_buffer *buffer,
+               size_t len)
+{
+       try_rebase(buffer);
+
+       while (len >= buffer->allocated - buffer->length - get_offset(buffer)) {
+               parserutils_error error = parserutils_buffer_grow(buffer);
+               if (error != PARSERUTILS_OK)
+                       return error;
+       }
+
+       return PARSERUTILS_OK;
+}
+
+/**
  * Append data to a memory buffer
  *
  * \param buffer  The buffer to append to
@@ -72,11 +119,9 @@ parserutils_error 
parserutils_buffer_destroy(parserutils_buffer *buffer)
 parserutils_error parserutils_buffer_append(parserutils_buffer *buffer, 
                const uint8_t *data, size_t len)
 {
-       while (len >= buffer->allocated - buffer->length) {
-               parserutils_error error = parserutils_buffer_grow(buffer);
-               if (error != PARSERUTILS_OK)
-                       return error;
-       }
+       parserutils_error error = ensure_space(buffer, len);
+       if (error != PARSERUTILS_OK)
+               return error;
 
        memcpy(buffer->data + buffer->length, data, len);
 
@@ -97,17 +142,17 @@ parserutils_error 
parserutils_buffer_append(parserutils_buffer *buffer,
 parserutils_error parserutils_buffer_insert(parserutils_buffer *buffer, 
                size_t offset, const uint8_t *data, size_t len)
 {
+       parserutils_error error;
+
        if (offset > buffer->length)
                return PARSERUTILS_BADPARM;
 
        if (offset == buffer->length)
                return parserutils_buffer_append(buffer, data, len);
 
-       while (len >= buffer->allocated - buffer->length) {
-               parserutils_error error = parserutils_buffer_grow(buffer);
-               if (error != PARSERUTILS_OK)
-                       return error;
-       }
+       error = ensure_space(buffer, len);
+       if (error != PARSERUTILS_OK)
+               return error;
 
        memmove(buffer->data + offset + len,
                        buffer->data + offset, buffer->length - offset);
@@ -133,6 +178,13 @@ parserutils_error 
parserutils_buffer_discard(parserutils_buffer *buffer,
        if (offset >= buffer->length || offset + len > buffer->length)
                return PARSERUTILS_BADPARM;
 
+       if (offset == 0) {
+               buffer->data += len;
+               buffer->length -= len;
+               try_rebase(buffer);
+               return PARSERUTILS_OK;
+       }
+
        memmove(buffer->data + offset, buffer->data + offset + len, 
                        buffer->length - (len + offset));
 
@@ -149,11 +201,13 @@ parserutils_error 
parserutils_buffer_discard(parserutils_buffer *buffer,
  */
 parserutils_error parserutils_buffer_grow(parserutils_buffer *buffer)
 {
-       uint8_t *temp = realloc(buffer->data, buffer->allocated * 2);
+       size_t offset = get_offset(buffer);
+       uint8_t *temp = realloc(buffer->alloc, buffer->allocated * 2);
        if (temp == NULL)
                return PARSERUTILS_NOMEM;
 
-       buffer->data = temp;
+       buffer->alloc = temp;
+       buffer->data = buffer->alloc + offset;
        buffer->allocated *= 2;
 
        return PARSERUTILS_OK;
@@ -180,7 +234,7 @@ parserutils_error 
parserutils_buffer_randomise(parserutils_buffer *buffer)
        /* Leak the buffer's current data, so we don't reuse it */
        /* buffer->alloc(buffer->data, 0, buffer->pw); */
 
-       buffer->data = temp;
+       buffer->alloc = buffer->data = temp;
 #endif
 
 


-----------------------------------------------------------------------

Summary of changes:
 include/parserutils/utils/buffer.h |    1 +
 src/utils/buffer.c                 |   86 +++++++++++++++++++++++++++++-------
 2 files changed, 71 insertions(+), 16 deletions(-)

diff --git a/include/parserutils/utils/buffer.h 
b/include/parserutils/utils/buffer.h
index 9425070..5f8f696 100644
--- a/include/parserutils/utils/buffer.h
+++ b/include/parserutils/utils/buffer.h
@@ -18,6 +18,7 @@ extern "C"
 
 struct parserutils_buffer
 {
+       uint8_t *alloc;
        uint8_t *data;
        size_t length;
        size_t allocated;
diff --git a/src/utils/buffer.c b/src/utils/buffer.c
index 716e67c..5e0f58c 100644
--- a/src/utils/buffer.c
+++ b/src/utils/buffer.c
@@ -30,12 +30,13 @@ parserutils_error 
parserutils_buffer_create(parserutils_buffer **buffer)
        if (b == NULL)
                return PARSERUTILS_NOMEM;
 
-       b->data = malloc(DEFAULT_SIZE);
-       if (b->data == NULL) {
+       b->alloc = malloc(DEFAULT_SIZE);
+       if (b->alloc == NULL) {
                free(b);
                return PARSERUTILS_NOMEM;
        }
 
+       b->data = b->alloc;
        b->length = 0;
        b->allocated = DEFAULT_SIZE;
 
@@ -55,13 +56,59 @@ parserutils_error 
parserutils_buffer_destroy(parserutils_buffer *buffer)
        if (buffer == NULL)
                return PARSERUTILS_BADPARM;
 
-       free(buffer->data);
+       free(buffer->alloc);
        free(buffer);
 
        return PARSERUTILS_OK;
 }
 
 /**
+ * Get current data offset within buffer's allocation.
+ *
+ * \param[in]  buffer  The buffer object.
+ * \return data offset in bytes.
+ */
+static inline size_t get_offset(parserutils_buffer *buffer)
+{
+       return buffer->data - buffer->alloc;
+}
+
+/**
+ * Try moving the data to the start of the allocation.
+ *
+ * \param[in]  buffer  The buffer object.
+ */
+static inline void try_rebase(parserutils_buffer *buffer)
+{
+       if (get_offset(buffer) >= buffer->length) {
+               memcpy(buffer->alloc, buffer->data, buffer->length);
+               buffer->data = buffer->alloc;
+       }
+}
+
+/**
+ * Ensure that the buffer has enough space at the end to add len bytes.
+ *
+ * \param[in]  buffer  The buffer object.
+ * \param[in]  len     Number of bytes to ensure there is space for.
+ * \return PARSERUTILS_OK on success, appropriate error otherwise.
+ */
+static inline parserutils_error ensure_space(
+               parserutils_buffer *buffer,
+               size_t len)
+{
+       try_rebase(buffer);
+
+       while (len >= buffer->allocated - buffer->length - get_offset(buffer)) {
+               parserutils_error error = parserutils_buffer_grow(buffer);
+               if (error != PARSERUTILS_OK)
+                       return error;
+       }
+
+       return PARSERUTILS_OK;
+}
+
+/**
  * Append data to a memory buffer
  *
  * \param buffer  The buffer to append to
@@ -72,11 +119,9 @@ parserutils_error 
parserutils_buffer_destroy(parserutils_buffer *buffer)
 parserutils_error parserutils_buffer_append(parserutils_buffer *buffer, 
                const uint8_t *data, size_t len)
 {
-       while (len >= buffer->allocated - buffer->length) {
-               parserutils_error error = parserutils_buffer_grow(buffer);
-               if (error != PARSERUTILS_OK)
-                       return error;
-       }
+       parserutils_error error = ensure_space(buffer, len);
+       if (error != PARSERUTILS_OK)
+               return error;
 
        memcpy(buffer->data + buffer->length, data, len);
 
@@ -97,17 +142,17 @@ parserutils_error 
parserutils_buffer_append(parserutils_buffer *buffer,
 parserutils_error parserutils_buffer_insert(parserutils_buffer *buffer, 
                size_t offset, const uint8_t *data, size_t len)
 {
+       parserutils_error error;
+
        if (offset > buffer->length)
                return PARSERUTILS_BADPARM;
 
        if (offset == buffer->length)
                return parserutils_buffer_append(buffer, data, len);
 
-       while (len >= buffer->allocated - buffer->length) {
-               parserutils_error error = parserutils_buffer_grow(buffer);
-               if (error != PARSERUTILS_OK)
-                       return error;
-       }
+       error = ensure_space(buffer, len);
+       if (error != PARSERUTILS_OK)
+               return error;
 
        memmove(buffer->data + offset + len,
                        buffer->data + offset, buffer->length - offset);
@@ -133,6 +178,13 @@ parserutils_error 
parserutils_buffer_discard(parserutils_buffer *buffer,
        if (offset >= buffer->length || offset + len > buffer->length)
                return PARSERUTILS_BADPARM;
 
+       if (offset == 0) {
+               buffer->data += len;
+               buffer->length -= len;
+               try_rebase(buffer);
+               return PARSERUTILS_OK;
+       }
+
        memmove(buffer->data + offset, buffer->data + offset + len, 
                        buffer->length - (len + offset));
 
@@ -149,11 +201,13 @@ parserutils_error 
parserutils_buffer_discard(parserutils_buffer *buffer,
  */
 parserutils_error parserutils_buffer_grow(parserutils_buffer *buffer)
 {
-       uint8_t *temp = realloc(buffer->data, buffer->allocated * 2);
+       size_t offset = get_offset(buffer);
+       uint8_t *temp = realloc(buffer->alloc, buffer->allocated * 2);
        if (temp == NULL)
                return PARSERUTILS_NOMEM;
 
-       buffer->data = temp;
+       buffer->alloc = temp;
+       buffer->data = buffer->alloc + offset;
        buffer->allocated *= 2;
 
        return PARSERUTILS_OK;
@@ -180,7 +234,7 @@ parserutils_error 
parserutils_buffer_randomise(parserutils_buffer *buffer)
        /* Leak the buffer's current data, so we don't reuse it */
        /* buffer->alloc(buffer->data, 0, buffer->pw); */
 
-       buffer->data = temp;
+       buffer->alloc = buffer->data = temp;
 #endif
 
 


-- 
Lexer/parser utility functions
_______________________________________________
netsurf-commits mailing list -- netsurf-commits@netsurf-browser.org
To unsubscribe send an email to netsurf-commits-le...@netsurf-browser.org

Reply via email to