Apache Arrow官方文档-内存结构

发布时间:2020-06-03 01:13:55 作者:Lynn_Yuan
来源:网络 阅读:1682

定义/术语

  由于不同的项目使用不同的词语描述各种概念,所以这里有一个小小的术语表来帮助消除歧义。

会像:

* Length: 5, Null count: 1
* Null bitmap buffer:

  |Byte 0 (validity bitmap) \| Bytes 1-63           |
  |-------------------------|-----------------------|
  |00011011                 | 0 (padding)          |

* Value Buffer:

  |Bytes 0-3 | Bytes 4-7 | Bytes 8-11| Bytes 12-15| Bytes 16-19 | Bytes 20-63 |
  |----------|-----------|-----------|-----------|-------------|-------------|
  | 1        | 2         | unspecified| 4        | 8           | unspecified |

示例布局:非空int32数组

[1,2,3,4,8]有两种可能的布局:

* Length: 5, Null count: 0
* Null bitmap buffer:

  | Byte 0 (validity bitmap) | Bytes 1-63            |
  |--------------------------|-----------------------|
  | 00011111                 | 0 (padding)           |

* Value Buffer:

  |Bytes 0-3 | Bytes 4-7| Bytes 8-11| bytes 12-15 | bytes 16-19 | Bytes 20-63 |
  |---------|----------|------------|-------------|-------------|-------------|
  | 1       | 2        | 3          | 4           | 8           | unspecified |
或者位图消失:
* Length 5, Null count: 0
* Null bitmap buffer: Not required
* Value Buffer:

  |Bytes 0-3 | Bytes 4-7 | Bytes 8-11| bytes 12-15 | bytes 16-19| Bytes 20-63 |
  |---------|-----------|------------|-------------|------------|-------------|
  | 1       | 2         | 3          | 4           | 8          | unspecified |

列表类型

  列表是一种嵌套类型,其中每个数组槽都包含一个可变大小的值序列,它们都具有相同的相对类型(异质性可以通过联合实现,稍后描述)。
  列表类型被指定为List<T>,这里的T是任何相对类型(原始或嵌套)。
  列表数组由以下组合表示:

* Length: 4, Null count: 1
* Null bitmap buffer:

  | Byte 0 (validity bitmap) | Bytes 1-63            |
  |--------------------------|-----------------------|
  | 00001101                 | 0 (padding)           |

* Offsets buffer (int32)

  | Bytes 0-3  | Bytes 4-7   | Bytes 8-11  | Bytes 12-15 | Bytes 16-19 | Bytes 20-63 |
  |------------|-------------|-------------|-------------|-------------|-------------|
  | 0          | 3           | 3           | 7           | 7           | unspecified |

* Values array (char array):
  * Length: 7,  Null count: 0
  * Null bitmap buffer: Not required

    | Bytes 0-6  | Bytes 7-63  |
    |------------|-------------|
    | joemark    | unspecified |

示例布局: List<List<byte>>

[[[1,2],[3,4]],[[5,6,7],null,[8]],[[9,10]]]

将被表示如下:

* Length 3
* Nulls count: 0
* Null bitmap buffer: Not required
* Offsets buffer (int32)

  | Bytes 0-3  | Bytes 4-7  | Bytes 8-11 | Bytes 12-15 | Bytes 16-63 |
  |------------|------------|------------|-------------|-------------|
  | 0          |  2         |  5         |  6          | unspecified |

* Values array (`List<byte>`)
  * Length: 6, Null count: 1
  * Null bitmap buffer:

    | Byte 0 (validity bitmap) | Bytes 1-63  |
    |--------------------------|-------------|
    | 00110111                 | 0 (padding) |

  * Offsets buffer (int32)

    | Bytes 0-27           | Bytes 28-63 |
    |----------------------|-------------|
    | 0, 2, 4, 7, 7, 8, 10 | unspecified |

  * Values array (bytes):
    * Length: 10, Null count: 0
    * Null bitmap buffer: Not required

      | Bytes 0-9                     | Bytes 10-63 |
      |-------------------------------|-------------|
      | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 | unspecified |

结构体类型

  一个struct是一个嵌套类型,它被一个有序序列的相对类型(可以都是不同的)参数化,相对类型称为它的字段。
  通常,这些字段具有名称,但名称及其类型是元数据类型的一部分,而不是物理内存布局。
  一个struct数组没有为它的值分配任何额外的物理存储。如果结构体数组有一个或多个空值,则它必须具有分配的空值位图。
  在物理上,一个struct类型中每个字段都有一个子数组。
例如,struct(这里显示为字符串的字段名称用于说明)

Struct <
  name: String (= List<char>),
  age: Int32
>

有两个子数组,一个列表 数组(如上所示)和一个具有Int32逻辑类型的4字节的基本类型数组。

示例布局Struct<List<char>, Int32>:

[{'joe',1},{null,2},null,{'mark',4}]的布局将是:

* Length: 4, Null count: 1
* Null bitmap buffer:

  |Byte 0 (validity bitmap) | Bytes 1-63            |
  |-------------------------|-----------------------|
  | 00001011                | 0 (padding)           |

* Children arrays:
  * field-0 array (`List<char>`):
    * Length: 4, Null count: 2
    * Null bitmap buffer:

      | Byte 0 (validity bitmap) | Bytes 1-63            |
      |--------------------------|-----------------------|
      | 00001001                 | 0 (padding)           |

    * Offsets buffer:

      | Bytes 0-19     |
      |----------------|
      | 0, 3, 3, 3, 7  |

     * Values array:
        * Length: 7, Null count: 0
        * Null bitmap buffer: Not required

        * Value buffer:

          | Bytes 0-6      |
          |----------------|
          | joemark        |

  * field-1 array (int32 array):
    * Length: 4, Null count: 1
    * Null bitmap buffer:

      | Byte 0 (validity bitmap) | Bytes 1-63            |
      |--------------------------|-----------------------|
      | 00001011                 | 0 (padding)           |

    * Value Buffer:

      |Bytes 0-3   | Bytes 4-7   | Bytes 8-11  | Bytes 12-15 | Bytes 16-63 |
      |------------|-------------|-------------|-------------|-------------|
      | 1          | 2           | unspecified | 4           | unspecified |

  虽然结构体没有为每个语义槽(即每个与C语言样结构体相似的标量)提供物理存储,但是可以通过空值位图将整个结构化槽设置为空。任何子字段数组可以根据各自的独立空值位图拥有空值。这意味着对于特定的结构体槽,结构体数组的空值位图可能表示一个空槽,当其一个或多个子数组在其相应的槽中具有非空值时。读取结构体数组时,父空值位图是权威的。这在上面的示例中说明,子数组具有空值结构体的有效实体,但是由父数组的空值位图“隐藏”。但是,独立处理时,子数组的对应值将不为空。

密集联合(共用体)类型

  密集的联合在语义上类似于一个结构体,并且包含相对类型的有序序列。当一个结构体包含多个数组时,一个联合语义上是一个单个数组,其中每个槽可以有一个不同的类型。
 联合类型可以被命名,但是像结构体一样,这将是元数据的问题,并且不会影响物理内存布局。
 我们定义了针对不同用例优化的两种不同的联合类型。首先,密集联合,表示每个值为5字节开销的混合型数组。其物理布局如下:
每个相对类型一个子数组

示例布局:密集联合

逻辑联合的示例布局: Union<f: float, i: int32>具有以下值:[{f = 1.2},null,{f = 3.4},{i = 5}]

* Length: 4, Null count: 1
* Null bitmap buffer:
  |Byte 0 (validity bitmap) | Bytes 1-63            |
  |-------------------------|-----------------------|
  |00001101                 | 0 (padding)           |

* Types buffer:

  |Byte 0   | Byte 1      | Byte 2   | Byte 3   | Bytes 4-63  |
  |---------|-------------|----------|----------|-------------|
  | 0       | unspecified | 0        | 1        | unspecified |

//存的是Union中的索引 f索引为0, i索引为1

* Offset buffer:

  |Byte 0-3 | Byte 4-7    | Byte 8-11 | Byte 12-15 | Bytes 16-63 |
  |---------|-------------|-----------|------------|-------------|
  | 0       | unspecified | 1         | 0          | unspecified |

* Children arrays:
  * Field-0 array (f: float):
    * Length: 2, nulls: 0
    * Null bitmap buffer: Not required

    * Value Buffer:

      | Bytes 0-7 | Bytes 8-63  |
      |-----------|-------------|
      | 1.2, 3.4  | unspecified |

  * Field-1 array (i: int32):
    * Length: 1, nulls: 0
    * Null bitmap buffer: Not required

    * Value Buffer:

      | Bytes 0-3 | Bytes 4-63  |
      |-----------|-------------|
      | 5         | unspecified |

稀疏联合类型

  稀疏联合与密集联合具有相同的结构,省略了偏移数组。在这种情况下,子数组的长度与union的长度相等。
  虽然与密集联合相比,稀疏联合可能使用明显更多的空间,但在某些确定的用例中可能拥有一些优点:


* Length: 6, Null count: 0
* Null bitmap buffer: Not required

* Types buffer:

 | Byte 0     | Byte 1      | Byte 2      | Byte 3      | Byte 4      | Byte 5       | Bytes  6-63           |
 |------------|-------------|-------------|-------------|-------------|--------------|-----------------------|
 | 0          | 1           | 2           | 1           | 0           | 2            | unspecified (padding) |

* Children arrays:

  * u0 (Int32):
    * Length: 6, Null count: 4
    * Null bitmap buffer:

      |Byte 0 (validity bitmap) | Bytes 1-63            |
      |-------------------------|-----------------------|
      |00010001                 | 0 (padding)           |

    * Value buffer:

      |Bytes 0-3   | Bytes 4-7   | Bytes 8-11  | Bytes 12-15 | Bytes 16-19 | Bytes 20-23  | Bytes 24-63           |
      |------------|-------------|-------------|-------------|-------------|--------------|-----------------------|
      | 5          | unspecified | unspecified | unspecified | 4           |  unspecified | unspecified (padding) |

  * u1 (float):
    * Length: 6, Null count: 4
    * Null bitmap buffer:

      |Byte 0 (validity bitmap) | Bytes 1-63            |
      |-------------------------|-----------------------|
      | 00001010                | 0 (padding)           |

    * Value buffer:

      |Bytes 0-3    | Bytes 4-7   | Bytes 8-11  | Bytes 12-15 | Bytes 16-19 | Bytes 20-23  | Bytes 24-63           |
      |-------------|-------------|-------------|-------------|-------------|--------------|-----------------------|
      | unspecified |  1.2        | unspecified | 3.4         | unspecified |  unspecified | unspecified (padding) |

  * u2 (`List<char>`)
    * Length: 6, Null count: 4
    * Null bitmap buffer:

      | Byte 0 (validity bitmap) | Bytes 1-63            |
      |--------------------------|-----------------------|
      | 00100100                 | 0 (padding)           |

    * Offsets buffer (int32)

      | Bytes 0-3  | Bytes 4-7   | Bytes 8-11  | Bytes 12-15 | Bytes 16-19 | Bytes 20-23 | Bytes 24-27 | Bytes 28-63 |
      |------------|-------------|-------------|-------------|-------------|-------------|-------------|-------------|
      | 0          | 0           | 0           | 3           | 3           | 3           | 7           | unspecified |

    * Values array (char array):
      * Length: 7,  Null count: 0
      * Null bitmap buffer: Not required

        | Bytes 0-7  | Bytes 8-63            |
        |------------|-----------------------|
        | joemark    | unspecified (padding) |

  请注意,稀疏联合中的嵌套类型必须在内部一致(例如,见图中的列表),即任何子数组上任何索引j的随机访问都不会导致错误。换句话说,嵌套类型的数组如果被重新解释为非嵌套数组,则必须是有效的。
  与结构类似,特定的子数组可能具有非空槽,即使父联合数组的空值位图表示槽为空。此外,即使类型数组指示槽在索引处包含不同类型,子数组也可能具有非空槽。

字典编码

  当字段被字典编码时,这些值由表示字典中值的索引的Int32数组表示。字典被收录为DictionaryBatch,它的id由字段表中的元数据(Message.fbs)中定义的字典属性引用。字典具有与字段类型相同的布局。字典中的每个实体都可以通过其DictionaryBatch中的索引来访问。当Schema引用Dictionary id时,它必须在任何RecordBatch之前为此id发送DictionaryBatch。
例如,您可以获得以下数据:

type: List<String>

[
 ['a', 'b'],
 ['a', 'b'],
 ['a', 'b'],
 ['c', 'd', 'e'],
 ['c', 'd', 'e'],
 ['c', 'd', 'e'],
 ['c', 'd', 'e'],
 ['a', 'b']
]

在字典编码的形式中,这可能显示为:

data List<String> (dictionary-encoded, dictionary id i)
indices: [0, 0, 0, 1, 1, 1, 0]
//['a','b']为字典值,索引为0;['c', 'd', 'e']为字典值,索引为2

dictionary i

type: List<String>

[
 ['a', 'b'],
 ['c', 'd', 'e'],
]
推荐阅读:
  1. Apache Arrow 晋升为Apache基金会顶级项目
  2. Apache Calcite官方文档中文版- 进阶-4. Lattices

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

arrow 内存结构 列式存储

上一篇:使用Azure Storage进行静态Web托管

下一篇:华为DHCP配置以及DHCP中继

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》