Trino中的Block类型
Block
类型,Trino查询获取数据的单元——页(Page)也是以Block
类型为基础的, 深入了解Block
结构有助于理解Trino内部的数据组织。
Block在Trino中以接口形式出现,Trino定义了几个基本的实现类, 作为基础的Block结构,然后再定义其他更加高层的Block结构,其内部是其他Block的组合,可以这么理解:当你手上有一个Block的数据,其内部的真实数据可能是引用其他的一个或多个Block。本质上Block是个套娃结构,Block对象是个实现了Block接口的嵌套数据对象,Block存储的底层数据都指向了基本的Block实现类。
Block基本实现类
Block基本实现类是指内部包含直接真实数据,不是以嵌套其他Block对象的形式出现的数据类型。其内部的数据以基本类型数组或者Slice对象出现,这里的Slice指的是一块连续内存区域,后面会讲到。
Block的基本实现类有IntArrayBlock
, ShortArrayBlock
, ByteArrayBlock
, LongArrayBlock
,Int96ArrayBlock
, Int128ArrayBlock
, VariableWidthBlock
.
IntArrayBlock
IntArrayBlock
内部以整型数组存放该Block的真实底层数据。具体的内存形式如下图:
IntArrayBlock
的底层数据其实就是int[] values
和boolean[] valueIsNull
这两个数组,这里boolean[] valueIsNull
的出现是为了表示某个位置上的值是否为null,毕竟values 是一个基本类型数组,而不是包装类型Integer
数组,所以还是需要有个额外的布尔类型数组表示某个位置是否是null。
这里要注意,values
数组和 valueIsNull
数组的长度不一定相同,因为IntArrayBlock
只会使用其中的一部分数据,即索引为 [arrayOffset, arrayOffset+positionCount)
的区域。所以这个Block在计算其底层数据大小(sizeInByte)的时候,只会统计自己使用的那一部分。
在计算整个类型占用的字节大小(retainedSizeInByte)时,会计算values
和valueIsNull
占用的全部内存,然后再加上这个类自身使用的内存大小(这里要注意,数组是引用类型,在类中只保存了一个引用标记,所以需要额外计算)。
与IntArrayBlock
类型类似, ShortArrayBlock
、ByteArrayBlock
和 LongArrayBlock
无非就是把int[]
换成了short[]
、byte[]
和Long[]
, 这几个类型此处就不再赘述了。
Int96ArrayBlock和Int128ArrayBlock
由于java中的整型长是64字节,即long类型,那么如何表示更长字节的整型呢?
Trino使用了long+int来表示一个96位的整型。同样,这里的high
数组 和 low
数组 的长度也没有必要相同,Block对象只会使用其一部分。
由于没有基本类型可以表示96位的整型,所以从Int96ArrayBlock
获取数据需要调用getLong()
和getInt()
两个方法,才能将一个完整的数据取出。并且由于high
和 low
表示的数据高低位不一样,所以在获取数据时要有明确的offset。只能这么调用:
long high = getLong(position, );
int low = getInt(position, 8);
相关文章