diff --git a/bflibcpp/src/array.hpp b/bflibcpp/src/array.hpp index 342ea99..cf114f8 100644 --- a/bflibcpp/src/array.hpp +++ b/bflibcpp/src/array.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "access.hpp" #include "vector.hpp" @@ -16,6 +17,10 @@ #include "exception.hpp" #include "swap.hpp" +extern "C" { +#include +} + namespace BF { /** @@ -26,8 +31,14 @@ namespace BF { * * Objects stored in array are assumed to be owned by owner of array * object + * + * blockSize: + * block size of memory allocation + * + * each reallocation where count > capacity, will always + * allocate memory in blocks of blockSize */ -template +template class Array : public Vector { public: virtual const char * className() const { @@ -39,6 +50,9 @@ class Array : public Vector { this->_count = 0; this->_callback = Array::comparisonDefault; this->_releasecb = NULL; + + this->_capacity = 0; + this->allocate(*this, blockSize); } /** @@ -75,7 +89,8 @@ class Array : public Vector { } } - this->deallocate(this->_address); + //this->deallocate(this->_address); + this->deallocate(*this); this->_address = 0; this->_count = 0; } @@ -180,7 +195,6 @@ class Array : public Vector { return res; } - /** * Prints the array from the first element to the last */ @@ -210,9 +224,9 @@ class Array : public Vector { /** * Copies content from arr to us */ - void copyFromArray(const Array * arr) { + void copyFromArray(const Array * arr) { this->removeAll(); - this->_address = (T *) this->allocate(arr->count()); + this->allocate(*this, arr->count()); this->_count = arr->count(); memcpy(this->_address, arr->address(), this->_count); } @@ -220,9 +234,8 @@ class Array : public Vector { /** * copies content of arr to the end of ours */ - void append(const Array & arr) { - this->_address = this->reallocate(this->_address, this->_count + arr._count); - //memcpy(&this->_address[this->_count], &arr._address[0], arr._count); + void append(const Array & arr) { + this->reallocate(*this, this->_count, this->_count + arr._count); for (int i = this->_count; i < this->_count + arr._count; i++) { this->_address[i] = arr._address[i - this->_count]; } @@ -233,7 +246,7 @@ class Array : public Vector { * Adds object at the end of the array */ int add(T obj) { - this->_address = this->reallocate(this->_address, this->_count + 1); + this->reallocate(*this, this->_count, this->_count + 1); if (this->_address == NULL) { this->_count = 0; return -3; @@ -290,37 +303,52 @@ class Array : public Vector { * adjusts address memory to size */ void adjustMemorySize(S size) { + this->reallocate(*this, this->_count, size); this->_count = size; - this->_address = this->reallocate(this->_address, this->_count); } /** * Returns address of array */ - T * address() const { return this->_address; } + T * address() const { + // capacity may be > 0 and _address may be allocated + if (this->_count == 0) return NULL; + return this->_address; + } private: - /** - * uses malloc to allocate mem - */ - static T * allocate(S size) { - return (T *) malloc(sizeof(T) * size); + static void allocate(Array & array, S size) { + if (size > array._capacity) { + array._capacity = size; + array._address = (T *) new T[size]; + } } - /** - * returns modified `addr` with `newsize` - */ - static T * reallocate(T * addr, S newsize) { - return (T *) realloc(addr, sizeof(T) * newsize); + static void reallocate(Array & array, S oldsize, S newsize) { + if (newsize < array._capacity) { + return; + } + + S adjustedNewSize = (((newsize / blockSize) + 1) * blockSize); + array._capacity = adjustedNewSize; + T * res = new T[adjustedNewSize]; + memcpy(res, array._address, sizeof(T) * oldsize); + memset(array._address, 0, sizeof(T) * oldsize); + + delete[] array._address; + array._address = res; + + return; } /** * Derived must make sure this follows the standard established * by allocate() */ - static void deallocate(T * value) { - free((void *) value); + static void deallocate(Array & array) { + delete[] array._address; + array._capacity = 0; } /** @@ -328,7 +356,7 @@ class Array : public Vector { */ void saveArray(const T * array, S size) { this->removeAll(); - this->_address = (T *) this->allocate(size); + this->allocate(*this, size); this->_count = size; if (this->_address) { @@ -347,7 +375,7 @@ class Array : public Vector { typename std::initializer_list::iterator itr; this->_count = list.size(); - this->_address = (T *) this->allocate(this->_count); + this->allocate(*this, this->_count); if (this->_address) { S i = 0; @@ -368,6 +396,12 @@ class Array : public Vector { /// Holds size of _address S _count; + /** + * will hold a certain amount of reserved space for the + * array elements. we will ask for more memory when _count > _capacity + */ + S _capacity; + /** * How we compare each item in the array */ @@ -390,7 +424,7 @@ class Array : public Vector { /** * Copies the string content from arr to us */ - virtual Array & operator=(const Array & arr) { + virtual Array & operator=(const Array & arr) { this->copyFromArray(&arr); return *this; } diff --git a/bflibcpp/src/data.cpp b/bflibcpp/src/data.cpp index c87434f..443f611 100644 --- a/bflibcpp/src/data.cpp +++ b/bflibcpp/src/data.cpp @@ -64,7 +64,7 @@ Data::Data(const Data & in) : Data(in.size(), (unsigned char *) in.buffer()) { } Data::~Data() { } -Data::Data(const size_t size, const unsigned char * data) : Array() { +Data::Data(const size_t size, const unsigned char * data) : Array() { this->alloc(size, data); } diff --git a/bflibcpp/src/data.hpp b/bflibcpp/src/data.hpp index 0ad530a..4315933 100644 --- a/bflibcpp/src/data.hpp +++ b/bflibcpp/src/data.hpp @@ -14,7 +14,7 @@ namespace BF { class String; class URL; -class Data : public Array { +class Data : public Array { public: virtual const char * className() const; diff --git a/bflibcpp/src/list.hpp b/bflibcpp/src/list.hpp index 541d5f7..31ebcfb 100644 --- a/bflibcpp/src/list.hpp +++ b/bflibcpp/src/list.hpp @@ -15,7 +15,7 @@ namespace BF { -template