Velox Types介绍和源码解析

Velox 支持 scalar(有大小没有方向)类型和复杂类型。标量类型分为一组固定的物理类型和一组可扩展的逻辑类型。物理类型决定数据在内存中的布局。逻辑类型向物理类型添加附加语义。

Phsical Types

每个物理类型都是用c++ type实现的,不会存储实际数据,下表是支持的物理类型、其对应的c++类型和每个值所需的固定宽度字节

Physical TypeC++ TypeFixed Width (bytes)
BOOLEANbool0.125 (i.e. 1 bit)
TINYINTint8_t1
SMALLINTint16_t2
INTEGERint32_t4
BIGINTint64_t8
HUGEINTint128_t16
REALfloat4
DOUBLEdouble8
TIMESTAMPstruct Timestamp16
VARCHARstruct StringView16
VARBINARYstruct StringView16
OPAQUEstd::shared_ptr16
UNKNOWNstruct UnknownValue0

除了VARCHAR and VARBINARY 所有的物理类型都有和 c++类型一对一的映射。c++类型也在vector类中用作模板参数。例如,64 位整数向量表示为 FlatVector<int64_t>,其类型为 BIGINT。

OPAQUE类型可用于定义自定义类型。OPAQUE类型必须与唯一的std::type_index一起指定。此类型的值必须以std::shared_ptr提供,其中T是C++类型。下面给出了有关何时使用OPAQUE类型定义自定义类型的更多详细信息。

VARCHAR、VARBINARY、OPAQUE 每个值使用可变的字节数。这些类型在 C++ 类型中存储固定宽度部分,在其他地方存储可变宽度部分。所有其他类型的每个值都使用固定宽度字节,如上表所示。VARCHAR和VARBINARY FlatVector将每个值的固定宽度部分存储在StringView中。StringView是一个结构,包含一个4字节大小字段、一个4字节前缀字段和一个指向可变宽度部分的8字节字段指针。每个值的可变宽度部分存储在stringBuffers中。OPAQUE类型将可变宽度部分存储在FlatVector之外。

UNKNOWN类型用于表示unknown type的empty或全为null的vector。例如,SELECT array() 返回 ARRAY(UNKNOWN()),因为无法确定元素的类型。这是有效的,因为array中没有元素。array方法作用:返回具有给定元素的数组

TIMESTAMP类型用于表示特定的时间点。 TIMESTAMP 定义为自 UNIX epoch 以来秒和纳秒的总和。struct Timestamp 包含一个表示秒的 64 位有符号整数和表示纳秒的另一个 64 位无符号整数。纳秒表示时间戳的高精度部分,小于1秒。纳秒的有效范围是 [0, 10^9)。纪元之前的时间戳是使用负秒值指定的。

Logical Types

逻辑类型由物理类型支持并包含附加语义。同一物理类型可以支持多种逻辑类型。因此,了解 C++ 类型不足以推断逻辑类型。下表显示了支持的逻辑类型及其相应的物理类型。

Logical TypePhysical Type
DATEINTEGER
DECIMALBIGINT if precision <= 18, HUGEINT if precision >= 19
INTERVAL DAY TO SECONDBIGINT
INTERVAL YEAR TO MONTHINTEGER

Custom Types

大多数自定义类型可以表示为逻辑类型,并且可以通过扩展现有的物理类型来构建。例如,下面描述的Presto类型是通过扩展物理类型来实现的。当没有物理类型可用于支持逻辑类型时,必须使用OPAQUE类型。

Complex Types

Velox 支持 ARRAY、MAP 和 ROW 复杂类型。复杂类型由标量(scalar)类型组成,可以与其他复杂类型嵌套。

例如: MAP<INTEGER, ARRAY> 是一个复杂类型,其key是标量类型 INTEGER,value是元素类型为 BIGINT 的复杂类型 ARRAY。

Array类型包含其元素类型。 Map类型包含键类型和值类型。row类型包含其字段类型及其名称。

源码解析

Type 定义了velox的内置类型的一些信息提供一些接口,不存储实际的数据

枚举类型TypeKind定义类型的种类

enum class TypeKind : int8_t {BOOLEAN = 0,TINYINT = 1,SMALLINT = 2,INTEGER = 3,BIGINT = 4,REAL = 5,DOUBLE = 6,VARCHAR = 7,VARBINARY = 8,TIMESTAMP = 9,HUGEINT = 10,// Enum values for ComplexTypes start after 30 to leave// some values space to accommodate adding new scalar/native// types above.ARRAY = 30,MAP = 31,ROW = 32,UNKNOWN = 33,FUNCTION = 34,OPAQUE = 35,INVALID = 36
};

下面是Type的继承结构

				             Type|TypeBase<T>/      |       \ScalarType  ArrayType   MapType

Type 是抽象基类继承自Tree,复杂类型子类例如ArrayType和MapType会包含子类型,从而形成Tree

TypeBase:从Type派生而来的中间类,借助TypeTraits实现方法,TypeTraits使用模板特化技术根据TypeKind定义以下属性

template <TypeKind KIND>
struct TypeTraits {};template <>
struct TypeTraits<TypeKind::BOOLEAN> {using ImplType = ScalarType<TypeKind::BOOLEAN>; // velox实现的 typeusing NativeType = bool; // c++ type,对于无法映射的复杂类型这里是voidusing DeepCopiedType = NativeType;static constexpr uint32_t minSubTypes = 0;static constexpr uint32_t maxSubTypes = 0;static constexpr TypeKind typeKind = TypeKind::BOOLEAN;// TypeKindstatic constexpr bool isPrimitiveType = true; // 是否为c++原生类型static constexpr bool isFixedWidth = true;// 是否为固定长度static constexpr const char* name = "BOOLEAN";//类型名
};class TypeBase : public Type {public:using NativeType = TypeTraits<KIND>;TypeBase() : Type{KIND} {}bool isPrimitiveType() const override {return TypeTraits<KIND>::isPrimitiveType;}bool isFixedWidth() const override {return TypeTraits<KIND>::isFixedWidth;}const char* kindName() const override {return TypeTraits<KIND>::name;}const char* name() const override {return TypeTraits<KIND>::name;}const std::vector<TypeParameter>& parameters() const override {static const std::vector<TypeParameter> kEmpty = {};return kEmpty;}
};

ScalarType:标量类型类模板,标量对象只含单个元素,以下类型都从ScalarType类模板实例而来:

  • 各种整型类型(对应8-64位宽度的整型,TinyintType、SmallintType、IntegerType、BigintType)
  • RealType、DoubleType
  • VarcharType、VarbinaryType
  • TimestampType、DateType、IntervalDayTimeType
using IntegerType = ScalarType<TypeKind::INTEGER>;
using BooleanType = ScalarType<TypeKind::BOOLEAN>;

ArrayType:对应数组类型,包含一个TypePtr child_成分(也就是Tree的子节点),数组类型所有内部元素的类型相同(只有一个)。

MapType:对应映射类型,包含TypePtr key_ + TypePtr value_两个成分,从Key映射到Value,符合一般映射的语义。

RowType:对应行类型TypeKind=ROW,代表行的每一列的meta信息,包括2个成分。

  • 一个string name_的列表(各列的名称)
  • 一个TypePtr children_的列表(各列的Type信息)

类型工厂:TypeFactory

类模板TypeFactory实现create()接口,用于创建某种具体类型,参考设计模式的工厂方法。

对于标量类型,通常只需要一个唯一的类型实例,因为标量类型不包含额外状态信息(额外是指相对于Type本身状态外)。

对于非标量类型(TypeKind>=30),比如ArrayType、MapType、RowType等类型,因为每个各MapType的Key、Value并不相同,所以需要针对每个类型创建对应的Type。

template <TypeKind KIND>
struct TypeFactory {static std::shared_ptr<const typename TypeTraits<KIND>::ImplType> create() {return TypeTraits<KIND>::ImplType::create();}
};template <>
struct TypeFactory<TypeKind::UNKNOWN> {static std::shared_ptr<const UnknownType> create() {return std::make_shared<UnknownType>();}
};

利用宏和模板提供了获取类型实例的方法使得INTEGER()等价于return ScalarType<TypeKind::INTEGER>::create();

#define VELOX_SCALAR_ACCESSOR(KIND) \std::shared_ptr<const ScalarType<TypeKind::KIND>> KIND()
#define VELOX_DEFINE_SCALAR_ACCESSOR(KIND)                   \std::shared_ptr<const ScalarType<TypeKind::KIND>> KIND() { \return ScalarType<TypeKind::KIND>::create();             \}
VELOX_DEFINE_SCALAR_ACCESSOR(INTEGER); 

CppToType支持根据c++ type获取velox type的相关信息(保存在TypeTraits),实现方法也是模板特化

template <typename T> struct CppToType {};
template <> struct CppToType<int128_t> : public CppToTypeBase<TypeKind::HUGEINT> {};
struct CppToTypeBase : public TypeTraits<KIND> {static auto create() {return TypeFactory<KIND>::create();}
};CppToType<T>::typeKind // 获取c++ type对应的TypeKind

参考

https://facebookincubator.github.io/velox/develop/types.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/22963.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

右键Open with VSCode打开Vue3项目

之前看到一些同事能够对项目根目录进行右键打开项目到 Microsoft VS Code &#xff0c;当时觉得挺不错的&#xff0c;于是乎今天自己折腾了一遍。 目录 1、创建vue3项目 2、更改注册表 # 打开注册表编辑器&#xff08;Registry Editor&#xff09; # 导航到以下注册表路径 …

前端_防抖节流

目录 一、防抖&#xff08;debounce&#xff09; 1.使用场景 2.js代码实现 3.lodash工具库使用 二、节流&#xff08;throttle&#xff09; 1.使用场景 2.js代码实现 3.lodash工具库使用 前端做项目&#xff0c;为了防止用户因为网络不好数据响应慢&#xff0c;导致进行…

信不信,马上教会你Purple Pi OH开发板之ADB常用命令

开源鸿蒙硬件方案领跑者 触觉智能 本文适用于在Purple Pi OH开发板进行分区镜像烧录。触觉智能的Purple Pi OH鸿蒙开源主板&#xff0c;是华为Laval官方社区主荐的一款鸿蒙开发主板。 该主板主要针对学生党&#xff0c;极客&#xff0c;工程师&#xff0c;极大降低了开源鸿蒙开…

自然资源-关于加强规划实施监督管理的指导意见(浙江省自然资源厅学习借鉴)

自然资源-关于加强规划实施监督管理的指导意见&#xff08;浙江省自然资源厅&#xff08;征求意见稿&#xff09;学习借鉴 以下为征求意见稿的内容&#xff0c;很多干活&#xff1a; 各市、县&#xff08;市、区&#xff09;自然资源主管部门&#xff1a; 为加强国土空间规划…

C#-Switch判断分支语句

Switch判断分支语句 作用 &#xff1a; 让顺序执行的代码 产生分支 判断变量和常量相同时 才会执行 用法: Switch后面的变量值与case后面的常量相同时&#xff0c;case内的代码才会执行&#xff0c;如果都不满足则执行default内的代码 break的作用: 跳出 不会再执行判断 …

lua字符串模式匹配

string.gmatch()不支持匹配首字符 string.gmatch(s, pattern)中&#xff0c;如果s的开头是’^字符&#xff0c;不会被当成首字符标志&#xff0c;而是被当成一个普通字符。 比如 s"hello world from lua" for w in string.gmatch(s, "^%a") doprint(w) e…

SQL学习小记(五)解决python连接Oracle数据库出现的问题

python运行时出现错误DPI-1047: Cannot locate a 64-bit Oracle Client library: “The specified module could not be 解决python连接Oracle数据库出现的问题 1. 配置本地Oracle的path2. python10的详细安装过程2.1. python10下载2.2. python10安装2.3.额外操作 3. python 安…

纷享销客BI典型场景案例解析

本章以具体案例来说明纷享销客一体化BI智能分析平台为企业在实际使用过程中带来的价值。 1)场景一&#xff1a;销售经理想要在周会上关注各销售人员的客户及订单情况&#xff0c;并在每周一上午9点可以把上周的整体情况周期性的将报表推送给相关销售人员。 具体图表展示样式及…

BIO 探究二

接上文 BIO 初探究 文章目录 前言一、使用netty二、nio 客户端 与 bio 服务端&#xff0c;bio 服务端 与 nio 客户端总结# 未完待续 前言 提示&#xff1a;验证阻塞到底阻塞在什么地方 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、使用netty 上…

当企业越来越难做,精益变革能带来什么改变?

随着技术的不断进步和消费者需求的日益多样化&#xff0c;传统的管理模式和生产方式已经难以适应时代的发展。越来越多的企业开始陷入困境&#xff0c;难以在激烈的市场竞争中立足。然而&#xff0c;正是在这样的背景下&#xff0c;精益变革应运而生&#xff0c;为企业带来了前…

使用html2canvas和jspdf导出pdf包含跨页以及页脚

首先要下载两个文件&#xff0c;一个为html2canvas.min.js&#xff0c;另一个是jspdf.umd.min.js这两个文件分别下载的地址我也附录上&#xff0c;都在官网git&#xff1a; html2canvas.min.js: https://html2canvas.hertzen.com/dist/html2canvas.min.js jspdf.umd.min.js: …

代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素

一、704. 二分查找 题目链接&#xff1a;https://leetcode.cn/problems/binary-search/description/ 文章讲解&#xff1a;https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html 视频讲解&#xff1a;https://www.bilibili.com/video/BV1fA4y1o715 1.…

感染恶意代码之后怎么办?

隔离设备 立即将感染设备与网络隔离&#xff0c;断开与互联网和其他设备的连接。这可以防止恶意代码进一步传播到其他设备&#xff0c;并减少对网络安全的威胁。 确认感染 确认设备是否真的感染了恶意代码。这可能需要使用安全软件进行全面扫描&#xff0c;以检测和识别任何已…

前端实现大文件分片并行上传、断点续传、秒传(完整解析)

一、总体流程图 二、具体步骤 简单理解&#xff1a;前端先将文件切割多份&#xff0c;在进行上传&#xff0c;由后端进行切片合并操作。 具体逻辑&#xff1a; 1. 前端选中上传文件&#xff08;如果是批量上传就把选中的文件存入选中文件列表数组中&#xff0c;后续在遍历上…

【Vue3-Element-Admin 动态路由】涉及到的配置

Vue3-Element-Admin 动态路由 涉及到的配置 0. Vue3-Element-Admin 项目地址1. router/index.ts2. Mock接口模拟数据3. store/permission4. api/menu5. plugins/permission 这篇文章讲的主要是 Vue3-Element-Admin 差不多内置的动态路由配置 (根据后端接口渲染) 先把开发环境&a…

纷享销客一体化BI智能分析平台介绍

纷享销客BI智能分析平台是一款自助式敏捷BI&#xff0c;无缝继承纷享销客PaaS平台的对象数据、对象关系、功能权限体系与数据权限体系&#xff0c;用户通过简单的拖拽点选即可实现灵活定义分析模型和可视化自助分析&#xff0c;零技术门槛快速上手&#xff0c;面向全员各类角色…

深度学习 --- stanford cs231 编程作业(assignment1,Q2: SVM分类器)

stanford cs231 编程作业之SVM分类器 写在最前面&#xff1a; 深度学习&#xff0c;或者是广义上的任何学习&#xff0c;都是“行千里路”胜过“读万卷书”的学识。这两天光是学了斯坦福cs231n的一些基础理论&#xff0c;越往后学越觉得没什么。但听的云里雾里的地方也越来越多…

Python教程-快速入门基础必看课程10-函数基础

该视频主要讲述了Python中函数的定义、使用和返回。函数是Python中一个重要的概念&#xff0c;可以用来封装一段可重复使用的代码&#xff0c;并通过函数名来调用它。在Python中&#xff0c;定义函数的关键字是def&#xff0c;后面跟着函数名和括号。函数可以没有参数&#xff…

【学习笔记】MySQL(Ⅰ)

MySQL(Ⅰ) 1、 介绍 1.1、概述 1.2、MySQL 的优缺点 1.4、关系型数据库模型2、 基础篇 —— SQL(结构化查询语言) 2.1、通用语法 2.2、SQL 语句的分类 2.3、DDL 语句 2.3.1 数据库结构相关的语法 2.3.2 数据表相关的语…

Java实现俄罗斯方块游戏源代码(启动即可玩)

这是一个用Java Swing实现的俄罗斯方块游戏&#xff0c;具有经典的游戏机制和图形界面。游戏中&#xff0c;玩家需要旋转和移动不断下落的方块&#xff0c;使其填满一行来消除该行并得分。 该项目适合学习Java GUI编程、游戏开发基础以及面向对象编程&#xff08;OOP&#xff0…