From e9b9584a587af65817fe0d04bedd939ec004a185 Mon Sep 17 00:00:00 2001 From: Tor Egge Date: Wed, 9 Feb 2022 16:22:31 +0100 Subject: Add reset and create methods to vespalib::Array. --- vespalib/src/tests/array/array_test.cpp | 48 ++++++++++++++++++++++++++++++ vespalib/src/vespa/vespalib/util/alloc.h | 7 +++++ vespalib/src/vespa/vespalib/util/array.h | 2 ++ vespalib/src/vespa/vespalib/util/array.hpp | 15 ++++++++++ 4 files changed, 72 insertions(+) diff --git a/vespalib/src/tests/array/array_test.cpp b/vespalib/src/tests/array/array_test.cpp index 719623c9401..5f80ee893da 100644 --- a/vespalib/src/tests/array/array_test.cpp +++ b/vespalib/src/tests/array/array_test.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -27,6 +28,11 @@ std::ostream & operator << (std::ostream & os, const Array & a) } +using alloc::Alloc; +using alloc::MemoryAllocator; +using MyMemoryAllocator = vespalib::alloc::test::MemoryAllocatorObserver; +using AllocStats = MyMemoryAllocator::Stats; + class Clever { public: Clever() : _counter(&_global) { (*_counter)++; } @@ -351,4 +357,46 @@ TEST_F("require that try_unreserve() succeedes if mmap can be shrinked", Unreser EXPECT_EQUAL(oldPtr, newPtr); } +struct Fixture { + AllocStats stats; + std::unique_ptr allocator; + Alloc initial_alloc; + Array arr; + + Fixture(); + ~Fixture(); +}; + +Fixture::Fixture() + : stats(), + allocator(std::make_unique(stats)), + initial_alloc(Alloc::alloc_with_allocator(allocator.get())), + arr(initial_alloc) +{ +} + +Fixture::~Fixture() = default; + +TEST_F("require that memory allocator can be set", Fixture) +{ + f.arr.resize(1); + EXPECT_EQUAL(AllocStats(1, 0), f.stats); +} + +TEST_F("require that memory allocator is preserved across reset", Fixture) +{ + f.arr.resize(1); + f.arr.reset(); + f.arr.resize(1); + EXPECT_EQUAL(AllocStats(2, 1), f.stats); +} + +TEST_F("require that created array uses same memory allocator", Fixture) +{ + auto arr2 = f.arr.create(); + EXPECT_EQUAL(AllocStats(0, 0), f.stats); + arr2.resize(1); + EXPECT_EQUAL(AllocStats(1, 0), f.stats); +} + TEST_MAIN() { TEST_RUN_ALL(); } diff --git a/vespalib/src/vespa/vespalib/util/alloc.h b/vespalib/src/vespa/vespalib/util/alloc.h index d25fb6f6a7c..4066894b4e3 100644 --- a/vespalib/src/vespa/vespalib/util/alloc.h +++ b/vespalib/src/vespa/vespalib/util/alloc.h @@ -62,6 +62,13 @@ public: std::swap(_alloc, rhs._alloc); std::swap(_allocator, rhs._allocator); } + void reset() { + if (_alloc.first != nullptr) { + _allocator->free(_alloc); + _alloc.first = nullptr; + _alloc.second = 0u; + } + } Alloc create(size_t sz) const noexcept { return (sz == 0) ? Alloc(_allocator) : Alloc(_allocator, sz); } diff --git a/vespalib/src/vespa/vespalib/util/array.h b/vespalib/src/vespa/vespalib/util/array.h index 30d87cd98f6..cb5d5c7cc63 100644 --- a/vespalib/src/vespa/vespalib/util/array.h +++ b/vespalib/src/vespa/vespalib/util/array.h @@ -135,6 +135,7 @@ public: std::destroy(array(0), array(_sz)); _sz = 0; } + void reset(); bool empty() const { return _sz == 0; } T & operator [] (size_t i) { return *array(i); } const T & operator [] (size_t i) const { return *array(i); } @@ -145,6 +146,7 @@ public: rhs._sz = 0; return std::move(rhs._array); } + Array create() const; private: T * array(size_t i) { return static_cast(_array.get()) + i; } const T * array(size_t i) const { return static_cast(_array.get()) + i; } diff --git a/vespalib/src/vespa/vespalib/util/array.hpp b/vespalib/src/vespa/vespalib/util/array.hpp index e9070f5759c..72178f0391b 100644 --- a/vespalib/src/vespa/vespalib/util/array.hpp +++ b/vespalib/src/vespa/vespalib/util/array.hpp @@ -205,5 +205,20 @@ void Array::cleanup() Alloc().swap(_array); } +template +void Array::reset() +{ + std::destroy(array(0), array(_sz)); + _sz = 0; + _array.reset(); +} + +template +Array +Array::create() const +{ + return Array(_array); // Use same memory allocator +} + } -- cgit v1.2.3