fresh-borzoni commented on code in PR #606:
URL: https://github.com/apache/fluss-rust/pull/606#discussion_r3369113682
##########
bindings/cpp/src/table.cpp:
##########
@@ -1405,6 +1561,65 @@ Result Lookuper::Lookup(const GenericRow& pk_row,
LookupResult& out) {
return utils::make_ok();
}
+// ============================================================================
+// PrefixLookuper
+// ============================================================================
+
+PrefixLookuper::PrefixLookuper() noexcept = default;
+
+PrefixLookuper::PrefixLookuper(ffi::PrefixLookuper* lookuper) noexcept :
lookuper_(lookuper) {}
+
+PrefixLookuper::~PrefixLookuper() noexcept { Destroy(); }
+
+void PrefixLookuper::Destroy() noexcept {
+ if (lookuper_) {
+ ffi::delete_prefix_lookuper(lookuper_);
+ lookuper_ = nullptr;
+ }
+}
+
+PrefixLookuper::PrefixLookuper(PrefixLookuper&& other) noexcept :
lookuper_(other.lookuper_) {
+ other.lookuper_ = nullptr;
+}
+
+PrefixLookuper& PrefixLookuper::operator=(PrefixLookuper&& other) noexcept {
+ if (this != &other) {
+ Destroy();
+ lookuper_ = other.lookuper_;
+ other.lookuper_ = nullptr;
+ }
+ return *this;
+}
+
+bool PrefixLookuper::Available() const { return lookuper_ != nullptr; }
+
+Result PrefixLookuper::PrefixLookup(const GenericRow& prefix_row,
PrefixLookupResult& out) {
+ if (!Available()) {
+ return utils::make_client_error("PrefixLookuper not available");
+ }
+ if (!prefix_row.Available()) {
+ return utils::make_client_error("GenericRow not available");
+ }
+
+ auto result_box = lookuper_->prefix_lookup(*prefix_row.inner_);
+ if (result_box->plv_has_error()) {
+ return utils::make_error(result_box->plv_error_code(),
+ std::string(result_box->plv_error_message()));
+ }
+
+ // Wrap the raw pointer immediately so it's never leaked on exception, then
+ // build the column map eagerly — shared by all PrefixRowViews.
Review Comment:
Good question 👍 . Think of it as a hand-off: the Rust Box owns the memory
and frees it for you automatically. into_raw() gives that up and hands back a
plain pointer and now nothing frees it unless we arrange it. So on the same
step we hand it to PrefixData, whose destructor calls from_raw. That's why the
"never leaked" is really about the loop after it: once PrefixData owns the
pointer, if the map-building throws, it still gets cleaned up on the way out.
Honestly though, the bigger reason for the into_raw/from_raw is just to
keep the cxx Box type out of the public header and the exception-safety bit is
more of a nice by-product, and a pretty standard "wrap it immediately" pattern.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]