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);