UDChunker 类
您可以子类化 UDChunker
类以允许解析器支持 协作解析。此类仅在 C++ API 中可用。
从根本上说,UDChunker
是一个非常简单的解析器。与 UDParser
一样,它包含以下三个方法:setup()
、process()
和 destroy()
。您必须覆盖 process()
,而且可以覆盖其他方法。此类包含一个额外的方法 alignPortion()
,您必须在要为 UDChunker
启用 分摊加载时实施该方法。
设置和分解
与 UDParser
一样,您可以为块分割器定义初始化和清理代码。Vertica 会在第一次调用 process()
之前先调用 setup()
,并在最后一次调用 process()
之后才调用 destroy()
。您的对象可能会在多个加载源之间重用,因此请确保 setup()
会完全初始化所有字段。
分块
Vertica 会调用 process()
以将输入拆分为可以独立解析的块。该方法会采用输入缓冲区和输入状态指示器:
-
OK
:输入缓冲区从流的开头或中间位置开始。 -
END_OF_FILE
:无更多数据可用。 -
END_OF_PORTION
:源已到达其部分的结尾。此状态仅在使用分摊加载时出现。
如果输入状态为 END_OF_FILE
,则块分割器应将 input.offset
标记设置为 input.size
并返回 DONE
。返回 INPUT_NEEDED
是错误的。
如果输入状态为 OK
,则块分割器应从输入缓冲区读取数据并找到记录边界。如果它找到至少一条记录的结尾,它应将 input.offset
标记与缓冲区中最后一条记录结尾之后的字节对齐并返回 CHUNK_ALIGNED
。例如,如果输入是“abc~def”并且“~”是记录终止符,则此方法应将 input.offset
设置为 4,即“d”的位置。如果 process()
在没有找到记录边界的情况下到达输入的结尾,则应返回 INPUT_NEEDED
。
您可以将输入拆分成更小的块,但使用输入中的所有可用记录可以提高性能。例如,块分割器可以从输入的结尾向后扫描以找到记录终止符(它可能是输入中诸多记录的最后一条),并将其作为一个块全部返回,而不扫描剩余输入。
如果输入状态为 END_OF_PORTION
,则块分割器的行为应与输入状态 OK
的行为相同,只不过它还应设置一个标记。再次调用时,它应在下一部分中找到第一条记录,并将块与该记录对齐。
输入数据可能包含 null 字节(如果源文件包含这种字节)。输入实参不会自动以 null 值终止。
process()
方法不得被无限期阻止。如果此方法在很长一段时间内无法继续执行,它应返回 KEEP_GOING
。未能返回 KEEP_GOING
将导致多种后果,例如导致用户无法取消查询。
有关使用分块的 process()
方法的示例,请参阅 C++ 示例:分隔解析器和块分割器。
对齐部分
如果块分割器支持分摊加载,请实施 alignPortion()
方法。在调用 process()
之前,Vertica 会调用此方法一次或多次,以将输入偏移量与该部分中第一个完整块的开头对齐。该方法会采用输入缓冲区和输入状态指示器:
-
START_OF_PORTION
:缓冲区的开头对应于该部分的开头。可以使用getPortion()
方法来访问该部分的偏移量和大小。 -
OK
:输入缓冲区在相应部分的中间。 -
END_OF_PORTION
:缓冲区的结尾对应于相应部分的结尾或超出相应部分的结尾。 -
END_OF_FILE
:无更多数据可用。
该方法应从缓冲区的开头扫描到第一个完整记录的开头。它应该将 input.offset
设置为此位置并返回以下值之一:
-
DONE
(如果找到块)。input.offset
为块的第一个字节。 -
INPUT_NEEDED
(如果输入缓冲区不包含任何块的开头)。从END_OF_FILE
的输入状态返回此值是错误的。 -
REJECT
(如果相应部分而非缓冲区不包含任何块的开头)。
API
UDChunker API 提供了以下通过子类扩展的方法:
virtual void setup(ServerInterface &srvInterface,
SizedColumnTypes &returnType);
virtual StreamState alignPortion(ServerInterface &srvInterface,
DataBuffer &input, InputState state);
virtual StreamState process(ServerInterface &srvInterface,
DataBuffer &input, InputState input_state)=0;
virtual void cancel(ServerInterface &srvInterface);
virtual void destroy(ServerInterface &srvInterface,
SizedColumnTypes &returnType);