diff options
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() { } |