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水平一定会有质的提升。

目录
相关文章
|
C# 计算机视觉
案例分享:Qt的PPT播放器
案例分享:Qt的PPT播放器
案例分享:Qt的PPT播放器
|
SpringCloudAlibaba Java Nacos
SpringBoot使用spring.config.import多种方式导入配置文件
`SpringBoot`从2.4.x版本开始支持了导入文件的方式来加载配置参数,与`spring.config.additional-location`不同的是不用提前设置而且支持导入的文件类型相对来说要丰富很多。
|
12天前
|
人工智能 自然语言处理 安全
阿里云千问办公 QwenWork详细介绍:产品核心能力、典型场景、价格及常见问题解答
千问办公是阿里云推出的一站式AI办公平台,主打"不止于对话,更注重交付",依托通义千问旗舰大模型,用户一句话即可完成数据分析、PPT生成、视频剪辑等复杂任务,直接输出可用成果。产品深度打通钉钉生态与企业OA,覆盖桌面端、网页端,提供企业标准版198元/人/月等多档订阅方案,新用户注册即赠2000积分,适配工程师、HR、财务等多职业办公场景,成为能动手干活的"全能AI同事"。
|
12天前
|
人工智能
千问办公官网入口:阿里AI办公QwenWork产品页和免费网页端链接
千问办公官网含两大入口:一是网页端(qwenwork.cn),即开即用,支持浏览器直接访问;二是阿里云产品页 https://t.aliyun.com/U/JNKJuO 提供免费/付费版详情、功能介绍及使用指南。
|
19天前
|
网络协议 Linux iOS开发
【2026实测】Wireshark下载+安装+汉化+使用教程(图文版,巨详细)
Wireshark 是一款免费开源的网络协议分析工具,可实时捕获、解析并可视化数据包,助你诊断网络故障、分析通信协议(如HTTP、DNS、TCP等)。支持Windows/macOS/Linux,含中文界面,新手入门便捷。(239字)
|
11天前
|
IDE 开发工具
Qoder 上线 Sonus 模型,Computer Use 能力全面增强
Qoder国际版上线全新内置大模型Sonus(/ˈsoʊnəs/),全球领先,专精超长任务执行与电脑操作(Computer Use)。配合Qoder桌面端0.2.3版本,可自主完成编程、金融建模、科研及表格制作等复杂工作。现全面支持Qoder全系产品,效率提升3.2倍。
1433 8
Qoder 上线 Sonus 模型,Computer Use 能力全面增强
|
14天前
|
缓存 人工智能 自然语言处理
阿里云qwen3.8-flash大模型介绍:模型能力、模型价格、免费额度与最新活动
本文是阿里云百炼平台Qwen3.8-Flash大模型的选型接入指南,作为兼顾性能与响应速度的高性价比多模态模型,它支持百万级上下文窗口、全场景多模态输入与完整智能体能力矩阵,适配编程辅助、智能体协作等核心场景。文中同步梳理了最新下调的阶梯定价、夜间4折等优惠活动,搭配OpenAI兼容流式调用示例,帮助开发者低成本快速落地高并发AI应用。
阿里云qwen3.8-flash大模型介绍:模型能力、模型价格、免费额度与最新活动
|
13天前
|
人工智能 API 内存技术
刚刚 DeepSeek V4.1 Flash 开启内测,1 分钟教你用上!
刚刚 DeepSeek 内测群发布了 DeepSeek V4.1 Flash 中间版本内测的消息,这次的模型采用了新的结构,原生支持多模态、能力更强、速度更快、且成本更低。
1988 15
|
7天前
|
缓存 IDE Java
【保姆级】Android Studio下载、安装和汉化教程(2026最新)
Android Studio 是 Google 官方推出的免费 Android 应用开发集成环境,基于 IntelliJ IDEA,内置模拟器、调试器、性能分析及 Compose 界面工具,功能全面,文档丰富,是安卓开发首选工具。(239字)
|
18天前
|
人工智能 运维 BI
阿里云千问办公QwenWork深度解析:基于Qwen3.8,六大核心能力重构企业全自动化工作流与计费选型指南
传统AI办公工具大多停留在对话问答、文档摘要、简单文案生成层面,只能完成单点碎片化任务,无法自主拆解复杂业务流程,很难串联多工具、多文档、外部业务系统完成端到端完整工作交付。很多企业在落地AI办公的时候,需要组合多款不同工具,来回切换界面,手动复制粘贴中间结果,智能化改造落地门槛居高不下。千问办公QwenWork是整合多款智能体产品能力打造的一体化企业办公智能体平台,底层基座依托Qwen3.8大模型,打通桌面端Agent、云端Agent、企业协同Agent三种运行形态,不再局限简单问答,接收业务目标之后自主拆解任务步骤,调用各类工具,处理文档、表格、浏览器自动化、数据查询,直接输出可交付的办公
1689 4