westonpace commented on code in PR #13252:
URL: https://github.com/apache/arrow/pull/13252#discussion_r891490267
##########
cpp/src/arrow/compute/registry.h:
##########
@@ -45,20 +45,42 @@ class FunctionOptionsType;
/// lower-level function execution.
class ARROW_EXPORT FunctionRegistry {
public:
- ~FunctionRegistry();
+ virtual ~FunctionRegistry();
Review Comment:
A destructor should not be the only virtual method. If no methods are
virtual then the destructor does not need to be virtual.
##########
cpp/src/arrow/compute/registry.h:
##########
@@ -45,20 +45,42 @@ class FunctionOptionsType;
/// lower-level function execution.
class ARROW_EXPORT FunctionRegistry {
public:
- ~FunctionRegistry();
+ virtual ~FunctionRegistry();
/// \brief Construct a new registry. Most users only need to use the global
/// registry
static std::unique_ptr<FunctionRegistry> Make();
+ /// \brief Construct a new nested registry with the given parent. Most users
only need
+ /// to use the global registry
+ static std::unique_ptr<FunctionRegistry> Make(FunctionRegistry* parent);
+
+ /// \brief Construct a new nested registry with the given parent. Most users
only need
+ /// to use the global registry
+ static std::unique_ptr<FunctionRegistry>
Make(std::unique_ptr<FunctionRegistry> parent);
Review Comment:
A function that accepts a unique_ptr should take ownership of that unique
pointer. That does not seem to be what we are doing here. In this case I
think we should probably get rid of this overload.
There is a "maybe owned" pattern we use in a few places where we have a
constructor that takes a raw pointer and one that takes a shared_ptr but in
that case we have two member variables (e.g.
https://github.com/apache/arrow/blob/master/cpp/src/arrow/io/caching.cc#L147)
##########
cpp/src/arrow/compute/registry.cc:
##########
@@ -34,78 +34,144 @@ namespace compute {
class FunctionRegistry::FunctionRegistryImpl {
public:
- Status AddFunction(std::shared_ptr<Function> function, bool allow_overwrite)
{
-#ifndef NDEBUG
- // This validates docstrings extensively, so don't waste time on it
- // in release builds.
- RETURN_NOT_OK(function->Validate());
-#endif
-
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ explicit FunctionRegistryImpl(FunctionRegistryImpl* parent = NULLPTR)
+ : parent_(parent) {}
+ virtual ~FunctionRegistryImpl() {}
+
+ virtual Status CanAddFunction(std::shared_ptr<Function> function,
+ bool allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/false);
Review Comment:
```suggestion
if (parent_ != nullptr) {
RETURN_NOT_OK(parent_->CanAddFunction(function, allow_overwrite)));
}
return DoAddFunction(function, allow_overwrite, /*add=*/false);
```
Now that it seems we won't be able to use `&&` we should probably move away
from this more compact pattern and more explicitly short-circuit.
##########
cpp/src/arrow/compute/registry.h:
##########
@@ -45,20 +45,42 @@ class FunctionOptionsType;
/// lower-level function execution.
class ARROW_EXPORT FunctionRegistry {
public:
- ~FunctionRegistry();
+ virtual ~FunctionRegistry();
/// \brief Construct a new registry. Most users only need to use the global
/// registry
static std::unique_ptr<FunctionRegistry> Make();
+ /// \brief Construct a new nested registry with the given parent. Most users
only need
+ /// to use the global registry
+ static std::unique_ptr<FunctionRegistry> Make(FunctionRegistry* parent);
+
+ /// \brief Construct a new nested registry with the given parent. Most users
only need
+ /// to use the global registry
+ static std::unique_ptr<FunctionRegistry>
Make(std::unique_ptr<FunctionRegistry> parent);
+
+ /// \brief Checks whether a new function can be added to the registry.
Returns
+ /// Status::KeyError if a function with the same name is already registered
+ Status CanAddFunction(std::shared_ptr<Function> function, bool
allow_overwrite = false);
+
/// \brief Add a new function to the registry. Returns Status::KeyError if a
/// function with the same name is already registered
Status AddFunction(std::shared_ptr<Function> function, bool allow_overwrite
= false);
- /// \brief Add aliases for the given function name. Returns Status::KeyError
if the
+ /// \brief Checks whether an alias can be added for the given function name.
Returns
+ /// Status::KeyError if the function with the given name is not registered
+ Status CanAddAlias(const std::string& target_name, const std::string&
source_name);
+
+ /// \brief Add alias for the given function name. Returns Status::KeyError
if the
/// function with the given name is not registered
Status AddAlias(const std::string& target_name, const std::string&
source_name);
+ /// \brief Checks whether a new function options type can be added to the
registry.
+ /// Returns Status::KeyError if a function options type with the same name
is already
+ /// registered
Review Comment:
```suggestion
/// \brief Check whether a new function options type can be added to the
registry.
/// \return Status::KeyError if a function options type with the same name
is already
/// registered
```
##########
cpp/src/arrow/compute/registry.cc:
##########
@@ -34,78 +34,144 @@ namespace compute {
class FunctionRegistry::FunctionRegistryImpl {
public:
- Status AddFunction(std::shared_ptr<Function> function, bool allow_overwrite)
{
-#ifndef NDEBUG
- // This validates docstrings extensively, so don't waste time on it
- // in release builds.
- RETURN_NOT_OK(function->Validate());
-#endif
-
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ explicit FunctionRegistryImpl(FunctionRegistryImpl* parent = NULLPTR)
+ : parent_(parent) {}
+ virtual ~FunctionRegistryImpl() {}
+
+ virtual Status CanAddFunction(std::shared_ptr<Function> function,
+ bool allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/false);
+ }
- const std::string& name = function->name();
- auto it = name_to_function_.find(name);
- if (it != name_to_function_.end() && !allow_overwrite) {
- return Status::KeyError("Already have a function registered with name:
", name);
- }
- name_to_function_[name] = std::move(function);
- return Status::OK();
+ virtual Status AddFunction(std::shared_ptr<Function> function, bool
allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/true);
}
- Status AddAlias(const std::string& target_name, const std::string&
source_name) {
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ virtual Status CanAddAlias(const std::string& target_name,
+ const std::string& source_name) {
+ Status st = DoAddAlias(target_name, source_name, /*add=*/false);
+ return st.ok() || parent_ == nullptr ? st
+ : parent_->CanAddAlias(target_name,
source_name);
+ }
- auto it = name_to_function_.find(source_name);
- if (it == name_to_function_.end()) {
- return Status::KeyError("No function registered with name: ",
source_name);
- }
- name_to_function_[target_name] = it->second;
- return Status::OK();
+ virtual Status AddAlias(const std::string& target_name,
Review Comment:
```suggestion
Status AddAlias(const std::string& target_name,
```
##########
cpp/src/arrow/compute/registry.cc:
##########
@@ -34,78 +34,144 @@ namespace compute {
class FunctionRegistry::FunctionRegistryImpl {
public:
- Status AddFunction(std::shared_ptr<Function> function, bool allow_overwrite)
{
-#ifndef NDEBUG
- // This validates docstrings extensively, so don't waste time on it
- // in release builds.
- RETURN_NOT_OK(function->Validate());
-#endif
-
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ explicit FunctionRegistryImpl(FunctionRegistryImpl* parent = NULLPTR)
+ : parent_(parent) {}
+ virtual ~FunctionRegistryImpl() {}
+
+ virtual Status CanAddFunction(std::shared_ptr<Function> function,
+ bool allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/false);
+ }
- const std::string& name = function->name();
- auto it = name_to_function_.find(name);
- if (it != name_to_function_.end() && !allow_overwrite) {
- return Status::KeyError("Already have a function registered with name:
", name);
- }
- name_to_function_[name] = std::move(function);
- return Status::OK();
+ virtual Status AddFunction(std::shared_ptr<Function> function, bool
allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/true);
}
- Status AddAlias(const std::string& target_name, const std::string&
source_name) {
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ virtual Status CanAddAlias(const std::string& target_name,
+ const std::string& source_name) {
+ Status st = DoAddAlias(target_name, source_name, /*add=*/false);
+ return st.ok() || parent_ == nullptr ? st
+ : parent_->CanAddAlias(target_name,
source_name);
+ }
- auto it = name_to_function_.find(source_name);
- if (it == name_to_function_.end()) {
- return Status::KeyError("No function registered with name: ",
source_name);
- }
- name_to_function_[target_name] = it->second;
- return Status::OK();
+ virtual Status AddAlias(const std::string& target_name,
+ const std::string& source_name) {
+ Status st = DoAddAlias(target_name, source_name, /*add=*/true);
+ return st.ok() || parent_ == nullptr ? st
+ : parent_->AddAlias(target_name,
source_name);
}
- Status AddFunctionOptionsType(const FunctionOptionsType* options_type,
- bool allow_overwrite = false) {
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ virtual Status CanAddFunctionOptionsType(const FunctionOptionsType*
options_type,
Review Comment:
```suggestion
Status CanAddFunctionOptionsType(const FunctionOptionsType* options_type,
```
##########
cpp/src/arrow/compute/registry.cc:
##########
@@ -34,78 +34,144 @@ namespace compute {
class FunctionRegistry::FunctionRegistryImpl {
public:
- Status AddFunction(std::shared_ptr<Function> function, bool allow_overwrite)
{
-#ifndef NDEBUG
- // This validates docstrings extensively, so don't waste time on it
- // in release builds.
- RETURN_NOT_OK(function->Validate());
-#endif
-
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ explicit FunctionRegistryImpl(FunctionRegistryImpl* parent = NULLPTR)
+ : parent_(parent) {}
+ virtual ~FunctionRegistryImpl() {}
+
+ virtual Status CanAddFunction(std::shared_ptr<Function> function,
+ bool allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/false);
+ }
- const std::string& name = function->name();
- auto it = name_to_function_.find(name);
- if (it != name_to_function_.end() && !allow_overwrite) {
- return Status::KeyError("Already have a function registered with name:
", name);
- }
- name_to_function_[name] = std::move(function);
- return Status::OK();
+ virtual Status AddFunction(std::shared_ptr<Function> function, bool
allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/true);
}
- Status AddAlias(const std::string& target_name, const std::string&
source_name) {
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ virtual Status CanAddAlias(const std::string& target_name,
+ const std::string& source_name) {
+ Status st = DoAddAlias(target_name, source_name, /*add=*/false);
+ return st.ok() || parent_ == nullptr ? st
+ : parent_->CanAddAlias(target_name,
source_name);
+ }
- auto it = name_to_function_.find(source_name);
- if (it == name_to_function_.end()) {
- return Status::KeyError("No function registered with name: ",
source_name);
- }
- name_to_function_[target_name] = it->second;
- return Status::OK();
+ virtual Status AddAlias(const std::string& target_name,
+ const std::string& source_name) {
+ Status st = DoAddAlias(target_name, source_name, /*add=*/true);
+ return st.ok() || parent_ == nullptr ? st
+ : parent_->AddAlias(target_name,
source_name);
}
- Status AddFunctionOptionsType(const FunctionOptionsType* options_type,
- bool allow_overwrite = false) {
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ virtual Status CanAddFunctionOptionsType(const FunctionOptionsType*
options_type,
+ bool allow_overwrite = false) {
+ return (parent_ == nullptr
+ ? Status::OK()
+ : parent_->CanAddFunctionOptionsType(options_type,
allow_overwrite)) &
+ DoAddFunctionOptionsType(options_type, allow_overwrite,
/*add=*/false);
+ }
- const std::string name = options_type->type_name();
- auto it = name_to_options_type_.find(name);
- if (it != name_to_options_type_.end() && !allow_overwrite) {
- return Status::KeyError(
- "Already have a function options type registered with name: ", name);
- }
- name_to_options_type_[name] = options_type;
- return Status::OK();
+ virtual Status AddFunctionOptionsType(const FunctionOptionsType*
options_type,
+ bool allow_overwrite = false) {
+ return (parent_ == nullptr
+ ? Status::OK()
+ : parent_->CanAddFunctionOptionsType(options_type,
allow_overwrite)) &
+ DoAddFunctionOptionsType(options_type, allow_overwrite,
/*add=*/true);
Review Comment:
```suggestion
if (parent_ != nullptr) {
RETURN_NOT_OK(parent_->CanAddFunctionOptionsType(options_type,
allow_overwrite));
}
return DoAddFunctionOptionsType(options_type, allow_overwrite,
/*add=*/true);
```
##########
cpp/src/arrow/compute/registry.cc:
##########
@@ -115,20 +181,47 @@ std::unique_ptr<FunctionRegistry>
FunctionRegistry::Make() {
return std::unique_ptr<FunctionRegistry>(new FunctionRegistry());
}
-FunctionRegistry::FunctionRegistry() { impl_.reset(new
FunctionRegistryImpl()); }
+std::unique_ptr<FunctionRegistry> FunctionRegistry::Make(FunctionRegistry*
parent) {
+ return std::unique_ptr<FunctionRegistry>(
+ new FunctionRegistry(new
FunctionRegistry::FunctionRegistryImpl(&*parent->impl_)));
Review Comment:
```suggestion
new FunctionRegistry(parent->impl_.get());
```
The way it is currently will create a copy of the parent. This pointer
leaks but, more importantly, if you did something like...
```
auto parent = GetFunctionRegistry();
auto nested = FunctionRegistry::Make(parent);
// The function added here (using parent) will not be visible by nested
// and, if I'm understanding the purpose correctly, we would want that
parent->AddFunction(...);
```
Instead we should just take a non-owning "view" pointer to the parent. If
the parent is deleted before the nested registry is deleted then bad things
will happen but that is to be expected.
##########
cpp/src/arrow/compute/registry.h:
##########
@@ -45,20 +45,42 @@ class FunctionOptionsType;
/// lower-level function execution.
class ARROW_EXPORT FunctionRegistry {
public:
- ~FunctionRegistry();
+ virtual ~FunctionRegistry();
/// \brief Construct a new registry. Most users only need to use the global
/// registry
static std::unique_ptr<FunctionRegistry> Make();
+ /// \brief Construct a new nested registry with the given parent. Most users
only need
+ /// to use the global registry
Review Comment:
```suggestion
/// \brief Construct a new nested registry with the given parent.
///
/// Most users only need to use the global registry
```
##########
cpp/src/arrow/compute/registry.h:
##########
@@ -45,20 +45,42 @@ class FunctionOptionsType;
/// lower-level function execution.
class ARROW_EXPORT FunctionRegistry {
public:
- ~FunctionRegistry();
+ virtual ~FunctionRegistry();
/// \brief Construct a new registry. Most users only need to use the global
/// registry
static std::unique_ptr<FunctionRegistry> Make();
+ /// \brief Construct a new nested registry with the given parent. Most users
only need
+ /// to use the global registry
+ static std::unique_ptr<FunctionRegistry> Make(FunctionRegistry* parent);
+
+ /// \brief Construct a new nested registry with the given parent. Most users
only need
+ /// to use the global registry
+ static std::unique_ptr<FunctionRegistry>
Make(std::unique_ptr<FunctionRegistry> parent);
+
+ /// \brief Checks whether a new function can be added to the registry.
Returns
+ /// Status::KeyError if a function with the same name is already registered
+ Status CanAddFunction(std::shared_ptr<Function> function, bool
allow_overwrite = false);
+
/// \brief Add a new function to the registry. Returns Status::KeyError if a
/// function with the same name is already registered
Status AddFunction(std::shared_ptr<Function> function, bool allow_overwrite
= false);
- /// \brief Add aliases for the given function name. Returns Status::KeyError
if the
+ /// \brief Checks whether an alias can be added for the given function name.
Returns
+ /// Status::KeyError if the function with the given name is not registered
Review Comment:
```suggestion
/// \brief Check whether an alias can be added for the given function name.
/// \return Status::KeyError if a function with the
/// given source_name is not registered
```
##########
cpp/src/arrow/compute/registry.cc:
##########
@@ -34,78 +34,144 @@ namespace compute {
class FunctionRegistry::FunctionRegistryImpl {
public:
- Status AddFunction(std::shared_ptr<Function> function, bool allow_overwrite)
{
-#ifndef NDEBUG
- // This validates docstrings extensively, so don't waste time on it
- // in release builds.
- RETURN_NOT_OK(function->Validate());
-#endif
-
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ explicit FunctionRegistryImpl(FunctionRegistryImpl* parent = NULLPTR)
+ : parent_(parent) {}
+ virtual ~FunctionRegistryImpl() {}
+
+ virtual Status CanAddFunction(std::shared_ptr<Function> function,
+ bool allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/false);
+ }
- const std::string& name = function->name();
- auto it = name_to_function_.find(name);
- if (it != name_to_function_.end() && !allow_overwrite) {
- return Status::KeyError("Already have a function registered with name:
", name);
- }
- name_to_function_[name] = std::move(function);
- return Status::OK();
+ virtual Status AddFunction(std::shared_ptr<Function> function, bool
allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/true);
}
- Status AddAlias(const std::string& target_name, const std::string&
source_name) {
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ virtual Status CanAddAlias(const std::string& target_name,
+ const std::string& source_name) {
+ Status st = DoAddAlias(target_name, source_name, /*add=*/false);
+ return st.ok() || parent_ == nullptr ? st
+ : parent_->CanAddAlias(target_name,
source_name);
+ }
- auto it = name_to_function_.find(source_name);
- if (it == name_to_function_.end()) {
- return Status::KeyError("No function registered with name: ",
source_name);
- }
- name_to_function_[target_name] = it->second;
- return Status::OK();
+ virtual Status AddAlias(const std::string& target_name,
+ const std::string& source_name) {
+ Status st = DoAddAlias(target_name, source_name, /*add=*/true);
+ return st.ok() || parent_ == nullptr ? st
+ : parent_->AddAlias(target_name,
source_name);
}
- Status AddFunctionOptionsType(const FunctionOptionsType* options_type,
- bool allow_overwrite = false) {
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ virtual Status CanAddFunctionOptionsType(const FunctionOptionsType*
options_type,
+ bool allow_overwrite = false) {
+ return (parent_ == nullptr
+ ? Status::OK()
+ : parent_->CanAddFunctionOptionsType(options_type,
allow_overwrite)) &
+ DoAddFunctionOptionsType(options_type, allow_overwrite,
/*add=*/false);
+ }
- const std::string name = options_type->type_name();
- auto it = name_to_options_type_.find(name);
- if (it != name_to_options_type_.end() && !allow_overwrite) {
- return Status::KeyError(
- "Already have a function options type registered with name: ", name);
- }
- name_to_options_type_[name] = options_type;
- return Status::OK();
+ virtual Status AddFunctionOptionsType(const FunctionOptionsType*
options_type,
+ bool allow_overwrite = false) {
+ return (parent_ == nullptr
+ ? Status::OK()
+ : parent_->CanAddFunctionOptionsType(options_type,
allow_overwrite)) &
+ DoAddFunctionOptionsType(options_type, allow_overwrite,
/*add=*/true);
}
- Result<std::shared_ptr<Function>> GetFunction(const std::string& name) const
{
+ virtual Result<std::shared_ptr<Function>> GetFunction(const std::string&
name) const {
auto it = name_to_function_.find(name);
if (it == name_to_function_.end()) {
+ if (parent_ != nullptr) {
+ return parent_->GetFunction(name);
+ }
return Status::KeyError("No function registered with name: ", name);
}
return it->second;
}
- std::vector<std::string> GetFunctionNames() const {
+ virtual std::vector<std::string> GetFunctionNames() const {
std::vector<std::string> results;
+ if (parent_ != nullptr) {
+ results = parent_->GetFunctionNames();
+ }
for (auto it : name_to_function_) {
results.push_back(it.first);
}
std::sort(results.begin(), results.end());
return results;
}
- Result<const FunctionOptionsType*> GetFunctionOptionsType(
+ virtual Result<const FunctionOptionsType*> GetFunctionOptionsType(
const std::string& name) const {
auto it = name_to_options_type_.find(name);
if (it == name_to_options_type_.end()) {
+ if (parent_ != nullptr) {
+ return parent_->GetFunctionOptionsType(name);
+ }
return Status::KeyError("No function options type registered with name:
", name);
}
return it->second;
}
- int num_functions() const { return
static_cast<int>(name_to_function_.size()); }
+ virtual int num_functions() const {
+ return (parent_ == nullptr ? 0 : parent_->num_functions()) +
+ static_cast<int>(name_to_function_.size());
+ }
private:
+ Status DoAddFunction(std::shared_ptr<Function> function, bool
allow_overwrite,
+ bool add) {
+#ifndef NDEBUG
+ // This validates docstrings extensively, so don't waste time on it
+ // in release builds.
+ RETURN_NOT_OK(function->Validate());
+#endif
+
+ std::lock_guard<std::mutex> mutation_guard(lock_);
+
+ const std::string& name = function->name();
+ auto it = name_to_function_.find(name);
+ if (it != name_to_function_.end() && !allow_overwrite) {
+ return Status::KeyError("Already have a function registered with name:
", name);
+ }
+ if (add) {
+ name_to_function_[name] = std::move(function);
+ }
+ return Status::OK();
+ }
+
+ Status DoAddAlias(const std::string& target_name, const std::string&
source_name,
+ bool add) {
+ std::lock_guard<std::mutex> mutation_guard(lock_);
+
+ // following invocation must not acquire the mutex
+ ARROW_ASSIGN_OR_RAISE(auto func, GetFunction(source_name));
+ if (add) {
Review Comment:
Should we be doing a check here to see if a function with `target_name` is
already registered (would probably also necessitate `allow_overwrite`)?
##########
cpp/src/arrow/compute/registry.h:
##########
@@ -45,20 +45,42 @@ class FunctionOptionsType;
/// lower-level function execution.
class ARROW_EXPORT FunctionRegistry {
public:
- ~FunctionRegistry();
+ virtual ~FunctionRegistry();
/// \brief Construct a new registry. Most users only need to use the global
/// registry
static std::unique_ptr<FunctionRegistry> Make();
+ /// \brief Construct a new nested registry with the given parent. Most users
only need
+ /// to use the global registry
+ static std::unique_ptr<FunctionRegistry> Make(FunctionRegistry* parent);
+
+ /// \brief Construct a new nested registry with the given parent. Most users
only need
+ /// to use the global registry
+ static std::unique_ptr<FunctionRegistry>
Make(std::unique_ptr<FunctionRegistry> parent);
+
+ /// \brief Checks whether a new function can be added to the registry.
Returns
+ /// Status::KeyError if a function with the same name is already registered
Review Comment:
```suggestion
/// \brief Check whether a new function can be added to the registry.
/// \return Status::KeyError if a function with the same name is already
registered
```
##########
cpp/src/arrow/compute/registry.h:
##########
@@ -45,20 +45,42 @@ class FunctionOptionsType;
/// lower-level function execution.
class ARROW_EXPORT FunctionRegistry {
public:
- ~FunctionRegistry();
+ virtual ~FunctionRegistry();
/// \brief Construct a new registry. Most users only need to use the global
/// registry
static std::unique_ptr<FunctionRegistry> Make();
+ /// \brief Construct a new nested registry with the given parent. Most users
only need
+ /// to use the global registry
+ static std::unique_ptr<FunctionRegistry> Make(FunctionRegistry* parent);
+
+ /// \brief Construct a new nested registry with the given parent. Most users
only need
+ /// to use the global registry
+ static std::unique_ptr<FunctionRegistry>
Make(std::unique_ptr<FunctionRegistry> parent);
+
+ /// \brief Checks whether a new function can be added to the registry.
Returns
+ /// Status::KeyError if a function with the same name is already registered
+ Status CanAddFunction(std::shared_ptr<Function> function, bool
allow_overwrite = false);
+
/// \brief Add a new function to the registry. Returns Status::KeyError if a
/// function with the same name is already registered
Status AddFunction(std::shared_ptr<Function> function, bool allow_overwrite
= false);
- /// \brief Add aliases for the given function name. Returns Status::KeyError
if the
+ /// \brief Checks whether an alias can be added for the given function name.
Returns
+ /// Status::KeyError if the function with the given name is not registered
+ Status CanAddAlias(const std::string& target_name, const std::string&
source_name);
+
+ /// \brief Add alias for the given function name. Returns Status::KeyError
if the
/// function with the given name is not registered
Review Comment:
```suggestion
/// \brief Add alias for the given function name.
/// \return Status::KeyError if the
/// function with the given source_name is not registered
```
##########
cpp/src/arrow/compute/registry.cc:
##########
@@ -34,78 +34,144 @@ namespace compute {
class FunctionRegistry::FunctionRegistryImpl {
public:
- Status AddFunction(std::shared_ptr<Function> function, bool allow_overwrite)
{
-#ifndef NDEBUG
- // This validates docstrings extensively, so don't waste time on it
- // in release builds.
- RETURN_NOT_OK(function->Validate());
-#endif
-
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ explicit FunctionRegistryImpl(FunctionRegistryImpl* parent = NULLPTR)
+ : parent_(parent) {}
+ virtual ~FunctionRegistryImpl() {}
+
+ virtual Status CanAddFunction(std::shared_ptr<Function> function,
+ bool allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/false);
+ }
- const std::string& name = function->name();
- auto it = name_to_function_.find(name);
- if (it != name_to_function_.end() && !allow_overwrite) {
- return Status::KeyError("Already have a function registered with name:
", name);
- }
- name_to_function_[name] = std::move(function);
- return Status::OK();
+ virtual Status AddFunction(std::shared_ptr<Function> function, bool
allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/true);
Review Comment:
```suggestion
if (parent_ != nullptr) {
RETURN_NOT_OK(parent_->CanAddFunction(function, allow_overwrite));
}
return DoAddFunction(function, allow_overwrite, /*add=*/true);
```
##########
cpp/src/arrow/compute/registry.cc:
##########
@@ -34,78 +34,144 @@ namespace compute {
class FunctionRegistry::FunctionRegistryImpl {
public:
- Status AddFunction(std::shared_ptr<Function> function, bool allow_overwrite)
{
-#ifndef NDEBUG
- // This validates docstrings extensively, so don't waste time on it
- // in release builds.
- RETURN_NOT_OK(function->Validate());
-#endif
-
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ explicit FunctionRegistryImpl(FunctionRegistryImpl* parent = NULLPTR)
+ : parent_(parent) {}
+ virtual ~FunctionRegistryImpl() {}
+
+ virtual Status CanAddFunction(std::shared_ptr<Function> function,
Review Comment:
```suggestion
Status CanAddFunction(std::shared_ptr<Function> function,
```
##########
cpp/src/arrow/compute/registry.cc:
##########
@@ -34,78 +34,144 @@ namespace compute {
class FunctionRegistry::FunctionRegistryImpl {
public:
- Status AddFunction(std::shared_ptr<Function> function, bool allow_overwrite)
{
-#ifndef NDEBUG
- // This validates docstrings extensively, so don't waste time on it
- // in release builds.
- RETURN_NOT_OK(function->Validate());
-#endif
-
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ explicit FunctionRegistryImpl(FunctionRegistryImpl* parent = NULLPTR)
+ : parent_(parent) {}
+ virtual ~FunctionRegistryImpl() {}
+
+ virtual Status CanAddFunction(std::shared_ptr<Function> function,
+ bool allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/false);
+ }
- const std::string& name = function->name();
- auto it = name_to_function_.find(name);
- if (it != name_to_function_.end() && !allow_overwrite) {
- return Status::KeyError("Already have a function registered with name:
", name);
- }
- name_to_function_[name] = std::move(function);
- return Status::OK();
+ virtual Status AddFunction(std::shared_ptr<Function> function, bool
allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/true);
}
- Status AddAlias(const std::string& target_name, const std::string&
source_name) {
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ virtual Status CanAddAlias(const std::string& target_name,
+ const std::string& source_name) {
+ Status st = DoAddAlias(target_name, source_name, /*add=*/false);
Review Comment:
```suggestion
RETURN_NOT_OK(DoAddAlias(target_name, source_name, /*add=*/false));
if (parent_ != nullptr) {
return parent_->CanAddAlias(target_name, source_name);
}
return Status::OK();
```
Hmm...I think we want to:
* Check if source_name exists in this and fail otherwise
* Check if target_name exists in parent_ and fail otherwise
* Actually try and add to this (may fail if target_name exists)
I might be confused though.
##########
cpp/src/arrow/compute/registry.cc:
##########
@@ -34,78 +34,144 @@ namespace compute {
class FunctionRegistry::FunctionRegistryImpl {
public:
- Status AddFunction(std::shared_ptr<Function> function, bool allow_overwrite)
{
-#ifndef NDEBUG
- // This validates docstrings extensively, so don't waste time on it
- // in release builds.
- RETURN_NOT_OK(function->Validate());
-#endif
-
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ explicit FunctionRegistryImpl(FunctionRegistryImpl* parent = NULLPTR)
+ : parent_(parent) {}
+ virtual ~FunctionRegistryImpl() {}
+
+ virtual Status CanAddFunction(std::shared_ptr<Function> function,
+ bool allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/false);
+ }
- const std::string& name = function->name();
- auto it = name_to_function_.find(name);
- if (it != name_to_function_.end() && !allow_overwrite) {
- return Status::KeyError("Already have a function registered with name:
", name);
- }
- name_to_function_[name] = std::move(function);
- return Status::OK();
+ virtual Status AddFunction(std::shared_ptr<Function> function, bool
allow_overwrite) {
Review Comment:
```suggestion
Status AddFunction(std::shared_ptr<Function> function, bool
allow_overwrite) {
```
##########
cpp/src/arrow/compute/registry.cc:
##########
@@ -34,78 +34,144 @@ namespace compute {
class FunctionRegistry::FunctionRegistryImpl {
public:
- Status AddFunction(std::shared_ptr<Function> function, bool allow_overwrite)
{
-#ifndef NDEBUG
- // This validates docstrings extensively, so don't waste time on it
- // in release builds.
- RETURN_NOT_OK(function->Validate());
-#endif
-
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ explicit FunctionRegistryImpl(FunctionRegistryImpl* parent = NULLPTR)
+ : parent_(parent) {}
+ virtual ~FunctionRegistryImpl() {}
+
+ virtual Status CanAddFunction(std::shared_ptr<Function> function,
+ bool allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/false);
+ }
- const std::string& name = function->name();
- auto it = name_to_function_.find(name);
- if (it != name_to_function_.end() && !allow_overwrite) {
- return Status::KeyError("Already have a function registered with name:
", name);
- }
- name_to_function_[name] = std::move(function);
- return Status::OK();
+ virtual Status AddFunction(std::shared_ptr<Function> function, bool
allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/true);
}
- Status AddAlias(const std::string& target_name, const std::string&
source_name) {
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ virtual Status CanAddAlias(const std::string& target_name,
Review Comment:
```suggestion
Status CanAddAlias(const std::string& target_name,
```
##########
cpp/src/arrow/compute/registry.cc:
##########
@@ -34,78 +34,144 @@ namespace compute {
class FunctionRegistry::FunctionRegistryImpl {
public:
- Status AddFunction(std::shared_ptr<Function> function, bool allow_overwrite)
{
-#ifndef NDEBUG
- // This validates docstrings extensively, so don't waste time on it
- // in release builds.
- RETURN_NOT_OK(function->Validate());
-#endif
-
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ explicit FunctionRegistryImpl(FunctionRegistryImpl* parent = NULLPTR)
+ : parent_(parent) {}
+ virtual ~FunctionRegistryImpl() {}
Review Comment:
```suggestion
~FunctionRegistryImpl() {}
```
Now that we aren't using inheritance these do not need to be virtual.
##########
cpp/src/arrow/compute/registry.cc:
##########
@@ -34,78 +34,144 @@ namespace compute {
class FunctionRegistry::FunctionRegistryImpl {
public:
- Status AddFunction(std::shared_ptr<Function> function, bool allow_overwrite)
{
-#ifndef NDEBUG
- // This validates docstrings extensively, so don't waste time on it
- // in release builds.
- RETURN_NOT_OK(function->Validate());
-#endif
-
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ explicit FunctionRegistryImpl(FunctionRegistryImpl* parent = NULLPTR)
+ : parent_(parent) {}
+ virtual ~FunctionRegistryImpl() {}
+
+ virtual Status CanAddFunction(std::shared_ptr<Function> function,
+ bool allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/false);
+ }
- const std::string& name = function->name();
- auto it = name_to_function_.find(name);
- if (it != name_to_function_.end() && !allow_overwrite) {
- return Status::KeyError("Already have a function registered with name:
", name);
- }
- name_to_function_[name] = std::move(function);
- return Status::OK();
+ virtual Status AddFunction(std::shared_ptr<Function> function, bool
allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/true);
}
- Status AddAlias(const std::string& target_name, const std::string&
source_name) {
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ virtual Status CanAddAlias(const std::string& target_name,
+ const std::string& source_name) {
+ Status st = DoAddAlias(target_name, source_name, /*add=*/false);
+ return st.ok() || parent_ == nullptr ? st
+ : parent_->CanAddAlias(target_name,
source_name);
+ }
- auto it = name_to_function_.find(source_name);
- if (it == name_to_function_.end()) {
- return Status::KeyError("No function registered with name: ",
source_name);
- }
- name_to_function_[target_name] = it->second;
- return Status::OK();
+ virtual Status AddAlias(const std::string& target_name,
+ const std::string& source_name) {
+ Status st = DoAddAlias(target_name, source_name, /*add=*/true);
+ return st.ok() || parent_ == nullptr ? st
+ : parent_->AddAlias(target_name,
source_name);
Review Comment:
I'm a little confused here. Why are we adding the alias to `parent_` as well?
##########
cpp/src/arrow/compute/registry.cc:
##########
@@ -34,78 +34,144 @@ namespace compute {
class FunctionRegistry::FunctionRegistryImpl {
public:
- Status AddFunction(std::shared_ptr<Function> function, bool allow_overwrite)
{
-#ifndef NDEBUG
- // This validates docstrings extensively, so don't waste time on it
- // in release builds.
- RETURN_NOT_OK(function->Validate());
-#endif
-
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ explicit FunctionRegistryImpl(FunctionRegistryImpl* parent = NULLPTR)
+ : parent_(parent) {}
+ virtual ~FunctionRegistryImpl() {}
+
+ virtual Status CanAddFunction(std::shared_ptr<Function> function,
+ bool allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/false);
+ }
- const std::string& name = function->name();
- auto it = name_to_function_.find(name);
- if (it != name_to_function_.end() && !allow_overwrite) {
- return Status::KeyError("Already have a function registered with name:
", name);
- }
- name_to_function_[name] = std::move(function);
- return Status::OK();
+ virtual Status AddFunction(std::shared_ptr<Function> function, bool
allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/true);
}
- Status AddAlias(const std::string& target_name, const std::string&
source_name) {
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ virtual Status CanAddAlias(const std::string& target_name,
+ const std::string& source_name) {
+ Status st = DoAddAlias(target_name, source_name, /*add=*/false);
+ return st.ok() || parent_ == nullptr ? st
+ : parent_->CanAddAlias(target_name,
source_name);
+ }
- auto it = name_to_function_.find(source_name);
- if (it == name_to_function_.end()) {
- return Status::KeyError("No function registered with name: ",
source_name);
- }
- name_to_function_[target_name] = it->second;
- return Status::OK();
+ virtual Status AddAlias(const std::string& target_name,
+ const std::string& source_name) {
+ Status st = DoAddAlias(target_name, source_name, /*add=*/true);
+ return st.ok() || parent_ == nullptr ? st
+ : parent_->AddAlias(target_name,
source_name);
}
- Status AddFunctionOptionsType(const FunctionOptionsType* options_type,
- bool allow_overwrite = false) {
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ virtual Status CanAddFunctionOptionsType(const FunctionOptionsType*
options_type,
+ bool allow_overwrite = false) {
+ return (parent_ == nullptr
+ ? Status::OK()
+ : parent_->CanAddFunctionOptionsType(options_type,
allow_overwrite)) &
+ DoAddFunctionOptionsType(options_type, allow_overwrite,
/*add=*/false);
Review Comment:
```suggestion
if (parent_ != nullptr) {
RETURN_NOT_OK(parent_->CanAddFunctionOptionsType(options_type,
allow_overwrite));
}
return DoAddFunctionsType(options_type, allow_overwrite, /*add=*/false);
```
##########
cpp/src/arrow/compute/registry.cc:
##########
@@ -34,78 +34,144 @@ namespace compute {
class FunctionRegistry::FunctionRegistryImpl {
public:
- Status AddFunction(std::shared_ptr<Function> function, bool allow_overwrite)
{
-#ifndef NDEBUG
- // This validates docstrings extensively, so don't waste time on it
- // in release builds.
- RETURN_NOT_OK(function->Validate());
-#endif
-
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ explicit FunctionRegistryImpl(FunctionRegistryImpl* parent = NULLPTR)
+ : parent_(parent) {}
+ virtual ~FunctionRegistryImpl() {}
+
+ virtual Status CanAddFunction(std::shared_ptr<Function> function,
+ bool allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/false);
+ }
- const std::string& name = function->name();
- auto it = name_to_function_.find(name);
- if (it != name_to_function_.end() && !allow_overwrite) {
- return Status::KeyError("Already have a function registered with name:
", name);
- }
- name_to_function_[name] = std::move(function);
- return Status::OK();
+ virtual Status AddFunction(std::shared_ptr<Function> function, bool
allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/true);
}
- Status AddAlias(const std::string& target_name, const std::string&
source_name) {
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ virtual Status CanAddAlias(const std::string& target_name,
+ const std::string& source_name) {
+ Status st = DoAddAlias(target_name, source_name, /*add=*/false);
+ return st.ok() || parent_ == nullptr ? st
+ : parent_->CanAddAlias(target_name,
source_name);
+ }
- auto it = name_to_function_.find(source_name);
- if (it == name_to_function_.end()) {
- return Status::KeyError("No function registered with name: ",
source_name);
- }
- name_to_function_[target_name] = it->second;
- return Status::OK();
+ virtual Status AddAlias(const std::string& target_name,
+ const std::string& source_name) {
+ Status st = DoAddAlias(target_name, source_name, /*add=*/true);
+ return st.ok() || parent_ == nullptr ? st
+ : parent_->AddAlias(target_name,
source_name);
}
- Status AddFunctionOptionsType(const FunctionOptionsType* options_type,
- bool allow_overwrite = false) {
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ virtual Status CanAddFunctionOptionsType(const FunctionOptionsType*
options_type,
+ bool allow_overwrite = false) {
+ return (parent_ == nullptr
+ ? Status::OK()
+ : parent_->CanAddFunctionOptionsType(options_type,
allow_overwrite)) &
+ DoAddFunctionOptionsType(options_type, allow_overwrite,
/*add=*/false);
+ }
- const std::string name = options_type->type_name();
- auto it = name_to_options_type_.find(name);
- if (it != name_to_options_type_.end() && !allow_overwrite) {
- return Status::KeyError(
- "Already have a function options type registered with name: ", name);
- }
- name_to_options_type_[name] = options_type;
- return Status::OK();
+ virtual Status AddFunctionOptionsType(const FunctionOptionsType*
options_type,
+ bool allow_overwrite = false) {
+ return (parent_ == nullptr
+ ? Status::OK()
+ : parent_->CanAddFunctionOptionsType(options_type,
allow_overwrite)) &
+ DoAddFunctionOptionsType(options_type, allow_overwrite,
/*add=*/true);
}
- Result<std::shared_ptr<Function>> GetFunction(const std::string& name) const
{
+ virtual Result<std::shared_ptr<Function>> GetFunction(const std::string&
name) const {
Review Comment:
```suggestion
Result<std::shared_ptr<Function>> GetFunction(const std::string& name)
const {
```
##########
cpp/src/arrow/compute/registry.cc:
##########
@@ -34,78 +34,144 @@ namespace compute {
class FunctionRegistry::FunctionRegistryImpl {
public:
- Status AddFunction(std::shared_ptr<Function> function, bool allow_overwrite)
{
-#ifndef NDEBUG
- // This validates docstrings extensively, so don't waste time on it
- // in release builds.
- RETURN_NOT_OK(function->Validate());
-#endif
-
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ explicit FunctionRegistryImpl(FunctionRegistryImpl* parent = NULLPTR)
+ : parent_(parent) {}
+ virtual ~FunctionRegistryImpl() {}
+
+ virtual Status CanAddFunction(std::shared_ptr<Function> function,
+ bool allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/false);
+ }
- const std::string& name = function->name();
- auto it = name_to_function_.find(name);
- if (it != name_to_function_.end() && !allow_overwrite) {
- return Status::KeyError("Already have a function registered with name:
", name);
- }
- name_to_function_[name] = std::move(function);
- return Status::OK();
+ virtual Status AddFunction(std::shared_ptr<Function> function, bool
allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/true);
}
- Status AddAlias(const std::string& target_name, const std::string&
source_name) {
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ virtual Status CanAddAlias(const std::string& target_name,
+ const std::string& source_name) {
+ Status st = DoAddAlias(target_name, source_name, /*add=*/false);
+ return st.ok() || parent_ == nullptr ? st
+ : parent_->CanAddAlias(target_name,
source_name);
+ }
- auto it = name_to_function_.find(source_name);
- if (it == name_to_function_.end()) {
- return Status::KeyError("No function registered with name: ",
source_name);
- }
- name_to_function_[target_name] = it->second;
- return Status::OK();
+ virtual Status AddAlias(const std::string& target_name,
+ const std::string& source_name) {
+ Status st = DoAddAlias(target_name, source_name, /*add=*/true);
+ return st.ok() || parent_ == nullptr ? st
+ : parent_->AddAlias(target_name,
source_name);
}
- Status AddFunctionOptionsType(const FunctionOptionsType* options_type,
- bool allow_overwrite = false) {
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ virtual Status CanAddFunctionOptionsType(const FunctionOptionsType*
options_type,
+ bool allow_overwrite = false) {
+ return (parent_ == nullptr
+ ? Status::OK()
+ : parent_->CanAddFunctionOptionsType(options_type,
allow_overwrite)) &
+ DoAddFunctionOptionsType(options_type, allow_overwrite,
/*add=*/false);
+ }
- const std::string name = options_type->type_name();
- auto it = name_to_options_type_.find(name);
- if (it != name_to_options_type_.end() && !allow_overwrite) {
- return Status::KeyError(
- "Already have a function options type registered with name: ", name);
- }
- name_to_options_type_[name] = options_type;
- return Status::OK();
+ virtual Status AddFunctionOptionsType(const FunctionOptionsType*
options_type,
Review Comment:
```suggestion
Status AddFunctionOptionsType(const FunctionOptionsType* options_type,
```
##########
cpp/src/arrow/compute/registry.cc:
##########
@@ -115,20 +181,47 @@ std::unique_ptr<FunctionRegistry>
FunctionRegistry::Make() {
return std::unique_ptr<FunctionRegistry>(new FunctionRegistry());
}
-FunctionRegistry::FunctionRegistry() { impl_.reset(new
FunctionRegistryImpl()); }
+std::unique_ptr<FunctionRegistry> FunctionRegistry::Make(FunctionRegistry*
parent) {
+ return std::unique_ptr<FunctionRegistry>(
+ new FunctionRegistry(new
FunctionRegistry::FunctionRegistryImpl(&*parent->impl_)));
+}
+
+std::unique_ptr<FunctionRegistry> FunctionRegistry::Make(
+ std::unique_ptr<FunctionRegistry> parent) {
+ return FunctionRegistry::Make(&*parent);
+}
+
Review Comment:
```suggestion
```
As explained in the header file.
##########
cpp/src/arrow/compute/registry.cc:
##########
@@ -34,78 +34,144 @@ namespace compute {
class FunctionRegistry::FunctionRegistryImpl {
public:
- Status AddFunction(std::shared_ptr<Function> function, bool allow_overwrite)
{
-#ifndef NDEBUG
- // This validates docstrings extensively, so don't waste time on it
- // in release builds.
- RETURN_NOT_OK(function->Validate());
-#endif
-
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ explicit FunctionRegistryImpl(FunctionRegistryImpl* parent = NULLPTR)
+ : parent_(parent) {}
+ virtual ~FunctionRegistryImpl() {}
+
+ virtual Status CanAddFunction(std::shared_ptr<Function> function,
+ bool allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/false);
+ }
- const std::string& name = function->name();
- auto it = name_to_function_.find(name);
- if (it != name_to_function_.end() && !allow_overwrite) {
- return Status::KeyError("Already have a function registered with name:
", name);
- }
- name_to_function_[name] = std::move(function);
- return Status::OK();
+ virtual Status AddFunction(std::shared_ptr<Function> function, bool
allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/true);
}
- Status AddAlias(const std::string& target_name, const std::string&
source_name) {
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ virtual Status CanAddAlias(const std::string& target_name,
+ const std::string& source_name) {
+ Status st = DoAddAlias(target_name, source_name, /*add=*/false);
+ return st.ok() || parent_ == nullptr ? st
+ : parent_->CanAddAlias(target_name,
source_name);
+ }
- auto it = name_to_function_.find(source_name);
- if (it == name_to_function_.end()) {
- return Status::KeyError("No function registered with name: ",
source_name);
- }
- name_to_function_[target_name] = it->second;
- return Status::OK();
+ virtual Status AddAlias(const std::string& target_name,
+ const std::string& source_name) {
+ Status st = DoAddAlias(target_name, source_name, /*add=*/true);
+ return st.ok() || parent_ == nullptr ? st
+ : parent_->AddAlias(target_name,
source_name);
}
- Status AddFunctionOptionsType(const FunctionOptionsType* options_type,
- bool allow_overwrite = false) {
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ virtual Status CanAddFunctionOptionsType(const FunctionOptionsType*
options_type,
+ bool allow_overwrite = false) {
+ return (parent_ == nullptr
+ ? Status::OK()
+ : parent_->CanAddFunctionOptionsType(options_type,
allow_overwrite)) &
+ DoAddFunctionOptionsType(options_type, allow_overwrite,
/*add=*/false);
+ }
- const std::string name = options_type->type_name();
- auto it = name_to_options_type_.find(name);
- if (it != name_to_options_type_.end() && !allow_overwrite) {
- return Status::KeyError(
- "Already have a function options type registered with name: ", name);
- }
- name_to_options_type_[name] = options_type;
- return Status::OK();
+ virtual Status AddFunctionOptionsType(const FunctionOptionsType*
options_type,
+ bool allow_overwrite = false) {
+ return (parent_ == nullptr
+ ? Status::OK()
+ : parent_->CanAddFunctionOptionsType(options_type,
allow_overwrite)) &
+ DoAddFunctionOptionsType(options_type, allow_overwrite,
/*add=*/true);
}
- Result<std::shared_ptr<Function>> GetFunction(const std::string& name) const
{
+ virtual Result<std::shared_ptr<Function>> GetFunction(const std::string&
name) const {
auto it = name_to_function_.find(name);
if (it == name_to_function_.end()) {
+ if (parent_ != nullptr) {
+ return parent_->GetFunction(name);
+ }
return Status::KeyError("No function registered with name: ", name);
}
return it->second;
}
- std::vector<std::string> GetFunctionNames() const {
+ virtual std::vector<std::string> GetFunctionNames() const {
std::vector<std::string> results;
+ if (parent_ != nullptr) {
+ results = parent_->GetFunctionNames();
+ }
for (auto it : name_to_function_) {
results.push_back(it.first);
}
std::sort(results.begin(), results.end());
return results;
}
- Result<const FunctionOptionsType*> GetFunctionOptionsType(
+ virtual Result<const FunctionOptionsType*> GetFunctionOptionsType(
Review Comment:
```suggestion
Result<const FunctionOptionsType*> GetFunctionOptionsType(
```
##########
cpp/src/arrow/compute/registry.cc:
##########
@@ -34,78 +34,144 @@ namespace compute {
class FunctionRegistry::FunctionRegistryImpl {
public:
- Status AddFunction(std::shared_ptr<Function> function, bool allow_overwrite)
{
-#ifndef NDEBUG
- // This validates docstrings extensively, so don't waste time on it
- // in release builds.
- RETURN_NOT_OK(function->Validate());
-#endif
-
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ explicit FunctionRegistryImpl(FunctionRegistryImpl* parent = NULLPTR)
+ : parent_(parent) {}
+ virtual ~FunctionRegistryImpl() {}
+
+ virtual Status CanAddFunction(std::shared_ptr<Function> function,
+ bool allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/false);
+ }
- const std::string& name = function->name();
- auto it = name_to_function_.find(name);
- if (it != name_to_function_.end() && !allow_overwrite) {
- return Status::KeyError("Already have a function registered with name:
", name);
- }
- name_to_function_[name] = std::move(function);
- return Status::OK();
+ virtual Status AddFunction(std::shared_ptr<Function> function, bool
allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/true);
}
- Status AddAlias(const std::string& target_name, const std::string&
source_name) {
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ virtual Status CanAddAlias(const std::string& target_name,
+ const std::string& source_name) {
+ Status st = DoAddAlias(target_name, source_name, /*add=*/false);
+ return st.ok() || parent_ == nullptr ? st
+ : parent_->CanAddAlias(target_name,
source_name);
+ }
- auto it = name_to_function_.find(source_name);
- if (it == name_to_function_.end()) {
- return Status::KeyError("No function registered with name: ",
source_name);
- }
- name_to_function_[target_name] = it->second;
- return Status::OK();
+ virtual Status AddAlias(const std::string& target_name,
+ const std::string& source_name) {
+ Status st = DoAddAlias(target_name, source_name, /*add=*/true);
+ return st.ok() || parent_ == nullptr ? st
+ : parent_->AddAlias(target_name,
source_name);
}
- Status AddFunctionOptionsType(const FunctionOptionsType* options_type,
- bool allow_overwrite = false) {
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ virtual Status CanAddFunctionOptionsType(const FunctionOptionsType*
options_type,
+ bool allow_overwrite = false) {
+ return (parent_ == nullptr
+ ? Status::OK()
+ : parent_->CanAddFunctionOptionsType(options_type,
allow_overwrite)) &
+ DoAddFunctionOptionsType(options_type, allow_overwrite,
/*add=*/false);
+ }
- const std::string name = options_type->type_name();
- auto it = name_to_options_type_.find(name);
- if (it != name_to_options_type_.end() && !allow_overwrite) {
- return Status::KeyError(
- "Already have a function options type registered with name: ", name);
- }
- name_to_options_type_[name] = options_type;
- return Status::OK();
+ virtual Status AddFunctionOptionsType(const FunctionOptionsType*
options_type,
+ bool allow_overwrite = false) {
+ return (parent_ == nullptr
+ ? Status::OK()
+ : parent_->CanAddFunctionOptionsType(options_type,
allow_overwrite)) &
+ DoAddFunctionOptionsType(options_type, allow_overwrite,
/*add=*/true);
}
- Result<std::shared_ptr<Function>> GetFunction(const std::string& name) const
{
+ virtual Result<std::shared_ptr<Function>> GetFunction(const std::string&
name) const {
auto it = name_to_function_.find(name);
if (it == name_to_function_.end()) {
+ if (parent_ != nullptr) {
+ return parent_->GetFunction(name);
+ }
return Status::KeyError("No function registered with name: ", name);
}
return it->second;
}
- std::vector<std::string> GetFunctionNames() const {
+ virtual std::vector<std::string> GetFunctionNames() const {
std::vector<std::string> results;
+ if (parent_ != nullptr) {
+ results = parent_->GetFunctionNames();
+ }
for (auto it : name_to_function_) {
results.push_back(it.first);
}
std::sort(results.begin(), results.end());
return results;
}
- Result<const FunctionOptionsType*> GetFunctionOptionsType(
+ virtual Result<const FunctionOptionsType*> GetFunctionOptionsType(
const std::string& name) const {
auto it = name_to_options_type_.find(name);
if (it == name_to_options_type_.end()) {
+ if (parent_ != nullptr) {
+ return parent_->GetFunctionOptionsType(name);
+ }
return Status::KeyError("No function options type registered with name:
", name);
}
return it->second;
}
- int num_functions() const { return
static_cast<int>(name_to_function_.size()); }
+ virtual int num_functions() const {
Review Comment:
```suggestion
int num_functions() const {
```
##########
cpp/src/arrow/compute/registry.cc:
##########
@@ -34,78 +34,144 @@ namespace compute {
class FunctionRegistry::FunctionRegistryImpl {
public:
- Status AddFunction(std::shared_ptr<Function> function, bool allow_overwrite)
{
-#ifndef NDEBUG
- // This validates docstrings extensively, so don't waste time on it
- // in release builds.
- RETURN_NOT_OK(function->Validate());
-#endif
-
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ explicit FunctionRegistryImpl(FunctionRegistryImpl* parent = NULLPTR)
+ : parent_(parent) {}
+ virtual ~FunctionRegistryImpl() {}
+
+ virtual Status CanAddFunction(std::shared_ptr<Function> function,
+ bool allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/false);
+ }
- const std::string& name = function->name();
- auto it = name_to_function_.find(name);
- if (it != name_to_function_.end() && !allow_overwrite) {
- return Status::KeyError("Already have a function registered with name:
", name);
- }
- name_to_function_[name] = std::move(function);
- return Status::OK();
+ virtual Status AddFunction(std::shared_ptr<Function> function, bool
allow_overwrite) {
+ return (parent_ == nullptr ? Status::OK()
+ : parent_->CanAddFunction(function,
allow_overwrite)) &
+ DoAddFunction(function, allow_overwrite, /*add=*/true);
}
- Status AddAlias(const std::string& target_name, const std::string&
source_name) {
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ virtual Status CanAddAlias(const std::string& target_name,
+ const std::string& source_name) {
+ Status st = DoAddAlias(target_name, source_name, /*add=*/false);
+ return st.ok() || parent_ == nullptr ? st
+ : parent_->CanAddAlias(target_name,
source_name);
+ }
- auto it = name_to_function_.find(source_name);
- if (it == name_to_function_.end()) {
- return Status::KeyError("No function registered with name: ",
source_name);
- }
- name_to_function_[target_name] = it->second;
- return Status::OK();
+ virtual Status AddAlias(const std::string& target_name,
+ const std::string& source_name) {
+ Status st = DoAddAlias(target_name, source_name, /*add=*/true);
+ return st.ok() || parent_ == nullptr ? st
+ : parent_->AddAlias(target_name,
source_name);
}
- Status AddFunctionOptionsType(const FunctionOptionsType* options_type,
- bool allow_overwrite = false) {
- std::lock_guard<std::mutex> mutation_guard(lock_);
+ virtual Status CanAddFunctionOptionsType(const FunctionOptionsType*
options_type,
+ bool allow_overwrite = false) {
+ return (parent_ == nullptr
+ ? Status::OK()
+ : parent_->CanAddFunctionOptionsType(options_type,
allow_overwrite)) &
+ DoAddFunctionOptionsType(options_type, allow_overwrite,
/*add=*/false);
+ }
- const std::string name = options_type->type_name();
- auto it = name_to_options_type_.find(name);
- if (it != name_to_options_type_.end() && !allow_overwrite) {
- return Status::KeyError(
- "Already have a function options type registered with name: ", name);
- }
- name_to_options_type_[name] = options_type;
- return Status::OK();
+ virtual Status AddFunctionOptionsType(const FunctionOptionsType*
options_type,
+ bool allow_overwrite = false) {
+ return (parent_ == nullptr
+ ? Status::OK()
+ : parent_->CanAddFunctionOptionsType(options_type,
allow_overwrite)) &
+ DoAddFunctionOptionsType(options_type, allow_overwrite,
/*add=*/true);
}
- Result<std::shared_ptr<Function>> GetFunction(const std::string& name) const
{
+ virtual Result<std::shared_ptr<Function>> GetFunction(const std::string&
name) const {
auto it = name_to_function_.find(name);
if (it == name_to_function_.end()) {
+ if (parent_ != nullptr) {
+ return parent_->GetFunction(name);
+ }
return Status::KeyError("No function registered with name: ", name);
}
return it->second;
}
- std::vector<std::string> GetFunctionNames() const {
+ virtual std::vector<std::string> GetFunctionNames() const {
Review Comment:
```suggestion
std::vector<std::string> GetFunctionNames() const {
```
--
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]