From 14683979c43e17393dc4f902fe65ed22898b2bce Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Tue, 25 Jun 2019 20:00:47 -0700 Subject: BlobBuilder implemented, tests in progress. --- src/unit/blobbuilder.unit | 28 ++++++++++++++++++++++++++++ src/unstable/blobbuilder.cpp | 8 +++++--- src/unstable/blobbuilder.h | 20 ++++++++++++++++++++ 3 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 src/unit/blobbuilder.unit diff --git a/src/unit/blobbuilder.unit b/src/unit/blobbuilder.unit new file mode 100644 index 0000000..84bf549 --- /dev/null +++ b/src/unit/blobbuilder.unit @@ -0,0 +1,28 @@ +// vim: syntax=cpp +/* + * Copyright (C) 2007-2019 Xagasoft, All rights reserved. + * + * This file is part of the libbu++ library and is released under the + * terms of the license contained in the file LICENSE. + */ + +#include "bu/blob.h" +#include "bu/blobbuilder.h" +#include "bu/exceptionindexoutofbounds.h" +#include "bu/sio.h" + +#include + +suite BlobBuilder +{ + test append + { + Bu::BlobBuilder a; + a.append("a"); + a.append("bc"); + a += "def"; + Bu::println(">%1<\n\n").arg( a.getBlob() ); + a.append("abcdef"); + Bu::println(">%1<\n\n").arg( a.getBlob() ); + } +} diff --git a/src/unstable/blobbuilder.cpp b/src/unstable/blobbuilder.cpp index d4b458b..497a1a1 100644 --- a/src/unstable/blobbuilder.cpp +++ b/src/unstable/blobbuilder.cpp @@ -8,7 +8,7 @@ #include "bu/blobbuilder.h" #include "bu/blob.h" -#define PAGE_SIZE 1024 +#define PAGE_SIZE 8 ///// // BlobBuilderCore::Chunk @@ -109,20 +109,20 @@ void Bu::BlobBuilderCore::clear() delete pCur; pCur = pNext; } - delete pFirst; pFirst = pLast = 0; iLength = 0; } void Bu::BlobBuilderCore::append( const char *pSrc, int32_t iLength ) { + this->iLength += iLength; if( pFirst == 0 ) { // Nothing in the list, just add a chunk. pFirst = pLast = new Chunk( pSrc, iLength ); return; } - else if( pLast->iLength < 1024 ) + else if( pLast->iLength < PAGE_SIZE ) { // Append to the last chunk first, this will modify pSrc & iLength. pLast->append( pSrc, iLength ); @@ -147,6 +147,7 @@ void Bu::BlobBuilderCore::prepend( const char *pSrc, int32_t iLength ) pNew->pNext = pFirst; pFirst = pNew; } + this->iLength += iLength; } void Bu::BlobBuilderCore::insert( int32_t iBefore, const char *pSrc, @@ -185,6 +186,7 @@ void Bu::BlobBuilderCore::insert( int32_t iBefore, const char *pSrc, } pCur = pCur->pNext; } + this->iLength += iLength; } void Bu::BlobBuilderCore::set( const char *pSrc, int32_t iLength ) diff --git a/src/unstable/blobbuilder.h b/src/unstable/blobbuilder.h index 483de43..744212a 100644 --- a/src/unstable/blobbuilder.h +++ b/src/unstable/blobbuilder.h @@ -61,6 +61,26 @@ namespace Bu }; /** @endcond */ + /** + * This makes creating a Blob piece at a time easy and fast. You can + * append, prepend, or insert with reasonable efficiency. The underlying + * data structure is currently a linked list, and the individual links are + * actually block allocated memory. If an amount of data is appended that + * is less than the minimum page size then the minimum page size is + * allocated. Subsequent appends will share that allocated buffer until it + * is full, at which point a new buffer will be created. If an amount + * greater than the minimum page size is appended then any extra space in + * the last buffer is used, and then the rest is placed in a single buffer. + * At most one buffer will be allocated for any given append or prepend + * operation. Due to the nature of insert, up to two buffers could be + * allocated. + * + * Insert operations will take O(N) time to find the location to insert to + * in the linked list, at that point the foud chunk will be split into two + * and the new data will be added at the new location. This will also + * attempt to share the existing buffers, but if there's extra it will + * allocate a new buffer for the remaining data. + */ class BlobBuilder : public Bu::SharedCore { protected: -- cgit v1.2.3