diff --git a/pvDataApp/misc/sharedVector.h b/pvDataApp/misc/sharedVector.h index fb6cd99..8e64f39 100644 --- a/pvDataApp/misc/sharedVector.h +++ b/pvDataApp/misc/sharedVector.h @@ -6,6 +6,8 @@ #include #include +#include + #include "pv/sharedPtr.h" namespace epics { namespace pvData { @@ -423,9 +425,34 @@ public: // Modifications +private: + void _push_resize() { + if(this->m_count==this->m_total || !this->unique()) { + size_t next; + if(this->m_total<1024) { + // round m_total+1 up to the next power of 2 + next = this->m_total; + next |= next >> 1; + next |= next >> 2; + next |= next >> 4; + next |= next >> 8; + next++; + } else { + // pad m_total up to the next multiple of 1024 + next = this->m_total+1024; + next &= ~0x3ff; + } + assert(next > this->m_total); + reserve(next); + } + resize(this->size()+1); + } + +public: + void push_back(param_type v) { - resize(this->size()+1); + _push_resize(); back() = v; } diff --git a/testApp/misc/testSharedVector.cpp b/testApp/misc/testSharedVector.cpp index 685b8f9..8895124 100644 --- a/testApp/misc/testSharedVector.cpp +++ b/testApp/misc/testSharedVector.cpp @@ -329,6 +329,31 @@ static void testCapacity() testOk1(vect[1]==124); } +static void testPush() +{ + epics::pvData::shared_vector vect; + + testDiag("Test push_back optimizations"); + + size_t nallocs = 0; + size_t cap = vect.capacity(); + + for(size_t s=0; s<16*1024; s++) { + vect.push_back(s); + + if(cap!=vect.capacity()) { + nallocs++; + cap = vect.capacity(); + } + } + + testDiag("push_back %ld times caused %ld re-allocations", + (unsigned long)vect.size(), + (unsigned long)nallocs); + + testOk1(nallocs==26); +} + static void testVoid() { testDiag("Test vecter cast to/from void"); @@ -409,7 +434,7 @@ static void testWeak() MAIN(testSharedVector) { - testPlan(121); + testPlan(122); testDiag("Tests for shared_vector"); testDiag("sizeof(shared_vector)=%lu", @@ -422,6 +447,7 @@ MAIN(testSharedVector) testShare(); testConst(); testSlice(); + testPush(); testVoid(); testNonPOD(); testWeak();