Add FastInaccurateEstimate boolean parameter for Arena::getSize

This commit is contained in:
sfc-gh-tclinkenbeard 2022-03-16 16:54:27 -07:00
parent 14c5c78f8f
commit 0ae9ba5fd0
3 changed files with 19 additions and 13 deletions

View File

@ -1130,7 +1130,8 @@ public:
DecodedNode& get(int index) { return decodedNodes[index]; }
void updateUsedMemory() {
int usedNow = sizeof(DeltaTree2) + arena.getSize(true) + (decodedNodes.capacity() * sizeof(DecodedNode));
int usedNow = sizeof(DeltaTree2) + arena.getSize(FastInaccurateEstimate::True) +
(decodedNodes.capacity() * sizeof(DecodedNode));
if (pMemoryTracker != nullptr) {
*pMemoryTracker += (usedNow - lastKnownUsedMemory);
}

View File

@ -106,7 +106,9 @@ void* Arena::allocate4kAlignedBuffer(uint32_t size) {
return ArenaBlock::dependOn4kAlignedBuffer(impl, size);
}
size_t Arena::getSize(bool fastInaccurateEstimate) const {
FDB_DEFINE_BOOLEAN_PARAM(FastInaccurateEstimate);
size_t Arena::getSize(FastInaccurateEstimate fastInaccurateEstimate) const {
if (impl) {
allowAccess(impl.getPtr());
size_t result;
@ -683,10 +685,10 @@ TEST_CASE("/flow/Arena/Size") {
// Note that the ASSERT argument order matters, the estimate must be calculated first as
// the full accurate calculation will update the estimate
makeString(40, a);
ASSERT_EQ(a.getSize(true), a.getSize());
ASSERT_EQ(a.getSize(FastInaccurateEstimate::True), a.getSize());
makeString(700, a);
ASSERT_EQ(a.getSize(true), a.getSize());
ASSERT_EQ(a.getSize(FastInaccurateEstimate::True), a.getSize());
// Copy a at a point where it points to a large block with room for block references
Arena b = a;
@ -697,35 +699,35 @@ TEST_CASE("/flow/Arena/Size") {
makeString(1000, a);
makeString(1000, a);
ASSERT_EQ(a.getSize(true), a.getSize());
ASSERT_EQ(a.getSize(FastInaccurateEstimate::True), a.getSize());
Standalone<StringRef> s = makeString(500);
a.dependsOn(s.arena());
ASSERT_EQ(a.getSize(true), a.getSize());
ASSERT_EQ(a.getSize(FastInaccurateEstimate::True), a.getSize());
Standalone<StringRef> s2 = makeString(500);
a.dependsOn(s2.arena());
ASSERT_EQ(a.getSize(true), a.getSize());
ASSERT_EQ(a.getSize(FastInaccurateEstimate::True), a.getSize());
// Add a dependency to b, which will fit in b's root and update b's size estimate
Standalone<StringRef> s3 = makeString(100);
b.dependsOn(s3.arena());
ASSERT_EQ(b.getSize(true), b.getSize());
ASSERT_EQ(b.getSize(FastInaccurateEstimate::True), b.getSize());
// But now a's size estimate is out of date because the new reference in b's root is still
// in a's tree
ASSERT_LT(a.getSize(true), a.getSize());
ASSERT_LT(a.getSize(FastInaccurateEstimate::True), a.getSize());
// Now that a full size calc has been done on a, the estimate is up to date.
ASSERT_EQ(a.getSize(true), a.getSize());
ASSERT_EQ(a.getSize(FastInaccurateEstimate::True), a.getSize());
// Add a dependency to c, which will NOT fit in c's root, so it will be added to a new
// root for c and that root will not be in a's tree so a's size and estimate remain
// unchanged and the same. The size and estimate of c will also match.
Standalone<StringRef> s4 = makeString(100);
c.dependsOn(s4.arena());
ASSERT_EQ(c.getSize(true), c.getSize());
ASSERT_EQ(a.getSize(true), a.getSize());
ASSERT_EQ(c.getSize(FastInaccurateEstimate::True), c.getSize());
ASSERT_EQ(a.getSize(FastInaccurateEstimate::True), a.getSize());
return Void();
}

View File

@ -24,6 +24,7 @@
#include <iterator>
#pragma once
#include "flow/BooleanParam.h"
#include "flow/FastAlloc.h"
#include "flow/FastRef.h"
#include "flow/Error.h"
@ -88,6 +89,8 @@ protected:
NonCopyable& operator=(const NonCopyable&) = delete;
};
FDB_DECLARE_BOOLEAN_PARAM(FastInaccurateEstimate);
// An Arena is a custom allocator that consists of a set of ArenaBlocks. Allocation is performed by bumping a pointer
// on the most recent ArenaBlock until the block is unable to service the next allocation request. When the current
// ArenaBlock is full, a new (larger) one is added to the Arena. Deallocation is not directly supported. Instead,
@ -110,7 +113,7 @@ public:
// non-root nodes in this Arena's block tree.
// When fastInaccurateEstimate is false, all estimates in the block tree will be updated to
// be accurate.
size_t getSize(bool fastInaccurateEstimate = false) const;
size_t getSize(FastInaccurateEstimate = FastInaccurateEstimate::False) const;
bool hasFree(size_t size, const void* address);