栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【软件工程实践】Pig项目2-Data目录源码分析-Tuple

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【软件工程实践】Pig项目2-Data目录源码分析-Tuple

2021SC@SDUSC

Data目录文件列表如下

文件很多,我们先了解Pig的数据结构,再进行分析,其中一个很重要的概念是数据模型

相关资料链接:【Pig源码分析】谈谈Pig的数据模型 -数据库-火龙果软件工程

数据模型Schema

Schema为数据所遵从的类型格式,包括两个部分:
field的 名称  类型

field表示数据块(A field is a piece of data)可理解为数据字段

Schema与Pig Latin的关系

Pig Latin表达式操作的是relation,FILTER、FOREACH、GROUP、SPLIT等关系操作符所操作的relation就是bag,bag为tuple的集合,tuple为有序的field列表集合

因此,Schema是Pig Latin表达式操作的一个单元

用户常用as语句来自定义schema,或是load函数导入schema,比如:

 

若不指定field的类型,则其默认为bytearray。对未知schema进行操作时,有:

若join/cogroup/cross多关系操作遇到未知schema,则会将其视为null schema,导致返回结果的schema也为null;

若flatten一个empty inner schema的bag(即:bag{})时,则返回结果的schema为null;

若union时二者relation的schema不一致,则返回结果的schema为null;

若field的schema为null,会将该字段视为bytearray。

为了保证pig脚本运行的有效性,在写UDF时要在outputSchema方法中指定返回结果的schema。

注释:UDF为用户自定义函数(Userdefined function)

数据类型

Pig的基本数据类型与对应的Java类:

复杂数据类型及其对应的Java类:

笔记:这里可以进一步理解Schama,如'hello'、18就是数据块field;有序field的集合是tuple,如(18,1),bag为tuple的集合,如{('hello'),(18,1)},某些操作符所操作的relation就是bag 

Tuple源码分析

在Data目录下搜索含有Tuple的文件名:

我们来参照上文提到文章里的内容:

在KEYSET源码中,创建Tuple对象采用工厂+单例设计模式:

private static final TupleFactory TUPLE_FACTORY = TupleFactory.getInstance();
Tuple t = TUPLE_FACTORY.newTuple(s);

笔记:keyset.java位于目录,代码如下

其中,map为java自带的类,用法参照以下博客,我们只需要知道它是用于遍历的就行了

java笔记--Map的用法_Linias的博客-CSDN博客_java map

可以看见新建bag的代码为 new NonSpillableDataBag(m.szie()),新建tuple的代码为前面那两端代码

继续参考前面的博客:

事实上,TupleFactory是个抽象类,实现接口TupleMaker。在方法TupleFactory.getInstance()中,默认情况下返回的是BinSedesTupleFactory对象,同时支持加载用户重写的TupleFactory类(pig.data.tuple.factory.name指定类名、 pig.data.tuple.factory.jar指定类所在的jar)。BinSedesTupleFactory继承于TupleFactory:

在BinSedesTupleFactory的newTuple方法中,返回的是BinSedesTuple对象。BinSedesTuple类继承于DefaultTuple类,在DefaultTuple类中有List mFields字段,这便是存储Tuple数据的地方了,mFields所持有类型为ArrayList();。类图关系:

笔记:这篇博客已经将Tuple整体脉络整理地非常清楚了,我们继续看一些细节

TupleFactory.java开头有以下注释

这是一个构造元组的工厂。这个类是抽象的,因此用户可以重写元组工厂,如果他们想提供自己的
返回它们对元组的实现。如果属性pig.data.tuple.factory.name设置为类名 pig.data.tuple.factory.jar被设置为一个指向jar的URL包含上面命名的类,然后{@link #getInstance()}将创建一个指定类的实例,使用指定的jar。否则,它将创建一个{@link DefaultTupleFactory}的实例

原文

 

TupleFactory实现的函数:

获取对单例工厂的引用。
@return用于构造元组的TupleFactory

public static TupleFactory getInstance()

创建一个空元组。这个(函数)应该尽量少用
,使用newTuple(int)代替。
@return空的新元组

public abstract Tuple newTuple();

创建一个具有size字段的元组。只要可能,这是首选
*在null构造函数上,因为构造函数可以预分配
*存放字段的容器大小。一旦这个被调用,它
*是合法的调用Tuple。Set (x, object),其中x <大小。
* @param size元组字段个数。
* @return带有size字段的元组

public abstract Tuple newTuple(int size);
从提供的对象列表创建一个元组。底层列表
*将被复制。
* @param c用于作为元组字段的对象列表。
* @return一个以列表对象作为字段的元组

public abstract Tuple newTuple(List c);
从提供的对象列表创建一个元组,保持所提供的
*列表。新的元组将接管所提供列表的所有权。
* @param list将成为元组字段的对象列表。
* @return一个以列表对象作为字段的元组

public abstract Tuple newTupleNoCopy(List list);

用单个元素创建一个元组。这很有用,因为
事实上,包(目前)只接受元组,我们经常结束
*将单个元素放入元组中,以便将其放入包中。
* @param datum放入元组的数据。
* @return一个只有一个字段的元组

public abstract Tuple newTuple(Object datum);

返回表示实现的元组的实际类
*工厂将返回。这是需要的,因为Hadoop需要
*以了解我们将用于输入和输出的确切类。
* @return实现元组的类

public abstract Class tupleClass();

protected TupleFactory() {
}

仅供测试之用。这个函数不应该是
*被任何人调用,但单元测试

public static void resetSelf() {
    gSelf = null;
}


返回实现元组原始比较器的实际类
工厂将会返回。重写此选项以允许Hadoop
*加快元组排序。实际返回的类应该知道
*元组的序列化细节。默认实现
* (PigTupleDefaultRawComparator)将在比较之前序列化数据
* @return实现元组原始比较器的类

public Class tupleRawComparatorClass() {
    return PigTupleDefaultRawComparator.class;
}

此方法用于检查该工厂是否创建了元组
*将是一个固定的大小时,他们被创建。在实践中,这意味着
*是否支持append。
* @return该元组是否固定

public abstract boolean isFixedSize();

总结:TupleFactory是个抽象类,除了getInstance外其他大多没给出实现,等待继承它的类来实现,至于TupleMaker更加简单粗暴,以下为其代码

 显然,这样的设计是一种面向对象的设计,是为了面向对象而服务的

那么,本次的代码分析就到这里

 

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号