为 UDx 分配资源
为用户定义的扩展 (UDx) 分配内存和文件句柄时,您可以选择以下两种方法:
-
使用 Vertica SDK 宏分配资源。这是最佳方法,因为此方法使用 Vertica 自有的资源管理器,并且能够保证 UDx 所使用的资源得到回收。请参阅使用 SDK 宏分配资源。
-
虽然不是推荐的选项,但您可以使用标准 C++ 方法(使用
new将对象实例化和使用malloc()分配内存块等)自己在 UDx 中分配资源。您必须在 UDx 退出之前手动释放这些资源。
注意
如果选择手动在 UDx 分配资源,您必须十分小心。未能正确释放资源将造成严重的负面影响,尤其是当 UDx 在非隔离模式下运行时。无论选择哪种方法,您通常都应在 UDx 类中名为 setup() 的函数中分配资源。在 UDx 函数对象已实例化之后,但在 Vertica 调用该对象以处理数据之前,将调用此函数。
如果手动在 setup() 函数中分配内存,则您必须在名为 destroy() 的相应函数中释放内存。在 UDx 已执行所有处理之后,将调用此函数。如果 UDx 返回错误,也会调用此函数(请参阅处理错误)。
注意
始终应使用setup() 和 destroy() 函数来分配和释放资源,而不应使用自己的构造函数和析构函数。Vertica 从自有的内存池之一为 UDx 对象分配内存。Vertica 总是在释放对象的内存之前调用 UDx 的 destroy() 函数。无法保证会在取消分配对象之前调用 UDx 的析构函数。使用 destroy() 函数可确保 UDx 有机会在被销毁之前释放已分配的资源。
以下代码片段演示了使用 setup() 和 destroy() 函数分配和释放内存。
class MemoryAllocationExample : public ScalarFunction
{
public:
uint64* myarray;
// Called before running the UDF to allocate memory used throughout
// the entire UDF processing.
virtual void setup(ServerInterface &srvInterface, const SizedColumnTypes
&argTypes)
{
try
{
// Allocate an array. This memory is directly allocated, rather than
// letting Vertica do it. Remember to properly calculate the amount
// of memory you need based on the data type you are allocating.
// This example divides 500MB by 8, since that's the number of
// bytes in a 64-bit unsigned integer.
myarray = new uint64[1024 * 1024 * 500 / 8];
}
catch (std::bad_alloc &ba)
{
// Always check for exceptions caused by failed memory
// allocations.
vt_report_error(1, "Couldn't allocate memory :[%s]", ba.what());
}
}
// Called after the UDF has processed all of its information. Use to free
// any allocated resources.
virtual void destroy(ServerInterface &srvInterface, const SizedColumnTypes
&argTypes)
{
// srvInterface.log("RowNumber processed %d records", *count_ptr);
try
{
// Properly dispose of the allocated memory.
delete[] myarray;
}
catch (std::bad_alloc &ba)
{
// Always check for exceptions caused by failed memory
// allocations.
vt_report_error(1, "Couldn't free memory :[%s]", ba.what());
}
}