aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2019-06-25 20:00:47 -0700
committerMike Buland <eichlan@xagasoft.com>2019-06-25 20:00:47 -0700
commit14683979c43e17393dc4f902fe65ed22898b2bce (patch)
treee2395ae8de63b41d944c46cae0d2d25266d4377a
parent9e4d15b6dec9a7f9358855faeb96b1ac767a15e6 (diff)
downloadlibbu++-14683979c43e17393dc4f902fe65ed22898b2bce.tar.gz
libbu++-14683979c43e17393dc4f902fe65ed22898b2bce.tar.bz2
libbu++-14683979c43e17393dc4f902fe65ed22898b2bce.tar.xz
libbu++-14683979c43e17393dc4f902fe65ed22898b2bce.zip
BlobBuilder implemented, tests in progress.
-rw-r--r--src/unit/blobbuilder.unit28
-rw-r--r--src/unstable/blobbuilder.cpp8
-rw-r--r--src/unstable/blobbuilder.h20
3 files changed, 53 insertions, 3 deletions
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 @@
1// vim: syntax=cpp
2/*
3 * Copyright (C) 2007-2019 Xagasoft, All rights reserved.
4 *
5 * This file is part of the libbu++ library and is released under the
6 * terms of the license contained in the file LICENSE.
7 */
8
9#include "bu/blob.h"
10#include "bu/blobbuilder.h"
11#include "bu/exceptionindexoutofbounds.h"
12#include "bu/sio.h"
13
14#include <string.h>
15
16suite BlobBuilder
17{
18 test append
19 {
20 Bu::BlobBuilder a;
21 a.append("a");
22 a.append("bc");
23 a += "def";
24 Bu::println(">%1<\n\n").arg( a.getBlob() );
25 a.append("abcdef");
26 Bu::println(">%1<\n\n").arg( a.getBlob() );
27 }
28}
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 @@
8#include "bu/blobbuilder.h" 8#include "bu/blobbuilder.h"
9#include "bu/blob.h" 9#include "bu/blob.h"
10 10
11#define PAGE_SIZE 1024 11#define PAGE_SIZE 8
12 12
13///// 13/////
14// BlobBuilderCore::Chunk 14// BlobBuilderCore::Chunk
@@ -109,20 +109,20 @@ void Bu::BlobBuilderCore::clear()
109 delete pCur; 109 delete pCur;
110 pCur = pNext; 110 pCur = pNext;
111 } 111 }
112 delete pFirst;
113 pFirst = pLast = 0; 112 pFirst = pLast = 0;
114 iLength = 0; 113 iLength = 0;
115} 114}
116 115
117void Bu::BlobBuilderCore::append( const char *pSrc, int32_t iLength ) 116void Bu::BlobBuilderCore::append( const char *pSrc, int32_t iLength )
118{ 117{
118 this->iLength += iLength;
119 if( pFirst == 0 ) 119 if( pFirst == 0 )
120 { 120 {
121 // Nothing in the list, just add a chunk. 121 // Nothing in the list, just add a chunk.
122 pFirst = pLast = new Chunk( pSrc, iLength ); 122 pFirst = pLast = new Chunk( pSrc, iLength );
123 return; 123 return;
124 } 124 }
125 else if( pLast->iLength < 1024 ) 125 else if( pLast->iLength < PAGE_SIZE )
126 { 126 {
127 // Append to the last chunk first, this will modify pSrc & iLength. 127 // Append to the last chunk first, this will modify pSrc & iLength.
128 pLast->append( pSrc, iLength ); 128 pLast->append( pSrc, iLength );
@@ -147,6 +147,7 @@ void Bu::BlobBuilderCore::prepend( const char *pSrc, int32_t iLength )
147 pNew->pNext = pFirst; 147 pNew->pNext = pFirst;
148 pFirst = pNew; 148 pFirst = pNew;
149 } 149 }
150 this->iLength += iLength;
150} 151}
151 152
152void Bu::BlobBuilderCore::insert( int32_t iBefore, const char *pSrc, 153void Bu::BlobBuilderCore::insert( int32_t iBefore, const char *pSrc,
@@ -185,6 +186,7 @@ void Bu::BlobBuilderCore::insert( int32_t iBefore, const char *pSrc,
185 } 186 }
186 pCur = pCur->pNext; 187 pCur = pCur->pNext;
187 } 188 }
189 this->iLength += iLength;
188} 190}
189 191
190void Bu::BlobBuilderCore::set( const char *pSrc, int32_t iLength ) 192void 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
61 }; 61 };
62 /** @endcond */ 62 /** @endcond */
63 63
64 /**
65 * This makes creating a Blob piece at a time easy and fast. You can
66 * append, prepend, or insert with reasonable efficiency. The underlying
67 * data structure is currently a linked list, and the individual links are
68 * actually block allocated memory. If an amount of data is appended that
69 * is less than the minimum page size then the minimum page size is
70 * allocated. Subsequent appends will share that allocated buffer until it
71 * is full, at which point a new buffer will be created. If an amount
72 * greater than the minimum page size is appended then any extra space in
73 * the last buffer is used, and then the rest is placed in a single buffer.
74 * At most one buffer will be allocated for any given append or prepend
75 * operation. Due to the nature of insert, up to two buffers could be
76 * allocated.
77 *
78 * Insert operations will take O(N) time to find the location to insert to
79 * in the linked list, at that point the foud chunk will be split into two
80 * and the new data will be added at the new location. This will also
81 * attempt to share the existing buffers, but if there's extra it will
82 * allocate a new buffer for the remaining data.
83 */
64 class BlobBuilder : public Bu::SharedCore<BlobBuilder, BlobBuilderCore> 84 class BlobBuilder : public Bu::SharedCore<BlobBuilder, BlobBuilderCore>
65 { 85 {
66 protected: 86 protected: