]> gitweb.hamatoma.de Git - cpidjinn/commitdiff
ArrayList::sort() works
authorhama <hama@siduction.net>
Sun, 14 Aug 2016 22:50:30 +0000 (00:50 +0200)
committerhama <hama@siduction.net>
Sun, 14 Aug 2016 22:50:30 +0000 (00:50 +0200)
* refactoring: DynBuffer::size() renamed to capacity()
* DynBuffer::m_maxBlocksize added

util/Makefile
util/arraylist.cpp
util/arraylist.hpp
util/cuarraylist.cpp
util/cudynbuffer.cpp
util/cutimeutils.cpp
util/dynbuffer.cpp
util/dynbuffer.hpp
util/test.cpp
util/thread.hpp

index 32ef2c96cd0329b21160039a21b50188a21fc4e7..0f09be755fdaf68911c29137f653e72e7df6b258 100644 (file)
@@ -1,7 +1,9 @@
 CC = g++
+#CC = clang
 CFLAGS = "-Wall"
 LDFLAGS = -lm -lpthread
 CL = g++
+#CL = clang
 
 OBJ = cuarraylist.o cutimeutils.o cutimer.o cudynbuffer.o \
        arraylist.o dynbuffer.o logger.o timeutils.o unittest.o test.o thread.o \
index 3652de1e5f00421a2aff9a9569d1babdae21932f..5503c1674d27596ca26e6e7c52ac5d42f304c718 100644 (file)
@@ -7,10 +7,10 @@
  * The latest sources: https://github.com/republib
  *
  */
+//#define TRACE_ON 1
 #include "stdlib.h"
 #include "assert.h"
 #include "memory.h"
-//#define TRACE_ON
 #include "trace.hpp"
 #include "util.hpp"
 
@@ -230,6 +230,69 @@ BaseArrayList& BaseArrayList::remove(const void* item){
        return *this;
 }
 
+/**
+ * Sorts a part of the array.
+ *
+ * @param count        the number of elements to sort
+ */
+void BaseArrayList::sort(){
+    heapify();
+
+    // The following loop maintains the invariants that a[0:end] is a heap and every element
+       // beyond end is greater than everything before it (so a[end:count] is in sorted order))
+    int end = m_count - 1;
+    while (end > 0) {
+        // (a[0] is the root and largest value. The swap moves it in front of the sorted elements.)
+        swapItems(end, 0);
+        // the heap size is reduced by one
+        --end;
+        // the swap ruined the heap property, so restore it:
+        shiftDown(0, end);
+       }
+}
+void BaseArrayList::heapify(){
+       // start is assigned the index in 'a' of the last parent node)
+    // the last element in a 0-based array is at index count-1; find the parent of that element)
+    int start = iParent(m_count-1);
+
+    while (start >= 0){
+        // shift down the node at index 'start' to the proper place such that all nodes below
+               // the start index are in heap order:
+        shiftDown(start, m_count - 1);
+        // go to the next parent node:
+        --start;
+       }
+    // after shifting down the root all nodes/elements are in heap order)
+}
+void BaseArrayList::shiftDown(int start, int end){
+    int root = start;
+
+       // while the root has at least one child:
+    while (iLeftChild(root) <= end){
+               // Left child of root)
+        int child = iLeftChild(root);
+        // (Keeps track of child to swap with:
+        int swap = root;
+
+        if (m_factory.compareItems(m_buffer[swap], m_buffer[child]) < 0)
+            swap = child;
+
+        // If there is a right child and that child is greater:
+        if (child+1 <= end
+                               && m_factory.compareItems(m_buffer[swap], m_buffer[child + 1]) < 0)
+            swap = child + 1;
+        if (swap == root){
+            // The root holds the largest element. Since we assume the heaps rooted at the
+             // children are valid, this means that we are done:
+            break;
+               } else {
+            swapItems(root, swap);
+            // repeat to continue shifting down the child now:
+            root = swap;
+               }
+       }
+}
+
 /**
  * Removes a the item with a given index from the list.
  *
@@ -238,7 +301,8 @@ BaseArrayList& BaseArrayList::remove(const void* item){
  */
 BaseArrayList& BaseArrayList::removeAt(int index){
        if (index >= 0 && index < m_count){
-               TRACEF(("removeAt(%d): %s factory: %llx\n", index, m_buffer[index], (long long int) &m_factory));
+               TRACEF(("removeAt(%d): %s factory: %llx\n", index,
+                               (char*) m_buffer[index], (long long int) &m_factory));
                m_factory.destroyItem(m_buffer[index]);
                TRACE1("removeAt(%d)\n", index);
                if (index < --m_count)
@@ -291,3 +355,19 @@ void CStringList::dump(const char* title) const{
        for (int ii = 0; ii < m_count; ii++)
                printf("%2d: %s\n", ii, (ptr = get(ii)) == NULL ? "<null>" : ptr);
 }
+
+void* CStringFactory::cloneItem(const void* source) {
+       char* rc = strdup(reinterpret_cast<const char*>(source));
+       TRACEF(("strdup [%llx] -> [%llx]: %s\n", (long long int) source, (long long int) rc, (char*) rc));
+       return rc;
+}
+void CStringFactory::destroyItem(const void* item) {
+       TRACE2("free [%llx]: %s\n", (long long int) item, (char*) item);
+       // reserved with strdup()
+       ::free((void*) item);
+}
+int CStringFactory::compareItems(const void* item1, const void* item2) const{
+       int rc = strcmp(reinterpret_cast<const char*>(item1),
+                                       reinterpret_cast<const char*>(item2));
+       return rc;
+}
index 773cc5e8dad4c6f573832d92a00739a8b3113937..10c9b7a36f8844dd51f06007058e09213954d61e 100644 (file)
@@ -15,7 +15,7 @@
 class ItemFactory {
 public:
        virtual void* cloneItem(const void* source) = 0;
-       virtual int compareItems(const void* item1, const void* item2) const;
+       virtual int compareItems(const void* item1, const void* item2) const = 0;
        virtual void destroyItem(const void* item) = 0;
 };
 class BaseArrayList
@@ -32,12 +32,29 @@ public:
        BaseArrayList& clear();
        BaseArrayList& ensuresSize(int capacity);
        int indexOf(const void* item) const;
-       BaseArrayList& remove(const void* item);
-       BaseArrayList& removeAt(int index);
-public:
        inline void** getBuffer() const{
                return m_buffer;
        }
+       BaseArrayList& remove(const void* item);
+       BaseArrayList& removeAt(int index);
+       void sort();
+protected:
+       void heapify();
+       void shiftDown(int start, int end);
+       inline void swapItems(int index1, int index2){
+               void* tmp = m_buffer[index1];
+               m_buffer[index1] = m_buffer[index2];
+               m_buffer[index2] = tmp;
+       }
+       inline int iParent(int index){
+               return (index-1) / 2;
+       }
+       inline int iLeftChild(int index){
+               return 2*index + 1;
+       }
+       inline int iRightChild(int index){
+               return 2*index + 2;
+       }
 protected:
     int m_capacity;
     int m_blocksize;
@@ -72,13 +89,6 @@ public:
                BaseArrayList::clear();
                return *this;
        }
-private:
-       virtual int compareItems(const void* item1, const void* item2) const{
-               int rc = compareItems(reinterpret_cast<const T*> (item1),
-                       reinterpret_cast<const T *> (item2));
-                       return rc;
-               return rc;
-       }
 public:
        inline int count() const {
                return m_count;
@@ -102,11 +112,16 @@ public:
                BaseArrayList::removeAt(index);
                return *this;
        }
+       inline void sort(){
+               BaseArrayList::sort();
+       }
        inline int sorted() const{
                return m_sorted;
        }
        inline void setSorted(bool sorted){
                m_sorted = sorted;
+               if (m_sorted)
+                       sort();
        }
 };
 
@@ -127,28 +142,18 @@ public:
 
 class CStringFactory {
        static CStringFactory* m_instance;
+private:
+       CStringFactory(){
+       }
 public:
        static CStringFactory* instance(){
                if (m_instance == NULL)
-                       m_instance = new CStringFactory();
+                       m_instance = new CStringFactory;
                return m_instance;
        }
 public:
-       virtual void* cloneItem(const void* source) {
-               char* rc = strdup(reinterpret_cast<const char*>(source));
-               TRACEF(("strdup [%llx] -> [%llx]: %s\n", (long long int) source, (long long int) rc, (char*) rc));
-               return rc;
-       }
-       virtual void destroyItem(const void* item) {
-               TRACE2("free [%llx]: %s\n", (long long int) item, (char*) item);
-               // reserved with strdup()
-               ::free((void*) item);
-       }
-public:
-       virtual int compareItems(const void* item1, const void* item2) const{
-               int rc = strcmp(reinterpret_cast<const char*>(item1),
-                                               reinterpret_cast<const char*>(item2));
-               return rc;
-       }
+       virtual void* cloneItem(const void* source);
+       virtual int compareItems(const void* item1, const void* item2) const;
+       virtual void destroyItem(const void* item);
 };
 #endif // ARRAYLIST_H
index 718f1fe9dcaf244be410ba658a5a4e6ba2e85c51..8f034ccdddf5fba267ad4249b601d5a62cca24fb 100644 (file)
@@ -16,6 +16,7 @@ class TestArrayList : public UnitTest {
     }
     public:
     virtual void run() {
+               testSort();
         testIndexOfUnsorted();
         testIndexOfSorted();
         testCopyUnsorted();
@@ -37,6 +38,37 @@ class TestArrayList : public UnitTest {
         testSetSorted();
         testDestroyItem();
     }
+    void checkSorted(int count, CStringList& list){
+        DynBuffer buffer;
+               for ( int ii = 0; ii < count; ii++ ) {
+            buffer.clear().appendInt ( ii, "%08x" );
+            checkE ( buffer.str(), list.get ( ii ) );
+        }
+    }
+    void fillReverse(int count, CStringList& list){
+        DynBuffer buffer;
+        for ( int ii = 0; ii < count; ii++ ) {
+            buffer.clear().appendInt ( count - ii - 1, "%08x");
+            list.add ( buffer.str() );
+        }
+    }
+    void testSort(){
+        CStringList list1 ( 16, 16, 256, true );
+        DynBuffer buffer;
+        for ( int ii = 0; ii < m_permutationSize; ii++ ) {
+            buffer.clear().appendInt ( m_permutation[ii], "%08x" );
+            list1.add ( buffer.str() );
+        }
+        list1.sort();
+               checkSorted(m_permutationSize, list1);
+
+               for (int ii = 1; ii < 128; ii++){
+                       list1.clear();
+                       fillReverse(ii, list1);
+                       list1.sort();
+                       checkSorted(ii, list1);
+               }
+    }
     void testCopyUnsorted() {
                {
         CStringList list1;
@@ -271,20 +303,24 @@ class TestArrayList : public UnitTest {
         checkE ( "joe", list.get ( 2 ) );
     }
     void testIndexOfUnsorted() {
-        int capacity = 16;
-        int blocksize = 16;
-        int maxBlocksize = 1024*1024;
-        bool sorted = true;
-        CStringList list ( capacity, blocksize, maxBlocksize, ! sorted );
-        DynBuffer buffer;
-        for ( int ix = 1; ix <= 1024; ix++ ) {
-            buffer.clear().appendInt ( 0x42ab7*ix );
-            list.add ( buffer.str() );
-        }
-        for ( int ix = 1; ix <= 1024; ix++ ) {
-            buffer.clear().appendInt ( 0x42ab7*ix );
-            checkE ( ix - 1, list.indexOf ( buffer.str() ) );
-        }
+               {
+                       int capacity = 16;
+                       int blocksize = 16;
+                       int maxBlocksize = 1024*1024;
+                       bool sorted = true;
+                       CStringList list ( capacity, blocksize, maxBlocksize, ! sorted );
+                       DynBuffer buffer;
+                       int count = 1;
+                       for ( int ix = 1; ix <= count; ix++ ) {
+                               buffer.clear().appendInt ( 0x42ab7*ix );
+                               list.add ( buffer.str() );
+                       }
+                       for ( int ix = 1; ix <= count; ix++ ) {
+                               buffer.clear().appendInt ( 0x42ab7*ix );
+                               checkE ( ix - 1, list.indexOf ( buffer.str() ) );
+                       }
+                       count++;
+               }
     }
     void testIndexOfSorted() {
         int capacity = 16;
index d5ae03c1a3e9dad3115ecfaeb81e5d311a74f4fd..8b1fe0d86ba54def632fdbe26b31dbbf0429c157 100644 (file)
@@ -33,112 +33,112 @@ public:
                DynBuffer buf4(4, 8);
                buf4.append("1234");
                checkE(4, buf4.length());
-               checkE(4, buf4.size());
+               checkE(4, buf4.capacity());
                buf4.append("5");
                checkE(5, buf4.length());
                checkE("12345", buf4);
-               checkE(4+8, buf4.size());
-               checkT(buf.length() <= buf.size());
+               checkE(4+2*8, buf4.capacity());
+               checkT(buf.length() <= buf.capacity());
 
                buf = "abc";
                checkE("abc", buf);
                checkE(3, buf.length());
-               checkT(buf.length() <= buf.size());
+               checkT(buf.length() <= buf.capacity());
 
                buf = DynBuffer("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
                checkE("ABCDEFGHIJKLMNOPQRSTUVWXYZ", buf);
                checkE(26, buf.length());
-               checkT(buf.length() <= buf.size());
+               checkT(buf.length() <= buf.capacity());
        }
        void testAppend(){
                DynBuffer buf("1", 1, 1);
                checkE(1, buf.length());
-               checkT(buf.length() <= buf.size());
+               checkT(buf.length() <= buf.capacity());
                buf.append("2x", 1);
                checkE("12", buf);
                checkE(2, buf.length());
-               checkT(buf.length() <= buf.size());
+               checkT(buf.length() <= buf.capacity());
                DynBuffer buf2("xy");
                buf.append(buf2);
                checkE("12xy", buf);
                checkE(4, buf.length());
-               checkT(buf.length() <= buf.size());
+               checkT(buf.length() <= buf.capacity());
 
                buf.clear();
                checkE(0, buf.length());
                buf.append("a");
                checkE("a", buf);
                checkE(1, buf.length());
-               checkT(buf.length() <= buf.size());
+               checkT(buf.length() <= buf.capacity());
 
                buf.append("zzz", 2);
                checkE("azz", buf);
                checkE(3, buf.length());
-               checkT(buf.length() <= buf.size());
+               checkT(buf.length() <= buf.capacity());
        }
        void testAppendFormatted(){
                DynBuffer buf(2, 4);
                buf.appendFormatted("%03d%c%s", 7, 'x', "Z.").appendFormatted("%.2s", "+++++");
                checkE("007xZ.++", buf);
                checkE(8, buf.length());
-               checkT(buf.length() <= buf.size());
+               checkT(buf.length() <= buf.capacity());
 
                buf.clear();
                buf.appendFormatted("%x", 15);
                checkE("f", buf);
                checkE(1, buf.length());
-               checkT(buf.length() <= buf.size());
+               checkT(buf.length() <= buf.capacity());
 
                buf.appendFormatted("%c", '!');
                checkE("f!", buf);
                checkE(2, buf.length());
-               checkT(buf.length() <= buf.size());
+               checkT(buf.length() <= buf.capacity());
        }
        void testAppendInt(){
                DynBuffer buf(2,2);
                buf.appendInt(123);
                checkE("123", buf);
                checkE(3, buf.length());
-               checkT(buf.length() <= buf.size());
+               checkT(buf.length() <= buf.capacity());
 
                buf.appendInt(64, "%4x");
                checkE("123  40", buf);
                checkE(3 + 4, buf.length());
-               checkT(buf.length() <= buf.size());
+               checkT(buf.length() <= buf.capacity());
 
                buf.clear();
                buf.appendInt(2);
                checkE("2", buf);
                checkE(1, buf.length());
-               checkT(buf.length() <= buf.size());
+               checkT(buf.length() <= buf.capacity());
 
                buf.appendInt(8, "%02d");
                checkE("208", buf);
                checkE(3, buf.length());
-               checkT(buf.length() <= buf.size());
+               checkT(buf.length() <= buf.capacity());
        }
        void testAppendLittleEndian(){
                DynBuffer buf(2,2);
                buf.appendAsLE(0x31323334, 4);
                checkE("4321", buf);
                checkE(4, buf.length());
-               checkT(buf.length() <= buf.size());
+               checkT(buf.length() <= buf.capacity());
 
                buf.appendAsLE(0x414243, 3);
                checkE("4321CBA", buf);
                checkE(7, buf.length());
-               checkT(buf.length() <= buf.size());
+               checkT(buf.length() <= buf.capacity());
 
                buf.clear();
                buf.appendAsLE(0x6162, 2);
                checkE("ba", buf);
                checkE(2, buf.length());
-               checkT(buf.length() <= buf.size());
+               checkT(buf.length() <= buf.capacity());
 
                buf.appendAsLE(0x21);
                checkE("ba!", buf);
                checkE(3, buf.length());
-               checkT(buf.length() <= buf.size());
+               checkT(buf.length() <= buf.capacity());
        }
        void testAt(){
                DynBuffer buf("abcd");
@@ -152,7 +152,7 @@ public:
 
        void testBufferClearLength(){
                DynBuffer buf(2, 2);
-               checkE(2, buf.size());
+               checkE(2, buf.capacity());
                checkE(0, buf.length());
                const char* longString = "123456789 123456789 123456789";
                int len = strlen(longString);
@@ -160,52 +160,52 @@ public:
                buf.setLength(len);
                checkE(longString, buf);
                checkE(29, buf.length());
-               checkT(buf.length() <= buf.size());
+               checkT(buf.length() <= buf.capacity());
 
                buf.clear();
                checkE("", buf);
                checkE(0, buf.length());
-               checkT(buf.length() <= buf.size());
+               checkT(buf.length() <= buf.capacity());
        }
        void testEnsureSize(){
                DynBuffer buf(2, 2);
-               checkE(2, buf.size());
+               checkE(2, buf.capacity());
                checkE(0, buf.length());
                // blocksize is 2:
                buf.ensureSize(3);
-               checkE(4, buf.size());
+               checkE(6, buf.capacity());
                checkE(0, buf.length());
                // reserve more than blocksize:
                buf.ensureSize(7);
-               checkE(7, buf.size());
+               checkE(14, buf.capacity());
                checkE(0, buf.length());
        }
        void testSet(){
                DynBuffer buf("123");
                checkE("123", buf);
                checkE(3, buf.length());
-               checkT(buf.length() <= buf.size());
+               checkT(buf.length() <= buf.capacity());
 
                // a shorter string:
                buf.set("ab");
                checkE("ab", buf);
                checkE(2, buf.length());
-               checkT(buf.length() <= buf.size());
+               checkT(buf.length() <= buf.capacity());
 
                // a longer string:
                buf.set("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
                checkE("ABCDEFGHIJKLMNOPQRSTUVWXYZ", buf);
                checkE(26, buf.length());
-               checkT(buf.length() <= buf.size());
+               checkT(buf.length() <= buf.capacity());
        }
        void testSetBlocksize(){
                DynBuffer buf(2, 4);
-               checkE(2, buf.size());
+               checkE(2, buf.capacity());
                checkE(0, buf.length());
                checkE(4, buf.blocksize());
 
                buf.setBlocksize(23);
-               checkE(2, buf.size());
+               checkE(2, buf.capacity());
                checkE(0, buf.length());
                checkE(23, buf.blocksize());
        }
@@ -213,7 +213,7 @@ public:
                DynBuffer buf("12345");
                buf.setBlocksize(2);
                checkE("12345", buf);
-               checkE(5, buf.size());
+               checkE(5, buf.capacity());
                checkE(5, buf.length());
 
                // make it shorter:
@@ -225,7 +225,7 @@ public:
                buf.setLength(8);
                checkT(buf.startsWith("1234"));
                checkE(8, buf.length());
-               checkE(8, buf.size());
+               checkE(9, buf.capacity());
        }
        // testSize() not implemented
        void testStartsWith(){
@@ -258,7 +258,7 @@ public:
                }
        }
        void testValueOfLE(){
-               // int valueOfLE(int size, int index = 0, int defaultValue = -1);
+               // int valueOfLE(int capacity, int index = 0, int defaultValue = -1);
                DynBuffer buf("abc");
                buf.appendAsLE(0x01020304, 4).append("xyz");
                checkE(0x04, buf.valueOfLE(1, 3));
@@ -275,13 +275,13 @@ public:
        void testMemory(){
                clock_t start = clock();
                int count = 1000*1000;
-               int size = 10*1024*1024;
+               int capacity = 10*1024*1024;
                for (int ix = 0; ix < 1000; ix++){
-                       DynBuffer big(size);
-                       big.setLength(size + 10);
+                       DynBuffer big(capacity);
+                       big.setLength(capacity + 10);
                }
                double duration = (clock() - start) / CLOCKS_PER_SEC;
-               printf("allocation of %d blocks with %d MiByte: %.3f sec\n", count, size / 1024 / 1024, duration);
+               printf("allocation of %d blocks with %d MiByte: %.3f sec\n", count, capacity / 1024 / 1024, duration);
        }
 };
 
index 5efbd1e3f3f2a2d5e73a92367415b7fb9b0f0aec..d0cb90b057dbcc064bc83a40b00b9af45455185f 100644 (file)
@@ -26,7 +26,7 @@ public:
                double dummy = 0.0;
                uint64_t startReal = TimeUtils::nanosecSinceEpoche();
                uint64_t startCpu = TimeUtils::nanosecSinceBoot();
-               int count;
+               int count = 0;
                uint64_t current;
                while(startReal + MRD > (current = TimeUtils::nanosecSinceEpoche())){
                        dummy = dummy * 12.45 + 1.12345 * sin(dummy) + tan(dummy*7);
index 44d52da22c9d30b2e81cd5f3c27728ef5804107f..306cc1373bf9a05cb3a10653c271d1015f33950b 100644 (file)
@@ -3,15 +3,16 @@
 /**
  * Constructor.
  *
- * @param bufferSize   initial size of the buffer
+ * @param capacity             initial size of the buffer
  * @param blocksize            minimal increment of size when reallocation is needed<br>
  *                                             0: use <i>bufferSize</i> as block size
  */
-DynBuffer::DynBuffer(size_t bufferSize, size_t blocksize) :
-       m_size(bufferSize == 0 ? 16 : bufferSize),
+DynBuffer::DynBuffer(size_t capacity, size_t blocksize, size_t m_maxBlocksize) :
+       m_capacity(capacity == 0 ? 16 : capacity),
        m_length(0),
-       m_blocksize(blocksize == 0 ? m_size : blocksize),
-       m_buffer(new char[m_size + 1]){
+       m_blocksize(blocksize == 0 ? m_capacity : blocksize),
+       m_maxBlocksize(m_maxBlocksize),
+       m_buffer(new char[m_capacity + 1]){
        m_buffer[0] = '\0';
 }
 /**
@@ -20,16 +21,17 @@ DynBuffer::DynBuffer(size_t bufferSize, size_t blocksize) :
  * @param value                initial value
  * @param length       0: <i>strlen(value)</i> will be taken<br>
  *                                     otherwise: the length of value
- * @param size         the initial buffer size<br>
+ * @param capacity     the initial buffer size<br>
  *                                     0: size depends on <i>length</i>
  */
-DynBuffer::DynBuffer(const char* value, size_t length, size_t size) :
-       m_size(0),
+DynBuffer::DynBuffer(const char* value, size_t length, size_t capacity) :
+       m_capacity(0),
        m_length(length == 0 ? strlen(value) : length),
-       m_blocksize(256),
+       m_blocksize(8),
+       m_maxBlocksize(1024*1024),
        m_buffer(NULL){
-               m_size = size == 0 ? m_length : size < m_length ? m_length : size;
-               m_buffer = new char[m_size + 1];
+               m_capacity = capacity == 0 ? m_length : capacity < m_length ? m_length : capacity;
+               m_buffer = new char[m_capacity + 1];
                memcpy(m_buffer, value, m_length);
                m_buffer[m_length] = '\0';
        }
@@ -43,7 +45,7 @@ DynBuffer::~DynBuffer(){
        }
        m_buffer = NULL;
        m_length = 0;
-       m_size = 0;
+       m_capacity = 0;
 }
 /**
  * Copy constructor.
@@ -51,10 +53,10 @@ DynBuffer::~DynBuffer(){
  * @param source       the source to copy
  */
 DynBuffer::DynBuffer(const DynBuffer& source) :
-       m_size(source.m_length < 16 ? 16 : source.m_length),
+       m_capacity(source.m_length < 16 ? 16 : source.m_length),
        m_length(source.m_length),
        m_blocksize(256),
-       m_buffer(new char[m_size + 1])
+       m_buffer(new char[m_capacity + 1])
 {
        // copy including the trailing '\0':
        memcpy(m_buffer, source.m_buffer, m_length + 1);
@@ -67,12 +69,12 @@ DynBuffer::DynBuffer(const DynBuffer& source) :
 DynBuffer& DynBuffer::operator =(const DynBuffer& source){
        if (source.m_length == 0){
                clear();
-       } else if (m_size >= source.m_length){
+       } else if (m_capacity >= source.m_length){
                // copy with '\0':
                memcpy(m_buffer, source.m_buffer, (m_length = source.m_length) + 1);
        } else {
                delete[] m_buffer;
-               m_buffer = new char[(m_size = m_length = source.m_length) + 1];
+               m_buffer = new char[(m_capacity = m_length = source.m_length) + 1];
                // copy with '\0':
                memcpy(m_buffer, source.m_buffer, m_length + 1);
        }
@@ -145,11 +147,13 @@ DynBuffer& DynBuffer::appendAsLE(int value, size_t size){
  * @return                     <i>*this</i> (for chaining)
  */
 DynBuffer& DynBuffer::ensureSize(size_t size){
-       if (size > m_size){
-               m_size = m_size + m_blocksize;
-               if (size > m_size)
-                       m_size = size;
-               char* newBuffer = new char[m_size + 1];
+       if (size > m_capacity){
+               if ( (m_blocksize *= 2) > m_maxBlocksize)
+                       m_blocksize = m_maxBlocksize;
+               m_capacity = m_capacity + m_blocksize;
+               if (size > m_capacity)
+                       m_capacity = size;
+               char* newBuffer = new char[m_capacity + 1];
                // copy with '\0':
                memcpy(newBuffer, m_buffer, m_length + 1);
                delete[] m_buffer;
index 5416d6f84ae7dcfc18eb8a7d4b031059becad294..65b544f96ab17f9607d42e051ae188f2e8aac9b9 100644 (file)
@@ -9,7 +9,8 @@
  */
 class DynBuffer {
 public:
-       DynBuffer(size_t bufferSize = 16, size_t blocksize = 0);
+       DynBuffer(size_t capacity = 16, size_t blocksize = 0,
+                         size_t m_maxBlocksize = 1024*1024);
        DynBuffer(const char* value, size_t length = 0, size_t size = 0);
        ~DynBuffer();
        DynBuffer(const DynBuffer& source);
@@ -26,7 +27,7 @@ public:
         * @return              the instance (for chaining)
         */
        inline DynBuffer& append(char cc){
-               if (m_length >= m_size - 1)
+               if (m_length >= m_capacity - 1)
                        ensureSize(m_length + 1);
                m_buffer[m_length ++] = cc;
                return *this;
@@ -110,7 +111,7 @@ public:
         * @return                      <i>*this</i> (for chaining)
         */
     inline DynBuffer& setLength(int length){
-               if (length > (int) m_size)
+               if (length > (int) m_capacity)
                        ensureSize(length);
                m_buffer[m_length = length] = '\0';
                return *this;
@@ -120,8 +121,8 @@ public:
         *
         * @return the current size
         */
-       inline size_t size() const{
-               return m_size;
+       inline size_t capacity() const{
+               return m_capacity;
        }
        /**
         * Tests whether the buffer starts with a given string.
@@ -152,12 +153,14 @@ public:
        int valueOfLE(int size, int index = 0, int defaultValue = -1);
 private:
        /// size of the buffer (without the trailing '\0')
-       size_t m_size;
+       size_t m_capacity;
        /// length without the trailing '\0'
        size_t m_length;
        /// the minimal increment when reallocation is done
        size_t m_blocksize;
        /// Holds the buffer contents
+       size_t m_maxBlocksize;
+       // the blocksize will be doubled until this size
        char* m_buffer;
 };
 
index 3855d68b5637677f0a05b920a4ccb0b1fd135621..d065f708ab16f3338a4e1f06570fd8706a84b838 100644 (file)
@@ -8,9 +8,9 @@ int main(int argc, char **argv) {
        extern void testTimerUtils();
        extern void testArrayList();
 
+       testDynBuffer();
        testArrayList();
        testTimer();
        testTimerUtils();
-       testDynBuffer();
     return 0;
 }
index 6840c40788d7fe7ac2281f908afef6df091b5060..f85051f13b06890793b0374b47b3cc80972f1db4 100644 (file)
@@ -7,7 +7,7 @@ class ThreadPool;
  * Implements a base class of a posix thread.
  */
 class Thread {
-       friend ThreadPool;
+       friend class ThreadPool;
 public:
     Thread(Announcer* logger, bool autoDelete = true, ThreadPool* pool = NULL);
     virtual ~Thread();