From 9559ecfb2e1d6022c54f616f7e5b56a3b599c941 Mon Sep 17 00:00:00 2001 From: Akshay Venkatesh Kaushik Date: Tue, 20 Oct 2026 15:44:51 -0700 Subject: [PATCH] Add unit test that Subspace::range() owns its key memory Resolves the FIXME in Subspace::range(): verify the returned KeyRange remains valid after the Subspace that produced it is destroyed. --- fdbclient/Subspace.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/fdbclient/Subspace.cpp b/fdbclient/Subspace.cpp index d106bf7464d..2aec245e432 100644 --- a/fdbclient/Subspace.cpp +++ b/fdbclient/Subspace.cpp @@ -19,6 +19,7 @@ */ #include "fdbclient/Subspace.h" +#include "flow/UnitTest.h" Subspace::Subspace(Tuple const& tuple, StringRef const& rawPrefix) { Standalone packed = tuple.pack(); @@ -71,7 +72,6 @@ KeyRange Subspace::range(Tuple const& tuple) const { end.append(keyRange.arena(), tuple.pack().begin(), tuple.pack().size()); end.push_back(keyRange.arena(), uint8_t('\xff')); - // FIXME: test that this uses the keyRange arena and doesn't create another one keyRange.KeyRangeRef::operator=( KeyRangeRef(StringRef(begin.begin(), begin.size()), StringRef(end.begin(), end.size()))); return keyRange; @@ -88,3 +88,23 @@ Subspace Subspace::subspace(Tuple const& tuple) const { Subspace Subspace::get(Tuple const& tuple) const { return subspace(tuple); } + +TEST_CASE("/fdbclient/Subspace/rangeOwnsMemory") { + Tuple t; + t.append("child"_sr); + + KeyRange range; + { + Subspace parent("prefix"_sr); + range = parent.range(t); + } + + // The returned range must be backed by its own arena, so it stays valid after the Subspace is gone. + Standalone packed = t.pack(); + Key expectedBegin = Key("prefix"_sr).withSuffix(packed).withSuffix("\x00"_sr); + Key expectedEnd = Key("prefix"_sr).withSuffix(packed).withSuffix("\xff"_sr); + ASSERT(range.begin == expectedBegin); + ASSERT(range.end == expectedEnd); + ASSERT(range.arena().getSize() >= range.begin.size() + range.end.size()); + return Void(); +}