titan0.1源码研究(1)

简介: 为什么是titan0.1?因为代码量小,后面的代码都是从0.1发展来的,代码量是增加了,但是代码结构基本没变。titan-0.1有3万多行代码,而且还没有弄成maven的多模块。用来学习正好。等熟悉了再跟后面的版本比对,看看哪些地方更新了。

为什么是titan0.1?因为代码量小,后面的代码都是从0.1发展来的,代码量是增加了,但是代码结构基本没变。
titan-0.1有3万多行代码,而且还没有弄成maven的多模块。用来学习正好。等熟悉了再跟后面的版本比对,看看哪些地方更新了。

titan是一个图数据库,没有自己的存储后端,需要安装hbase,cassandra等数据库。我们使用cassandra。
下载cassandra-1.1.3.tar.gz。解压后,配置一个Cassandra_HOME环境变量,然后启动它:

cd $CASSANDRA_HOME\bin
cassandra 

先来看一个小demo吧,稍微熟悉一下titan。
注意titan0.1要想遍历结点的话,必须要建索引:
把源码test模块下的TitanTestBed修改成这样:

Configuration conf = new BaseConfiguration();
conf.setProperty("storage.backend","cassandra");
conf.setProperty("storage.hostname","127.0.0.1");
TitanGraph g = TitanFactory.open(conf);
// 给titan的vertex的name2属性建一个索引。
g.createKeyIndex("name2", Vertex.class);
// 新建一个结点,手动给结点的id赋值
Vertex v = g.addVertex(1);
v.setProperty("name2", "zhangsan");
// 如果上面没有建索引,这句会报错:java.lang.UnsupportedOperationException: The configured storage backend does not support global graph operations - use Faunus instead
// 参考这里: https://groups.google.com/forum/#!topic/aureliusgraphs/jU6-Yyxm9F4
System.out.println(g.getVertices("name2", "zhangsan").iterator().next().getId());
System.out.println(g.getVertex(1).getProperty("name"));
g.stopTransaction(Conclusion.SUCCESS);
g.shutdown();

好,正式开始。代码太多了,从哪儿下手呢?
一看readme.md文件。哦,内容比较少,没有什么干货。
二看包名,有5个大包:core, diskstorage, graphdb, tinkerpop, util。先看core包。
三看接口。core包里一共有15个接口。在eclipse选择类名,按F4会显示这个接口的继承关系及接口里的方法。

titan遵守tinkerpop规范,所以,必定会实现blueprints(新版本叫gremlin structure)里的接口。
在实现blueprints的接口之前,titan自己定义了一些接口。这些接口继承了blueprints的接口。
这样有一个好处,以后扩展的时候只需要修改自己的接口就行了,blueprints里的不用动。

core包的15个接口:
core15_

我们知道图有两个要素,结点和边。
titan是这样抽象的:

最顶层的接口叫TitanElement
TitanElement_

这是所有元素都需要用到的方法。

然后InternalElement和TitanVertex两个接口继承了TitanElement。
InternalElement接口里只有一个方法setID。似乎这个接口并没有什么用。 这个暂时不用管,以后我们再好好研究一下它。因为源码里凡是以Internal开头的接口,代码里都没有注释,所以先不管它。

TitanVertex很明显是操作vertex用到的接口。于是乎我们猜测,代码里一定会有一个操作边的接口叫TitanEdge。
不好意思猜错了。没有一个接口叫TitanEdge的,只有一个TitanRelation。

为什么要这样安排?来看一下TitanVertex的继承关系。
TitanVertex_

因为vertex和edge的属性都有键(key),vertex和edge本身都有标签(label)。所以将key和label抽象成TitanType,这样以后不管是结点还是边,都可以用这个父类接口了。

因为vertex不仅有属性(property),同时还有边的信息。将属性和边抽象成TitanRelation。这样以后不管是addProperty还是addEdge,都可以用这个父类接口了。

因为都跟vertex有关。所以TitanType和TitanRelation继承了TitanVertex。虽然乍一看有点怪,不过非常合理。

blueprints的Vertex接口里只有3个方法getEdges,getVertices,query。
TitanVertex:继承了blueprints的Vertex接口。
但是显然方法还是太少了,所以TitanVertex里又添加了许多方法,见上图。

这些方法就够了吗?当然不够。
TitanRelation里增加了getDirection, getType, isDirected, isEdge, isIncidentOn, isLoop, isModifiable, isProperty, isSimple, isUndirected, isUnidirected(对跟左边的方法就一字之差)
TitanEdge里增加了 getOtherVertex, getTitanLabel, getVertex 3个方法。
TitanProperty里增加了getAttribute, getPropertyKey, getVertex 3个方法。

TitanType里增加了getGroup, getName, isEdgeLabel, isFunctional, isModifiable, isPropertyKey, isSimple
TitanKey里增加了 getDataType, hasIndex, isUnique 3个方法。
TitanLabel增加了 isDirected, isUndirected, isUnidirected 3个方法。

不要觉得烦,这就是软件设计里的接口隔离原则。弄成一个个小的接口,一点一点的增加方法。

以Titan开头的8个接口就定出了titan基本元素的框架。core包里还有7个接口,分别是:
AttributeSerializer,DefaultTypeMaker,TitanGraph,TitanQuery,TitanTransaction,TypeMaker,VertexList

TitanQuery:毫无疑问,继承了blueprints的Query接口。blueprints Query接口只有9个方法。
count, direction, edges, has, interval, labels, limit, vertexIds, vertices。
TitanQuery增加了很多方法:
clone, count, directon, edges, group, has, inMemory, interval, keys, labels, limit, onlyModifiable, properties, propertyCount, relations, titanEdges, types, vertexIds.
这里虽然有些方法在父类接口里已经有了,不过没关系。 java接口里的方法都是抽象的。实现类只要实现了抽象方法就行。反正方法签名都是一样的,虽然父类接口和子类接口都有声明,编译器只会加载一次,所以不会有问题。

TitanTransaction:继承了blueprints的TransactionalGraph和KeyIndexableGraph两个接口。
TransactionalGraph接口里只有 shutdown, stopTransaction 2个方法。
KeyIndexableGraph 接口里只有 createKeyIndex, dropKeyIndex, getIndexedKeys 3个方法。
TitanTransaction 增加了很多方法:
abort, addEdge, addProperty, addVertex, commit, containsType, containsVertex, getEdgeLabel, getPropertyKey
getType, getVertex, getVertices, hasModifications, isClosed, isOpen, makeType, query

咦很多方法前面出现过了对不对? 比如addProperty, addEdge, getVertices。 是的,这些方法有一个要求,都要传入vertex对象,所以最后调用的还是vertex的方法,而不会是tx的。

VertexList:继承了java里的Iterable接口,遍历的时候要用到这个接口。有5个方法: get, getID, getIDs, size, sort
AttributeSerializer:为attribute的值序列化用的,允许用户自定义序列化器。只有read, writeObjectData两个方法。

TypeMaker:TitanType的工厂。TitanType可以被配置用来提高数据校验,更好的存储效率和更高的性能。 TitanType给某个类型所有的TitanRelation定义schema。
有这些方法: dataType, directed, functional, group, indexed, makeEdgeLabel, makePropertyKey, name, primaryKey, signature, simple,
undirected, unidirected, unique
用户可以用com.thinkaurelius.titan.core.TitanTransaction#makeType()自定义一个类型。

DefaultTypeMaker:当graph被配置成 边label和属性的key第一次被使用时自动创建边label和属性的key。分别使用DefaultTypeMaker实现类的makeLabel(String, TypeMaker)
或者makeKey(String, TypeMaker)来定义他们。 也可以自定义一个DefaultTypeMaker的实现类,该类指明了默认情况下这些类型是如何被定义的。
在配置里使用全路径指明实现类。

TitanGraph:继承了blueprints的Graph, KeyIndexableGraph, ThreadedTransactionalGraph 3个接口。 哦,人家blueprints也是接口隔离的。
Graph:addEdge, addVertex, getEdge, getEdges, getFeatures, getVertex, getVertices, removeEdge, removeVertex, shutdown。

KeyIndexableGraph:createKeyIndex, dropKeyIndex, getIndexedKeys

ThreadedTransactionalGraph: startTransaction

嗯,TitanGraph把vertex, edge, tx, serializer都封装起来了。我们大概知道titan要做哪些事了:

打开数据库,开启事务,构造vertex和edge,将数据序列化一下,然后将序列化后的数据提交到存储后端(hbase, cassandra等)。

这里最难的是事务。titan没有自己的存储后端,它是一个图数据层。
BigTable是很好,可惜就是没有原生地提供事务支持,所以titan自己实现了一个分布式事务。

本次收获:面向接口编程,接口隔离,接口继承。

titan源码有太多太多值得我们学习的地方:
设计模式,线程安全,maven多模块,maven各种插件的使用,单元测试,持续集成等。把这个项目研究好了,Java水平一定会有质的提升。

目录
相关文章
|
13天前
|
机器学习/深度学习 编解码 异构计算
4090笔记本0.37秒直出大片!英伟达联手MIT清华祭出Sana架构,速度秒杀FLUX
英伟达、麻省理工学院与清华大学联合发布Sana,一款高效文本到图像生成框架。Sana通过深度压缩自编码器和线性注意力机制,实现快速高分辨率图像生成,生成1024×1024图像仅需不到1秒。此外,Sana采用解码器专用文本编码器增强文本与图像对齐度,大幅提高生成质量和效率。相比现有模型,Sana体积更小、速度更快,适用于多种设备。
26 7
|
3月前
|
机器学习/深度学习 并行计算 计算机视觉
CUDA:王者之巅——探究CUDA为何能成为并行计算的佼佼者
本文探讨了CUDA在并行计算领域的崛起及其成为佼佼者的原因,详细介绍了CUDA的技术背景、架构原理及在深度学习、图像处理等领域的应用案例,展示了其显著的性能优势与优化方法,并展望了CUDA在未来计算技术发展中的潜力与方向。
|
7月前
GPTs每日推荐--生化危机【典藏版】
GPTs每日推荐--生化危机【典藏版】
45 1
|
机器学习/深度学习 缓存 分布式计算
Transformer取代者登场!微软、清华刚推出RetNet:成本低、速度快、性能强
Transformer取代者登场!微软、清华刚推出RetNet:成本低、速度快、性能强
127 0
Transformer取代者登场!微软、清华刚推出RetNet:成本低、速度快、性能强
|
机器学习/深度学习 人工智能 数据安全/隐私保护
昇思MindSpore安装教程
昇思MindSpore安装教程
307 0
|
人工智能 并行计算 架构师
CUDA编程模型都改了!英伟达架构师团队撰文详解:Hopper为啥这么牛?
CUDA编程模型都改了!英伟达架构师团队撰文详解:Hopper为啥这么牛?
366 0
|
架构师 Serverless 程序员
Forrester Wave™ 扫盲贴
Forrester Wave™ 是为考虑采购技术解决方案的买方提供的专业参考调研报告,面向成熟技术市场。
2217 11
Forrester Wave™ 扫盲贴
|
机器学习/深度学习 人工智能 分布式计算
一万亿模型要来了?谷歌大脑和DeepMind联手发布分布式训练框架Launchpad
AI模型进入大数据时代,单机早已不能满足训练模型的要求,最近Google Brain和DeepMind联手发布了一个可以分布式训练模型的框架Launchpad,堪称AI界的MapReduce。
269 0
一万亿模型要来了?谷歌大脑和DeepMind联手发布分布式训练框架Launchpad
|
人工智能 并行计算 自动驾驶
英伟达或推出没有光线追踪的新款图灵架构GPU,这里有几个猜想
过去几个月有关于英伟达准备推出没有即时光线追踪功能的图灵架构GPU的传言,近期也有相关的报道,这背后可能的原因有哪些?
497 0