summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--searchcore/src/tests/proton/common/alloc_config/alloc_config_test.cpp2
-rw-r--r--searchcore/src/tests/proton/proton_config_fetcher/proton_config_fetcher_test.cpp10
-rw-r--r--searchcore/src/vespa/searchcore/proton/common/alloc_config.cpp6
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/documentdbconfigmanager.cpp2
-rw-r--r--searchlib/src/tests/searchcommon/attribute/config/attribute_config_test.cpp3
-rw-r--r--searchlib/src/vespa/searchcommon/common/growstrategy.cpp4
-rw-r--r--searchlib/src/vespa/searchcommon/common/growstrategy.h12
-rw-r--r--searchlib/src/vespa/searchlib/attribute/attributevector.h4
-rw-r--r--searchlib/src/vespa/searchlib/attribute/changevector.h1
-rw-r--r--searchlib/src/vespa/searchlib/attribute/reference_mappings.cpp4
-rw-r--r--searchlib/src/vespa/searchlib/common/condensedbitvectors.cpp2
-rw-r--r--vespalib/src/tests/util/rcuvector/rcuvector_test.cpp53
-rw-r--r--vespalib/src/vespa/vespalib/util/growstrategy.h21
-rw-r--r--vespalib/src/vespa/vespalib/util/rcuvector.hpp5
14 files changed, 75 insertions, 54 deletions
diff --git a/searchcore/src/tests/proton/common/alloc_config/alloc_config_test.cpp b/searchcore/src/tests/proton/common/alloc_config/alloc_config_test.cpp
index 59503464222..a27c66cfaa2 100644
--- a/searchcore/src/tests/proton/common/alloc_config/alloc_config_test.cpp
+++ b/searchcore/src/tests/proton/common/alloc_config/alloc_config_test.cpp
@@ -15,7 +15,7 @@ namespace {
CompactionStrategy baseline_compaction_strategy(0.2, 0.25);
GrowStrategy make_grow_strategy(uint32_t initial_docs) {
- return GrowStrategy(initial_docs, 0.1, 1, 0.15);
+ return GrowStrategy(initial_docs, 0.1, 1, initial_docs, 0.15);
}
AllocStrategy make_alloc_strategy(uint32_t initial_docs) {
diff --git a/searchcore/src/tests/proton/proton_config_fetcher/proton_config_fetcher_test.cpp b/searchcore/src/tests/proton/proton_config_fetcher/proton_config_fetcher_test.cpp
index 4022bd68c92..f6c1518ba90 100644
--- a/searchcore/src/tests/proton/proton_config_fetcher/proton_config_fetcher_test.cpp
+++ b/searchcore/src/tests/proton/proton_config_fetcher/proton_config_fetcher_test.cpp
@@ -404,6 +404,10 @@ TEST_FF("require that docstore config computes cachesize automatically if unset"
EXPECT_EQUAL(500000ul, config->getStoreConfig().getMaxCacheBytes());
}
+GrowStrategy
+growStrategy(uint32_t initial) {
+ return GrowStrategy(initial, 0.1, 1, initial, 0.15);
+}
TEST_FF("require that allocation config is propagated",
ConfigTestFixture("test"),
DocumentDBConfigManager(f1.configId + "/test", "test"))
@@ -424,9 +428,9 @@ TEST_FF("require that allocation config is propagated",
auto config = getDocumentDBConfig(f1, f2);
{
auto& alloc_config = config->get_alloc_config();
- EXPECT_EQUAL(AllocStrategy(GrowStrategy(20000000, 0.1, 1, 0.15), CompactionStrategy(0.25, 0.3), 10000), alloc_config.make_alloc_strategy(SubDbType::READY));
- EXPECT_EQUAL(AllocStrategy(GrowStrategy(100000, 0.1, 1, 0.15), CompactionStrategy(0.25, 0.3), 10000), alloc_config.make_alloc_strategy(SubDbType::REMOVED));
- EXPECT_EQUAL(AllocStrategy(GrowStrategy(30000000, 0.1, 1, 0.15), CompactionStrategy(0.25, 0.3), 10000), alloc_config.make_alloc_strategy(SubDbType::NOTREADY));
+ EXPECT_EQUAL(AllocStrategy(growStrategy(20000000), CompactionStrategy(0.25, 0.3), 10000), alloc_config.make_alloc_strategy(SubDbType::READY));
+ EXPECT_EQUAL(AllocStrategy(growStrategy(100000), CompactionStrategy(0.25, 0.3), 10000), alloc_config.make_alloc_strategy(SubDbType::REMOVED));
+ EXPECT_EQUAL(AllocStrategy(growStrategy(30000000), CompactionStrategy(0.25, 0.3), 10000), alloc_config.make_alloc_strategy(SubDbType::NOTREADY));
}
}
diff --git a/searchcore/src/vespa/searchcore/proton/common/alloc_config.cpp b/searchcore/src/vespa/searchcore/proton/common/alloc_config.cpp
index 2eb365e245c..8525b0ea779 100644
--- a/searchcore/src/vespa/searchcore/proton/common/alloc_config.cpp
+++ b/searchcore/src/vespa/searchcore/proton/common/alloc_config.cpp
@@ -30,8 +30,8 @@ AllocConfig::operator==(const AllocConfig &rhs) const noexcept
AllocStrategy
AllocConfig::make_alloc_strategy(SubDbType sub_db_type) const
{
- auto &baseline_grow_strategy = _alloc_strategy.get_grow_strategy();
- size_t initial_capacity = baseline_grow_strategy.getDocsInitialCapacity();
+ auto &baseline = _alloc_strategy.get_grow_strategy();
+ size_t initial_capacity = baseline.getDocsInitialCapacity();
switch (sub_db_type) {
case SubDbType::READY:
initial_capacity *= _searchable_copies;
@@ -44,7 +44,7 @@ AllocConfig::make_alloc_strategy(SubDbType sub_db_type) const
initial_capacity = std::max(1024ul, initial_capacity / 100);
break;
}
- GrowStrategy grow_strategy(initial_capacity, baseline_grow_strategy.getDocsGrowFactor(), baseline_grow_strategy.getDocsGrowDelta(), baseline_grow_strategy.getMultiValueAllocGrowFactor());
+ GrowStrategy grow_strategy(initial_capacity, baseline.getDocsGrowFactor(), baseline.getDocsGrowDelta(), initial_capacity, baseline.getMultiValueAllocGrowFactor());
return AllocStrategy(grow_strategy, _alloc_strategy.get_compaction_strategy(), _alloc_strategy.get_amortize_count());
}
diff --git a/searchcore/src/vespa/searchcore/proton/server/documentdbconfigmanager.cpp b/searchcore/src/vespa/searchcore/proton/server/documentdbconfigmanager.cpp
index 64c1a9c58a7..1aadc845744 100644
--- a/searchcore/src/vespa/searchcore/proton/server/documentdbconfigmanager.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/documentdbconfigmanager.cpp
@@ -254,7 +254,7 @@ build_alloc_config(const ProtonConfig& proton_config, const vespalib::string& do
auto& document_db_config_entry = find_document_db_config_entry(proton_config.documentdb, doc_type_name);
auto& alloc_config = document_db_config_entry.allocation;
auto& distribution_config = proton_config.distribution;
- search::GrowStrategy grow_strategy(alloc_config.initialnumdocs, alloc_config.growfactor, alloc_config.growbias, alloc_config.multivaluegrowfactor);
+ search::GrowStrategy grow_strategy(alloc_config.initialnumdocs, alloc_config.growfactor, alloc_config.growbias, alloc_config.initialnumdocs, alloc_config.multivaluegrowfactor);
CompactionStrategy compaction_strategy(alloc_config.maxDeadBytesRatio, alloc_config.maxDeadAddressSpaceRatio, alloc_config.maxCompactBuffers, alloc_config.activeBuffersRatio);
return AllocConfig(AllocStrategy(grow_strategy, compaction_strategy, alloc_config.amortizecount),
distribution_config.redundancy, distribution_config.searchablecopies);
diff --git a/searchlib/src/tests/searchcommon/attribute/config/attribute_config_test.cpp b/searchlib/src/tests/searchcommon/attribute/config/attribute_config_test.cpp
index 918e14546e6..8abe5dcc414 100644
--- a/searchlib/src/tests/searchcommon/attribute/config/attribute_config_test.cpp
+++ b/searchlib/src/tests/searchcommon/attribute/config/attribute_config_test.cpp
@@ -101,11 +101,12 @@ TEST("test operator== on attribute config for tensor type")
}
TEST("Test GrowStrategy consistency") {
- GrowStrategy g(1024, 0.5, 17, 0.4f);
+ GrowStrategy g(1024, 0.5, 17, 3, 0.4f);
EXPECT_EQUAL(1024u, g.getDocsInitialCapacity());
EXPECT_EQUAL(50u, g.getDocsGrowPercent());
EXPECT_EQUAL(0.5, g.getDocsGrowFactor());
EXPECT_EQUAL(17u, g.getDocsGrowDelta());
+ EXPECT_EQUAL(3u, g.getDocsMinimumCapacity());
EXPECT_EQUAL(0.4f, g.getMultiValueAllocGrowFactor());
}
diff --git a/searchlib/src/vespa/searchcommon/common/growstrategy.cpp b/searchlib/src/vespa/searchcommon/common/growstrategy.cpp
index f35cdbaa640..36c577b1048 100644
--- a/searchlib/src/vespa/searchcommon/common/growstrategy.cpp
+++ b/searchlib/src/vespa/searchcommon/common/growstrategy.cpp
@@ -5,9 +5,11 @@
namespace search {
-std::ostream& operator<<(std::ostream& os, const GrowStrategy& grow_strategy)
+std::ostream&
+operator<<(std::ostream& os, const GrowStrategy& grow_strategy)
{
os << "{docsInitialCapacity=" << grow_strategy.getDocsInitialCapacity() <<
+ ", docsMinimumCapacity=" << grow_strategy.getDocsMinimumCapacity() <<
", docsGrowFactor=" << grow_strategy.getDocsGrowFactor() <<
", docsGrowDelta=" << grow_strategy.getDocsGrowDelta() <<
", multiValueAllocGrowFactor=" << grow_strategy.getMultiValueAllocGrowFactor() <<
diff --git a/searchlib/src/vespa/searchcommon/common/growstrategy.h b/searchlib/src/vespa/searchcommon/common/growstrategy.h
index b9b4a42cf72..3320e6ead6e 100644
--- a/searchlib/src/vespa/searchcommon/common/growstrategy.h
+++ b/searchlib/src/vespa/searchcommon/common/growstrategy.h
@@ -12,16 +12,18 @@ class GrowStrategy
{
private:
uint32_t _docsInitialCapacity;
+ uint32_t _docsMinimumCapacity;
float _docsGrowFactor;
uint32_t _docsGrowDelta;
float _multiValueAllocGrowFactor;
public:
GrowStrategy() noexcept
- : GrowStrategy(1024, 0.5, 0, 0.2)
+ : GrowStrategy(1024, 0.5, 0, 0, 0.2)
{}
GrowStrategy(uint32_t docsInitialCapacity, float docsGrowFactor,
- uint32_t docsGrowDelta, float multiValueAllocGrowFactor) noexcept
+ uint32_t docsGrowDelta, uint32_t docsMinimumCapacity, float multiValueAllocGrowFactor) noexcept
: _docsInitialCapacity(docsInitialCapacity),
+ _docsMinimumCapacity(docsMinimumCapacity),
_docsGrowFactor(docsGrowFactor),
_docsGrowDelta(docsGrowDelta),
_multiValueAllocGrowFactor(multiValueAllocGrowFactor)
@@ -29,19 +31,21 @@ public:
}
static GrowStrategy make(uint32_t docsInitialCapacity, float docsGrowFactor, uint32_t docsGrowDelta) {
- return GrowStrategy(docsInitialCapacity, docsGrowFactor, docsGrowDelta, 0.2);
+ return GrowStrategy(docsInitialCapacity, docsGrowFactor, docsGrowDelta, 0, 0.2);
}
uint32_t getDocsInitialCapacity() const { return _docsInitialCapacity; }
+ uint32_t getDocsMinimumCapacity() const { return _docsMinimumCapacity; }
uint32_t getDocsGrowPercent() const { return _docsGrowFactor*100; }
float getDocsGrowFactor() const { return _docsGrowFactor; }
uint32_t getDocsGrowDelta() const { return _docsGrowDelta; }
float getMultiValueAllocGrowFactor() const { return _multiValueAllocGrowFactor; }
void setDocsInitialCapacity(uint32_t v) { _docsInitialCapacity = v; }
+ void setDocsMinimumCapacity(uint32_t v) { _docsMinimumCapacity = v; }
void setDocsGrowDelta(uint32_t v) { _docsGrowDelta = v; }
vespalib::GrowStrategy to_generic_strategy() const {
- return vespalib::GrowStrategy(_docsInitialCapacity, _docsGrowFactor, _docsGrowDelta);
+ return vespalib::GrowStrategy(_docsInitialCapacity, _docsGrowFactor, _docsGrowDelta, _docsMinimumCapacity);
}
bool operator==(const GrowStrategy & rhs) const {
diff --git a/searchlib/src/vespa/searchlib/attribute/attributevector.h b/searchlib/src/vespa/searchlib/attribute/attributevector.h
index 57c73067671..09dc27f0451 100644
--- a/searchlib/src/vespa/searchlib/attribute/attributevector.h
+++ b/searchlib/src/vespa/searchlib/attribute/attributevector.h
@@ -5,7 +5,6 @@
#include "address_space_usage.h"
#include "changevector.h"
#include "readable_attribute_vector.h"
-#include <vespa/fastlib/text/normwordfolder.h>
#include <vespa/searchcommon/attribute/config.h>
#include <vespa/searchcommon/attribute/i_search_context.h>
#include <vespa/searchcommon/attribute/iattributevector.h>
@@ -19,8 +18,7 @@
#include <vespa/searchlib/queryeval/searchiterator.h>
#include <vespa/vespalib/objects/identifiable.h>
#include <vespa/vespalib/stllike/asciistream.h>
-#include <vespa/vespalib/util/address_space.h>
-#include <vespa/vespalib/util/rcuvector.h>
+#include <vespa/vespalib/util/generationholder.h>
#include <vespa/vespalib/util/time.h>
#include <cmath>
#include <mutex>
diff --git a/searchlib/src/vespa/searchlib/attribute/changevector.h b/searchlib/src/vespa/searchlib/attribute/changevector.h
index d929e8615a9..5f858a3e012 100644
--- a/searchlib/src/vespa/searchlib/attribute/changevector.h
+++ b/searchlib/src/vespa/searchlib/attribute/changevector.h
@@ -3,6 +3,7 @@
#pragma once
#include <vespa/searchcommon/common/undefinedvalues.h>
+#include <vespa/vespalib/util/memoryusage.h>
#include <vector>
namespace vespalib { class MemoryUsage; }
diff --git a/searchlib/src/vespa/searchlib/attribute/reference_mappings.cpp b/searchlib/src/vespa/searchlib/attribute/reference_mappings.cpp
index fe61913b801..37b7a82ab55 100644
--- a/searchlib/src/vespa/searchlib/attribute/reference_mappings.cpp
+++ b/searchlib/src/vespa/searchlib/attribute/reference_mappings.cpp
@@ -9,10 +9,10 @@
namespace search::attribute {
ReferenceMappings::ReferenceMappings(GenerationHolder &genHolder, const std::atomic<uint32_t>& committedDocIdLimit)
- : _reverseMappingIndices(vespalib::GrowStrategy(16, 1.0, 0), genHolder),
+ : _reverseMappingIndices(vespalib::GrowStrategy(16, 1.0, 0, 0), genHolder),
_targetLidLimit(0),
_reverseMapping(),
- _targetLids(vespalib::GrowStrategy(16, 1.0, 0), genHolder),
+ _targetLids(vespalib::GrowStrategy(16, 1.0, 0, 0), genHolder),
_committedDocIdLimit(committedDocIdLimit)
{
}
diff --git a/searchlib/src/vespa/searchlib/common/condensedbitvectors.cpp b/searchlib/src/vespa/searchlib/common/condensedbitvectors.cpp
index 74df5c8c5d4..15e09172718 100644
--- a/searchlib/src/vespa/searchlib/common/condensedbitvectors.cpp
+++ b/searchlib/src/vespa/searchlib/common/condensedbitvectors.cpp
@@ -17,7 +17,7 @@ class CondensedBitVectorT : public CondensedBitVector
{
public:
CondensedBitVectorT(size_t sz, GenerationHolder &genHolder) :
- _v(vespalib::GrowStrategy(sz, 30, 1000), genHolder)
+ _v(vespalib::GrowStrategy(sz, 30, 1000, 0), genHolder)
{
for (size_t i = 0; i < sz; ++i) {
_v.push_back(0);
diff --git a/vespalib/src/tests/util/rcuvector/rcuvector_test.cpp b/vespalib/src/tests/util/rcuvector/rcuvector_test.cpp
index 0190d59edfb..eb2b00f9e20 100644
--- a/vespalib/src/tests/util/rcuvector/rcuvector_test.cpp
+++ b/vespalib/src/tests/util/rcuvector/rcuvector_test.cpp
@@ -31,10 +31,15 @@ assertUsage(const MemoryUsage & exp, const MemoryUsage & act)
return retval;
}
+GrowStrategy
+growStrategy(size_t initial, float factor, size_t delta, size_t minimal = 0) {
+ return GrowStrategy(initial, factor, delta, minimal);
+}
+
TEST(RcuVectorTest, basic)
{
{ // insert
- RcuVector<int32_t> v(GrowStrategy(4, 0, 4));
+ RcuVector<int32_t> v(growStrategy(4, 0, 4));
for (int32_t i = 0; i < 100; ++i) {
v.push_back(i);
EXPECT_EQ(i, v[i]);
@@ -53,7 +58,7 @@ TEST(RcuVectorTest, basic)
TEST(RcuVectorTest, resize)
{
{ // resize percent
- RcuVector<int32_t> v(GrowStrategy(2, 0.50, 0));
+ RcuVector<int32_t> v(growStrategy(2, 0.50, 0));
EXPECT_EQ(2u, v.capacity());
v.push_back(0);
EXPECT_EQ(2u, v.capacity());
@@ -65,7 +70,7 @@ TEST(RcuVectorTest, resize)
EXPECT_TRUE(v.isFull());
}
{ // resize delta
- RcuVector<int32_t> v(GrowStrategy(1, 0, 3));
+ RcuVector<int32_t> v(growStrategy(1, 0, 3));
EXPECT_EQ(1u, v.capacity());
v.push_back(0);
EXPECT_EQ(1u, v.capacity());
@@ -75,7 +80,7 @@ TEST(RcuVectorTest, resize)
EXPECT_TRUE(!v.isFull());
}
{ // resize both
- RcuVector<int32_t> v(GrowStrategy(2, 2.0, 3));
+ RcuVector<int32_t> v(growStrategy(2, 2.0, 3));
EXPECT_EQ(2u, v.capacity());
v.push_back(0);
EXPECT_EQ(2u, v.capacity());
@@ -87,14 +92,14 @@ TEST(RcuVectorTest, resize)
EXPECT_TRUE(!v.isFull());
}
{ // reserve
- RcuVector<int32_t> v(GrowStrategy(2, 0, 0));
+ RcuVector<int32_t> v(growStrategy(2, 0, 0));
EXPECT_EQ(2u, v.capacity());
v.unsafe_reserve(8);
EXPECT_EQ(8u, v.capacity());
}
{ // explicit resize
GenerationHolder g;
- RcuVectorBase<int8_t> v(GrowStrategy(16, 1.0, 0), g);
+ RcuVectorBase<int8_t> v(growStrategy(16, 1.0, 0), g);
v.push_back(1);
v.push_back(2);
g.transferHoldLists(0);
@@ -120,7 +125,7 @@ TEST(RcuVectorTest, resize)
TEST(RcuVectorTest, generation_handling)
{
- RcuVector<int32_t> v(GrowStrategy(2, 0, 2));
+ RcuVector<int32_t> v(growStrategy(2, 0, 2));
v.push_back(0);
v.push_back(10);
EXPECT_EQ(0u, v.getMemoryUsage().allocatedBytesOnHold());
@@ -143,7 +148,7 @@ TEST(RcuVectorTest, generation_handling)
TEST(RcuVectorTest, reserve)
{
- RcuVector<int32_t> v(GrowStrategy(2, 0, 2));
+ RcuVector<int32_t> v(growStrategy(2, 0, 2));
EXPECT_EQ(2u, v.capacity());
EXPECT_EQ(0u, v.size());
v.push_back(0);
@@ -167,7 +172,7 @@ TEST(RcuVectorTest, reserve)
TEST(RcuVectorTest, memory_usage)
{
- RcuVector<int8_t> v(GrowStrategy(2, 0, 2));
+ RcuVector<int8_t> v(growStrategy(2, 0, 2));
EXPECT_TRUE(assertUsage(MemoryUsage(2,0,0,0), v.getMemoryUsage()));
v.push_back(0);
EXPECT_TRUE(assertUsage(MemoryUsage(2,1,0,0), v.getMemoryUsage()));
@@ -183,10 +188,11 @@ TEST(RcuVectorTest, memory_usage)
EXPECT_TRUE(assertUsage(MemoryUsage(6,5,0,0), v.getMemoryUsage()));
}
-TEST(RcuVectorTest, shrink_with_buffer_copying)
-{
+void verify_shrink_with_buffer_copying(size_t initial_size, size_t absolute_minimum) {
+ const size_t minimal_capacity = std::max(4ul, absolute_minimum);
+ const size_t initial_capacity = std::max(initial_size, minimal_capacity);
GenerationHolder g;
- RcuVectorBase<int8_t> v(GrowStrategy(16, 1.0, 0), g);
+ RcuVectorBase<int8_t> v(growStrategy(initial_size, 1.0, 0, absolute_minimum), g);
v.push_back(1);
v.push_back(2);
v.push_back(3);
@@ -196,9 +202,9 @@ TEST(RcuVectorTest, shrink_with_buffer_copying)
MemoryUsage mu;
mu = v.getMemoryUsage();
mu.incAllocatedBytesOnHold(g.getHeldBytes());
- EXPECT_TRUE(assertUsage(MemoryUsage(16, 4, 0, 0), mu));
+ EXPECT_TRUE(assertUsage(MemoryUsage(initial_capacity, 4, 0, 0), mu));
EXPECT_EQ(4u, v.size());
- EXPECT_EQ(16u, v.capacity());
+ EXPECT_EQ(initial_capacity, v.capacity());
EXPECT_EQ(1, v[0]);
EXPECT_EQ(2, v[1]);
EXPECT_EQ(3, v[2]);
@@ -207,7 +213,7 @@ TEST(RcuVectorTest, shrink_with_buffer_copying)
v.shrink(2);
g.transferHoldLists(1);
EXPECT_EQ(2u, v.size());
- EXPECT_EQ(4u, v.capacity());
+ EXPECT_EQ(minimal_capacity, v.capacity());
EXPECT_EQ(1, v[0]);
EXPECT_EQ(2, v[1]);
EXPECT_EQ(1, old[0]);
@@ -217,7 +223,14 @@ TEST(RcuVectorTest, shrink_with_buffer_copying)
EXPECT_EQ(2, v[1]);
mu = v.getMemoryUsage();
mu.incAllocatedBytesOnHold(g.getHeldBytes());
- EXPECT_TRUE(assertUsage(MemoryUsage(4, 2, 0, 0), mu));
+ EXPECT_TRUE(assertUsage(MemoryUsage(minimal_capacity, 2, 0, 0), mu));
+}
+
+TEST(RcuVectorTest, shrink_with_buffer_copying)
+{
+ verify_shrink_with_buffer_copying(16, 8);
+ verify_shrink_with_buffer_copying(0, 8);
+ verify_shrink_with_buffer_copying(0, 0);
}
struct ShrinkFixture {
@@ -229,7 +242,7 @@ struct ShrinkFixture {
ShrinkFixture() : g(),
initial_capacity(4 * page_ints()),
initial_size(initial_capacity / 1024 * 1000),
- vec(GrowStrategy(initial_capacity, 0.50, 0), g, alloc::Alloc::allocMMap()), oldPtr()
+ vec(growStrategy(initial_capacity, 0.50, 0), g, alloc::Alloc::allocMMap()), oldPtr()
{
for (size_t i = 0; i < initial_size; ++i) {
vec.push_back(7);
@@ -272,7 +285,7 @@ TEST(RcuVectorTest, shrink_can_shrink_mmap_allocation)
TEST(RcuVectorTest, small_expand)
{
GenerationHolder g;
- RcuVectorBase<int8_t> v(GrowStrategy(1, 0.50, 0), g);
+ RcuVectorBase<int8_t> v(growStrategy(1, 0.50, 0), g);
EXPECT_EQ(1u, v.capacity());
EXPECT_EQ(0u, v.size());
v.push_back(1);
@@ -321,7 +334,7 @@ struct Fixture : public FixtureBase {
Fixture::Fixture()
: FixtureBase(),
- arr(GrowStrategy(16, 1.0, 0), g, initial_alloc)
+ arr(growStrategy(16, 1.0, 0), g, initial_alloc)
{
arr.reserve(100);
}
@@ -403,7 +416,7 @@ struct StressFixture : public FixtureBase {
StressFixture::StressFixture()
: FixtureBase(),
- arr(GrowStrategy(16, 1.0, 0), g, initial_alloc),
+ arr(growStrategy(16, 1.0, 0), g, initial_alloc),
stop_read(false),
read_area(1000),
generation_handler(),
diff --git a/vespalib/src/vespa/vespalib/util/growstrategy.h b/vespalib/src/vespa/vespalib/util/growstrategy.h
index dad83a5f704..efac26ce19d 100644
--- a/vespalib/src/vespa/vespalib/util/growstrategy.h
+++ b/vespalib/src/vespa/vespalib/util/growstrategy.h
@@ -9,32 +9,29 @@ namespace vespalib {
class GrowStrategy {
private:
size_t _initialCapacity;
- float _growFactor;
+ size_t _minimumCapacity;
size_t _growDelta;
+ float _growFactor;
public:
GrowStrategy() noexcept
- : GrowStrategy(1024, 0.5, 0)
+ : GrowStrategy(1024, 0.5, 0, 0)
{}
- GrowStrategy(size_t initialCapacity, float growPercent, size_t growDelta) noexcept
+ GrowStrategy(size_t initialCapacity, float growPercent, size_t growDelta, size_t minimumCapacity) noexcept
: _initialCapacity(initialCapacity),
- _growFactor(growPercent),
- _growDelta(growDelta)
+ _minimumCapacity(minimumCapacity),
+ _growDelta(growDelta),
+ _growFactor(growPercent)
{
}
- static GrowStrategy make(size_t initialCapacity, float growFactor, size_t growDelta) noexcept {
- return GrowStrategy(initialCapacity, growFactor, growDelta);
- }
-
+ size_t getMinimumCapacity() const noexcept { return _minimumCapacity; }
size_t getInitialCapacity() const noexcept { return _initialCapacity; }
- size_t getGrowPercent() const noexcept { return _growFactor*100; }
float getGrowFactor() const noexcept { return _growFactor; }
size_t getGrowDelta() const noexcept { return _growDelta; }
- void setInitialCapacity(size_t v) noexcept { _initialCapacity = v; }
- void setGrowDelta(size_t v) noexcept { _growDelta = v; }
bool operator==(const GrowStrategy & rhs) const noexcept {
return (_initialCapacity == rhs._initialCapacity &&
+ _minimumCapacity == rhs._minimumCapacity &&
_growFactor == rhs._growFactor &&
_growDelta == rhs._growDelta);
}
diff --git a/vespalib/src/vespa/vespalib/util/rcuvector.hpp b/vespalib/src/vespa/vespalib/util/rcuvector.hpp
index 3c76ed22471..35a5fda81e4 100644
--- a/vespalib/src/vespa/vespalib/util/rcuvector.hpp
+++ b/vespalib/src/vespa/vespalib/util/rcuvector.hpp
@@ -20,7 +20,8 @@ RcuVectorHeld<T>::~RcuVectorHeld() = default;
template <typename T>
size_t RcuVectorBase<T>::calcNewSize(size_t baseSize) const {
size_t delta = (baseSize * _growStrategy.getGrowFactor()) + _growStrategy.getGrowDelta();
- return baseSize + std::max(delta, static_cast<size_t>(1));
+ size_t newSize = baseSize + std::max(delta, static_cast<size_t>(1));
+ return std::max(newSize, _growStrategy.getMinimumCapacity());
}
template <typename T>
size_t RcuVectorBase<T>::calcNewSize() const {
@@ -166,7 +167,7 @@ RcuVector<T>::onReallocation() {
template <typename T>
RcuVector<T>::RcuVector()
- : RcuVectorBase<T>(GrowStrategy(16, 1.0, 0), _genHolderStore),
+ : RcuVectorBase<T>(GrowStrategy(16, 1.0, 0, 0), _genHolderStore),
_generation(0),
_genHolderStore()
{ }