Added static template ::construct(args...) on both ReferenceCounter<> classes as a more convenient way to construct references.

This commit is contained in:
Steve Atherton 2022-01-06 02:41:13 -08:00
parent 1ec8dd38b7
commit d4bb27c05a
3 changed files with 18 additions and 10 deletions

View File

@ -145,11 +145,6 @@ public:
}
};
// Convenient constructor that returns a reference
static Reference<ArenaPage> create(int logicalSize, int bufferSize) {
return Reference<ArenaPage>(new ArenaPage(logicalSize, bufferSize));
}
~ArenaPage() {
if (userData != nullptr && userDataDestructor != nullptr) {
userDataDestructor(userData);

View File

@ -2557,7 +2557,7 @@ public:
}
Reference<ArenaPage> newPageBuffer(size_t blocks = 1) override {
return ArenaPage::create(logicalPageSize * blocks, physicalPageSize * blocks);
return ArenaPage::construct(logicalPageSize * blocks, physicalPageSize * blocks);
}
int getPhysicalPageSize() const override { return physicalPageSize; }
@ -2943,7 +2943,7 @@ public:
ASSERT(!self->memoryOnly);
state Reference<ArenaPage> page =
header ? ArenaPage::create(smallestPhysicalBlock, smallestPhysicalBlock) : self->newPageBuffer();
header ? ArenaPage::construct(smallestPhysicalBlock, smallestPhysicalBlock) : self->newPageBuffer();
debug_printf("DWALPager(%s) op=readPhysicalStart %s ptr=%p header=%d\n",
self->filename.c_str(),
toString(pageID).c_str(),
@ -3235,7 +3235,7 @@ public:
readSize = self->physicalExtentSize;
}
state Reference<ArenaPage> extent = ArenaPage::create(readSize, readSize);
state Reference<ArenaPage> extent = ArenaPage::construct(readSize, readSize);
// physicalReadSize is the size of disk read we intend to issue
auto physicalReadSize = SERVER_KNOBS->REDWOOD_DEFAULT_EXTENT_READ_SIZE;
@ -9334,12 +9334,12 @@ TEST_CASE(":/redwood/performance/mutationBuffer") {
TEST_CASE(":/redwood/pager/ArenaPage") {
Arena x;
printf("Making p\n");
Reference<ArenaPage> p = ArenaPage::create(4096, 4096);
Reference<ArenaPage> p = ArenaPage::construct(4096, 4096);
printf("Made p=%p\n", p->data());
printf("Clearing p\n");
p.clear();
printf("Making p\n");
p = ArenaPage::create(4096, 4096);
p = ArenaPage::construct(4096, 4096);
printf("Made p=%p\n", p->data());
printf("Making x depend on p\n");
x.dependsOn(p->getArena());

View File

@ -25,6 +25,9 @@
#include <atomic>
#include <cstdint>
template <class P>
class Reference;
// The thread safety this class provides is that it's safe to call addref and
// delref on the same object concurrently in different threads. Subclass does
// not get deleted until after all calls to delref complete.
@ -52,6 +55,11 @@ public:
void setrefCountUnsafe(int32_t count) const { referenceCount.store(count); }
int32_t debugGetReferenceCount() const { return referenceCount.load(); }
template <class... Us>
static Reference<Subclass> construct(Us&&... args) {
return Reference<Subclass>(new Subclass(std::forward<Us>(args)...));
}
private:
ThreadSafeReferenceCounted(const ThreadSafeReferenceCounted&) /* = delete*/;
void operator=(const ThreadSafeReferenceCounted&) /* = delete*/;
@ -72,6 +80,11 @@ public:
int32_t debugGetReferenceCount() const { return referenceCount; } // Never use in production code, only for tracing
bool isSoleOwner() const { return referenceCount == 1; }
template <class... Us>
static Reference<Subclass> construct(Us&&... args) {
return Reference<Subclass>(new Subclass(std::forward<Us>(args)...));
}
private:
ThreadUnsafeReferenceCounted(const ThreadUnsafeReferenceCounted&) /* = delete*/;
void operator=(const ThreadUnsafeReferenceCounted&) /* = delete*/;