Skip to content

Commit 8224853

Browse files
committed
Fixed review comments.
1 parent 4509757 commit 8224853

File tree

2 files changed

+30
-74
lines changed

2 files changed

+30
-74
lines changed

core/resource_manager.hpp

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ struct ResourceManagementOptions {
7474
IResourceManager* cached_columns{&IResourceManager::kNoop};
7575
};
7676

77+
// Memory manager for IResearch.
78+
// This is a singleton class
7779
struct IResearchMemoryManager : public IResourceManager {
7880
protected:
7981
IResearchMemoryManager() = default;
@@ -86,19 +88,19 @@ struct IResearchMemoryManager : public IResourceManager {
8688
IRS_ASSERT(this != &kForbidden);
8789
IRS_ASSERT(value >= 0);
8890

89-
if (0 == IResearchMemoryManager::_memory_limit) {
91+
if (0 == _memoryLimit) {
9092
// since we have no limit, we can simply use fetch-add for the increment
91-
IResearchMemoryManager::_current.fetch_add(value, std::memory_order_relaxed);
93+
_current.fetch_add(value, std::memory_order_relaxed);
9294
} else {
9395
// we only want to perform the update if we don't exceed the limit!
94-
std::uint64_t cur = IResearchMemoryManager::_current.load(std::memory_order_relaxed);
96+
std::uint64_t cur = _current.load(std::memory_order_relaxed);
9597
std::uint64_t next;
9698
do {
9799
next = cur + value;
98-
if (IRS_UNLIKELY(next > IResearchMemoryManager::_memory_limit.load(std::memory_order_relaxed))) {
100+
if (IRS_UNLIKELY(next > _memoryLimit.load(std::memory_order_relaxed))) {
99101
throw std::bad_alloc();
100102
}
101-
} while (!IResearchMemoryManager::_current.compare_exchange_weak(
103+
} while (!_current.compare_exchange_weak(
102104
cur, next, std::memory_order_relaxed));
103105
}
104106
}
@@ -109,28 +111,30 @@ struct IResearchMemoryManager : public IResourceManager {
109111
_current.fetch_sub(value, std::memory_order_relaxed);
110112
}
111113

112-
protected:
113-
// This limit can be set only by IResearchFeature.
114-
// During IResearchFeature::prepare() it is set to a pre-defined
115-
// percentage of the total available physical memory or to the value
116-
// of ARANGODB_OVERRIDE_DETECTED_TOTAL_MEMORY option if specified.
117-
static inline std::atomic<std::uint64_t> _memory_limit = { 0 };
118-
119-
// Singleton
120-
static inline std::shared_ptr<IResourceManager> _instance;
114+
// NOTE: IResearchFeature owns and manages this memory limit.
115+
// That is why this method should only be used by IResearchFeature.
116+
virtual void SetMemoryLimit(uint64_t memoryLimit) {
117+
_memoryLimit.store(memoryLimit);
118+
}
121119

122120
private:
123-
static inline std::atomic<std::uint64_t> _current = { 0 };
121+
// This limit should be set exclusively by IResearchFeature.
122+
// During IResearchFeature::validateOptions() this limit is set to a
123+
// percentage of either the total available physical memory or the value
124+
// of ARANGODB_OVERRIDE_DETECTED_TOTAL_MEMORY envvar if specified.
125+
std::atomic<std::uint64_t> _memoryLimit = { 0 };
126+
std::atomic<std::uint64_t> _current = { 0 };
127+
128+
// Singleton
129+
static inline std::shared_ptr<IResearchMemoryManager> _instance;
124130

125131
public:
126-
static std::shared_ptr<IResourceManager> GetInstance() {
132+
static std::shared_ptr<IResearchMemoryManager> GetInstance() {
127133
if (!_instance.get())
128134
_instance.reset(new IResearchMemoryManager());
129135

130136
return _instance;
131137
}
132-
133-
friend class arangodb::iresearch::IResearchFeature;
134138
};
135139

136140
template<typename T>

tests/memory/IResearchMemoryManager_tests.cpp

Lines changed: 8 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -29,72 +29,24 @@
2929

3030
using namespace irs;
3131

32-
// Wrapper class around IResearchMemoryManager.
33-
// We use it to track memory increase/decrease.
34-
// To be used mostly for debugging purposes.
35-
struct IResearchMemoryManagerAccessor : public irs::IResearchMemoryManager {
32+
TEST(IResearchMemoryLimitTest, managed_allocator_smoke_test) {
3633

37-
IResearchMemoryManagerAccessor() = default;
38-
virtual ~IResearchMemoryManagerAccessor() = default;
39-
40-
virtual void Increase([[maybe_unused]] uint64_t value) override {
41-
42-
// std::cout << "Increase: " << value << std::endl;
43-
IResearchMemoryManager::Increase(value);
44-
}
45-
46-
virtual void Decrease([[maybe_unused]] uint64_t value) noexcept override {
47-
// std::cout << "Decrease: " << value << std::endl;
48-
IResearchMemoryManager::Decrease(value);
49-
}
50-
51-
static std::shared_ptr<IResearchMemoryManagerAccessor> GetInstance() {
52-
if (!_accessor)
53-
_accessor.reset(new IResearchMemoryManagerAccessor());
54-
55-
return _accessor;
56-
}
57-
58-
static void setMemoryLimit(uint64_t limit) {
59-
irs::IResearchMemoryManager::_memory_limit.store(limit);
60-
}
61-
62-
private:
63-
static inline std::shared_ptr<IResearchMemoryManagerAccessor> _accessor;
64-
};
65-
66-
// An allocator using IResearchMemoryManagerAccessor
67-
// so that we can track the allocations/deallocations
68-
// during the test.
69-
template<typename T>
70-
struct ManagedTypedAllocatorTest
71-
: ManagedAllocator<std::allocator<T>, IResearchMemoryManagerAccessor> {
72-
using Base = ManagedAllocator<std::allocator<T>, IResearchMemoryManagerAccessor>;
73-
explicit ManagedTypedAllocatorTest()
74-
: Base(
75-
*IResearchMemoryManagerAccessor::GetInstance()
76-
) {
77-
}
78-
using Base::Base;
79-
};
80-
81-
TEST(IResearch_memory_limit_test, managed_allocator_smoke_test) {
82-
83-
IResearchMemoryManagerAccessor::setMemoryLimit(3);
84-
auto memoryMgr = IResearchMemoryManagerAccessor::GetInstance();
34+
auto memoryMgr = IResearchMemoryManager::GetInstance();
35+
memoryMgr->SetMemoryLimit(3);
8536

8637
using type = char;
87-
std::vector<type, ManagedTypedAllocatorTest<type>> arr(*memoryMgr.get());
38+
std::vector<type, ManagedTypedAllocator<type>> arr(*memoryMgr);
8839

8940
arr.push_back('a');
9041
arr.push_back('b');
9142
ASSERT_THROW(arr.push_back('c'), std::bad_alloc);
9243
}
9344

94-
TEST(IResearch_memory_limit_test, memory_manager_smoke_test) {
45+
TEST(IResearchMemoryLimitTest, memory_manager_smoke_test) {
9546

9647
// set limit
97-
IResearchMemoryManagerAccessor::setMemoryLimit(47);
48+
auto memoryMgr = IResearchMemoryManager::GetInstance();
49+
memoryMgr->SetMemoryLimit(47);
9850

9951
// allocate vector
10052
ManagedVector<uint64_t> vec;
@@ -104,7 +56,7 @@ TEST(IResearch_memory_limit_test, memory_manager_smoke_test) {
10456
ASSERT_THROW(vec.push_back(12), std::bad_alloc); // Allocate 32 while holding previous 16, total 48 (bad_alloc)
10557

10658
// Increase memory limit to accommodate the 3rd element.
107-
IResearchMemoryManagerAccessor::setMemoryLimit(48);
59+
memoryMgr->SetMemoryLimit(48);
10860

10961
ASSERT_NO_THROW(vec.push_back(12));
11062
}

0 commit comments

Comments
 (0)