mondrian源码分析与说明Word下载.docx

上传人:b****7 文档编号:22261948 上传时间:2023-02-03 格式:DOCX 页数:21 大小:245.38KB
下载 相关 举报
mondrian源码分析与说明Word下载.docx_第1页
第1页 / 共21页
mondrian源码分析与说明Word下载.docx_第2页
第2页 / 共21页
mondrian源码分析与说明Word下载.docx_第3页
第3页 / 共21页
mondrian源码分析与说明Word下载.docx_第4页
第4页 / 共21页
mondrian源码分析与说明Word下载.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

mondrian源码分析与说明Word下载.docx

《mondrian源码分析与说明Word下载.docx》由会员分享,可在线阅读,更多相关《mondrian源码分析与说明Word下载.docx(21页珍藏版)》请在冰豆网上搜索。

mondrian源码分析与说明Word下载.docx

1.2.架构

mondrian总共包含四个层次:

表示层,计算层,聚集层,存储层.。

表示层(presentationlayer):

指最终呈现在用户显示器上的,以及与用户之间的交互,有许多方法来展现多维数据,包括数据透视表,饼,柱,线状图.

计算层(dimensionallayer):

分析,验证,执行MDX查询.一个mdx查询语句会有多个处理阶段。

先是计算轴,然后是轴上的单元值。

为效率起见,计算层批量将单元请求发送到聚集层。

请求转换器允许程序操作存在的请求,而不是为每个请求从头构造mdx请求。

元数据描述了计算模型和它怎么匹配到关系模型。

聚集层(starlayer):

一个聚集指内存中一组计算值(cell),这些值通过维列来限制.计算层发送单元请求,如果请求不在缓存中,或者不能通过旋转聚集导出的话,聚集层向存储层发送请求.聚集层是一个数据缓冲层(cache),从数据库来的单元数据,聚合后提供给计算层。

聚集层的主要作用是提高系统的性能。

存储层:

提供聚集单元数据(cell)和维表的成员(member),这些层可以不在同一机子上,但是计算和聚集层必须在同一台机子上。

有三种需要存储的数据:

事实数据(事实表)、维度表和聚集数据(即聚合表)

架构图如下:

2.静态类包分析

2.1.包解释

mondrian.calc提供编译好的表达式。

mondrian.gui设计Mondrianschema的图形接口

mondrian.i18n国际化和本地化工具

mondrian.mdx为mdx表达式定义解析树

mondrian.olap核心包,定义了连接和schema的元模型,用来执行查询

mondrian.olap4j中间层,olap服务器的驱动,用来代替jolap的

mondrian.recorder任务处理记录接口

mondrian.rolapolap包的数据访问层的实现

mondrian.spi用户自定义扩展的服务端支持接口

mondrian.tuiMondrian文本用户接口

mondrian.udf用户定义方法

mondrian.utilMondrian工具包

mondrian.webMondrian的servlet和tag库

mondrian.xmlaxmlforanalysisAPI的实现

2.2.Schemamanger部分

Mondrian.rolap.RolapSchema类是mondrianschema的核心类,该类在在建立RolapConnection时被建立,但是有个schemaPool维护着schema的缓存,参见RolapSchema.Pool内部类。

在RolapSchema对象生成之前,首先有个原始的MondrianDef$Schema对象,该对象相当于mondrianschemaxml文件的简单对应,由xml解析器直接生成。

具体来说首先由xml文件解析成dom对象,然后再生成更加结构化的MondrianDef$Schema,最后再load成更加高级的RolapSchema对象,具体参见RolapSchema.load(StringcatalogUrl,StringcatalogStr);

以MondrianDef$Schema或RolapSchema对象为根,都还会有一系列的内部类去对应于mondrianschema下的子元素。

如果一个Hierarchy的hasAll为true,则会有一个allmember,对应着也需要一个虚拟的alllevel,位于该Hierarchy的levels[0]位置。

2.3.包mondrian.calc

Calc是所有可计算表达式的基接口。

在mondrian中关于表达式有如下两个概念:

⏹ThelogicallanguageofparsedMDXfragments(Exp).

⏹Thephyiscallanguageofcompiledexpressions(Calc).

两种语言可以允许我们将逻辑语言(即mdx语言)和物理语言(howitistobeevaluated)分开.物理语言对类型的要求更加严格,andcertainconstructswhichareimplicitinthelogicallanguage(suchastheadditionofcallstothe<

Member>

.CurrentMemberfunction)aremadeexplicitinthephysicallanguage。

Calc接口针对各种类型有许多子接口:

其中IntegerCalc,BooleanCalc,DoubleCalc,StringCalc是数值型的,MemberCalc,LevelCalc,HierarchyCalc,DimensionCalc则用于olap模型中的元素。

每一个子接口有都有一个实现的虚基类:

AbstractIntegerCalc,AbstractBooleanCalc,AbstractDoubleCalc,AbstractStringCalc,AbstractMemberCalc,AbstractLevelCalc,AbstractHierarchyCalc,AbstractDimensionCalc。

表达式(Expression)通常由表达式编译者(ExpCompiler)创建。

对于一个给定的表达式通常有若干个evaluation策略,表达式编译者在编译过程中可以给我们一个选择的机会。

2.4.包mondrian.olap—接口

Mondrian的核心包,定义了连接对象和完整的olap模型结构元对象,并且允许执行mdx查询语句。

2.4.1.mdx函数包

mondrian.olap.fun定义了mdx内置的函数集。

函数(function)的定义:

参数

描述

例子

name

函数名

"

Members"

signature

函数标志

<

Dimension>

.Members"

description

函数描述

Returnsthesetofallmembersinadimension."

flags

Encodingofthesyntactictype,returntype,andparametertypesofthisoperator.Theencodingisdescribedbelow.

pxd"

Theflagsfieldisanstringwhichencodesthesyntactictype,returntype,andparametertypesofthisoperator.

Thefirstcharacterdeterminesthesyntactictype,asdescribedbyFunUtil.decodeSyntacticType(String).

Thesecondcharacterdeterminesthereturntype,asdescribedbyFunUtil.decodeReturnCategory(String).

Thethirdandsubsequencecharactersdeterminethetypesoftheargumentsarguments,asdescribedbyFunUtil.decodeParameterCategories(String).

Forexample,"

means"

anoperatorwithpropertysyntax(p)whichreturnsaset(x)andtakesadimension(d)asitsargument"

.

2.4.2.funCall

AFunCallisafunctionappliedtoalistofoperands.

Theparsercreatesfunctioncallsasanunresolvedfunctioncall.

Thevalidatorconvertsittoaresolvedfunctioncall,whichhasafunctiondefinitionandextratypeinformation。

参见:

Mondrian.olap.ResolveFunCallUnresolveFunCall

2.4.3.Query类

用于mdx查询。

2.4.3.1.创建query

创建:

Connection.parseQuery(java.lang.String)。

创建mondrian.olap.Parser类,基于java_cup实现,调用其parse或debug_parse()方法,里面最主要是CUP$Parser$do_action()方法,内部针对所有语句词句做了解析。

其中case75:

生成最后的mondrian.olap.Query对象,内部调用parser.makeQuery()方法,内部初始化时会再调用query的resolve,mondrian.olap.QueryAxis的resolve(),进而会执行数据库。

2.4.3.2.执行query

执行:

Connection.execute(mondrian.olap.Query)

返回结果:

Result.

有些查询从缓存中读取,非常迅速。

当也有些需要花费些时间,这时可以通过MondrianProperties.QueryTimeout参数设置timeout。

如果想控制返回结果不至于太大,可以通过MondrianProperties.QueryLimit参数控制返回的cell数目。

在查询执行的任何时候,另一个进程都可以通过cancel()方法取消该查询,此时Connection.execute(Query)会抛出异常。

2.5.包mondrian.rolap—计算层

实现最终的实际的olap数据访问功能,包括读取维度成员值和cell值。

2.5.1.成员读取包MemberReader

2.5.1.1.概述

包路径:

Mondrian.rolap。

该部分的起点是RolapEvaluator类。

当一个类似于“member.children”的成员表达式被请求时,RolapEvaluator将调用RolapSchemaReader对象.RolapSchemaReader将再负责调用各个MemberReader对象(每个维度一个memberReader)。

在大部分场合下,将使用SmartMemberReader来迅速返回所需要的维度成员值。

2.5.1.2.SmartMemberReader

SmartMemberReader实现了MemberReader接口,它实现了维度成员及其子成员的缓存,如果有一个成员位于缓存中,则还会有一个其子成员的列表。

它同时缓存了level下的成员们。

该类主要的成员有:

source:

MemberReader,用于实际从数据库中读取维度成员值。

mapMemberToChildren:

map,实现成员及其子成员的映射,

key为RolapMember,value为List<

RolapMember>

mapKeyToMember:

map,实现所有成员的缓存,其中的key为MemberKey

mapLevelToMembers:

map,实现级别及其所有成员的映射,

key为RolapLevel,value为List<

上述的source其实为mondrian.rolap.SqlMemberSource类,该类中反过来又存储了SmartMemberReader对象,作为其cache成员属性。

成员读取过程:

⏹smartMemberReader.getMemberChildren(parentMembers,children,constrain);

⏹最终通过source.getMemberChildren()…,其中反过来会把找到的children赋予mapKeyToMember。

⏹最终除了将结果返回在children输出参数中,同时也对mapMemberToChildren赋值了。

另外,smartMemberReader.getMembersInlevel()实现了对mapLevelToMembers的缓存。

在newRolapEvaluator()时被调用。

在读取时会对成员进行orderby(如果设置了ascending的话。

2.5.2.单元格读取CellReader

2.5.2.1.概述

Cells会被求值多次。

第一次时,Evaluator使用FastBatchingCellReader来求值。

当一个单元被求值时,evaluateCurrent()被调用。

此时FastBatchingCellReader并没有被调用,而是为那个cell记录了一个CellRequest并且return(notthrow)anexception。

在所有的cells都有了对应的CellRequests之后,Aggregation会生成SQL,以一个单独的sql请求来载入所有的cells。

然后由AggregatingCellReader重新计算cells,从缓存中返回cells值。

2.5.2.2.FastBatchingCellReader类

主要方法,Objectget(Evaluatorevaluator)

⏹首先根据当前的上下文环境(即一组members)创建cellRequest,cellRequest中包含了所有必要的从star中取值的信息。

该组members的交集便是要求值的单元格,其中切片轴上的成员和其他轴上的成员完全同等对待;

其中度量轴上的成员要求上StoredMeasure(非计算成员CaculatedMember);

度量值上的成员位于第一个。

通过调用request的addConstrainedColumn()方法把各member对应的column和value(属StarColumnPredicate)值加至到request中.

⏹调用AggregationManager.getCellFromCache(request,pinnedSegments)方法从缓存中获取cell值。

首先根据request中的列组索引标识从缓存中获取aggreation缓存对象,如果为空说明缓存还未建立则直接返回null,如果有值则调用aggregation.getCellValue(measure,colValueKeys)方法获取缓存的cell值;

getCellValue内部首先会根据measure查找匹配的segment,然后调用segment.getCellValue(keys)从segment的dataset缓存集中查找相应的cell值。

⏹如果getCellFromCache返回为null则调用recordCellRequest()记录需求。

这些cellrequest会被组织成多个cellrequestbatch,以便将来聚合层进行批读取以提高效率。

关于batch的详细讨论参见下面Batch类章节。

⏹上层会在适当的时候调用batchCellReading.loadAggregations()以实际读取这些cell值,前提是batches对象中已有cellRequest了。

每个batch的读取参见batch.loadAggregation()方法,最终调用聚合层的方法,参见aggreation.load(….)。

2.5.2.3.FastBatchingCellReader.Batch类

每个batch对应与一组特定的columns环境下的cell求取(具有相同的列和列值(列值是具体的值,不会是“all”值));

从batch的属性可以看出batch包含了哪些上下文:

⏹RolapStar.Column[],这个指明了基于哪些列(也即基于哪些维度,包括切片维度)进行读取;

⏹Set<

StarColumnPredicate>

[],保存了每列的限定值,对于一列而言,限定值可能会有多个(毕竟是批处理,一次请求多个);

⏹MeasureList,指明求取哪些度量值上的cell(度量值本质是度量维上的限定值)。

⏹BitKey,该batch的唯一索引。

如图所示的一个mdx查询结果界面:

此时会产生两个batch,每个batch最终可能会产生若干segment,segment是cells的集合,segment数和度量值个数相同。

⏹一个batch是(其中“当量数/适应交通量=拥挤度”,拥挤度是计算成员),最终产生3个segment,每个segment只有一个cell:

Ø

(地市=’宁波市’,measure=’观察里程’)

(地市=’宁波市’,measure=’当量数’)

(地市=’宁波市’,measure=’适应交通量’)

⏹另一个batch是(其中的G310等是路线代码,最终过滤掉空值后就剩下两个了),最终产生3个segment,每个segment有多个cell:

(地市=’宁波市’,roadIdin(G310,G322,G210,S321….),measure=’观察里程’)

(地市=’宁波市’,roadIdin(G310,G322,G210,S321….),measure=’当量数’)

(地市=’宁波市’,roadIdin(G310,G322,G210,S321….),measure=’适应交通量’)

1、…

2.5.3.RolapResult类

RolapResult是一个运行中的请求的结果集。

Mondiran的执行结果由RolapResult类表单,由于mdx查询语句本身就包含onrows(行轴上)、oncolumns(列轴上)和where部分(切片轴上),结果集中相对应的为ROlapAxis对象,这其中有个sliceAxis对象。

因此结果集是由若干ROlapAxis对象和一个RolapCell组构成的。

每个axis对象又由若干Position对象组成,每个Position对象又可能由若干member组成(注意一个postion会横跨多个维度的成员)。

注意ROlapAxis是抽象类,实际的对象类可能随着不同的轴是不同的。

如图:

图中,column轴上两个position(每个position含有一个成员),分别是:

[[Measures].[YJD]]

[[Measures].[GCLC]]

Row轴上有三个position(每个position含有二个成员),分别是:

[[dimLX].[AlldimLXs],[dimTime].[AlldimTimes]]

[[dimLX].[AlldimLXs].[宁波—梁辉],[dimTime].[AlldimTimes]]

[[dimLX].[AlldimLXs].[同江-三亚],[dimTime].[AlldimTimes]]

切片轴上则有一个position:

[[dimStation].[AlldimStations].[宁波市]]

单元值们则放置在RolapResult中的cellInfos对象里,属CellInfoContainer接口,其中存放着CellInfo,并通过Cellkey进行索引。

CellKey:

用于在maps里访问cellinfo时使用的键值,根据cell的位置来决定键值。

CellKey共有四个默认实现,及zero、one、two、three和many版的实现,分别对应着轴的个数。

这些类中关键的属性便是存储各轴的位置值。

CellInfo、CellInfoContainer:

内部类。

CellInfo包含了一个cell所需要的所有信息(最关键的包含value值和一些formatter设置);

最终将作为构造ROlapCell对象的参数。

CellInfoContainer显然是cellInfo的容器,并使用CellKey来索引。

ROlapCell:

最终返回给jpivot的cell单元值。

2.5.4.RolapEvaluator类

最终负责在多维环境中执行mdx表达式。

该类中维护一个很重要的对象,即currentMembers,该上下文对象针对每个维度都包含了一个成员;

通过setContext方法用来设置当前维度,以开始计算当前维度组合下的表达式值。

2.5.5.关于排序

排序有单元值排序和维度成员排序两种场景,但单元值排序优先级更高,只有当单元值排序相当时,才再对成员值进行排序。

单元值排序有六种,升序、降序、打破Hierarchy升序、打破Hierarchy降序、topcount、bottomcount。

其中前四种参见:

FunUtil.SortMembers()中的方法,这是总入口,其中有BreakMemberComparator、HierarchicalMemberComparator、BreakArrayComparator、HierarchicalArrayComparator等排序器(Array包含多个member,此时相当于cell上下文环境由多个维度参与)。

对于array类排序,参见其中的publicintcompare(Member[]a1,Member[]a2)方法;

对于单member类排序,参见其中的publicintcompareInternal(Membera1,Membera2)方法。

维度成员排序似乎有三种:

按照orderKey、按照ordinary、按照值(参见RolapMpareTo()方法,最终相当于按字符串或数值比较,其中第三种内部又会用到ascending属性),这个是我们自己新增的属性。

具体参见FunUpareSiblingMembers()方法。

2.6.

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 中考

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1