一: Hugegraph 源代碼 : HugeGraph對象

hugraph對象為百度的開源圖數(shù)據(jù)庫,實現(xiàn)了Tinkerpop框架,本系列解讀 hugegraph-core 的開源代碼,加深圖數(shù)據(jù)的理解。

hugeraph項目 提供了 api 功能桶良,用戶可以調(diào)用 api 添加節(jié)點,本文就以 這個 增加節(jié)點的api為起點沮翔,一步一步講解 hugegraph是如何實現(xiàn)的陨帆。

addVertex 作為 api 的入口

    @POST
    @Timed
    @Status(Status.CREATED)
    @Consumes(APPLICATION_JSON)
    @Produces(APPLICATION_JSON_WITH_CHARSET)
    public String create(@Context GraphManager manager,
                         @PathParam("graph") String graph,
                         JsonVertex jsonVertex) {
        LOG.debug("Graph [{}] create vertex: {}", graph, jsonVertex);
        checkCreatingBody(jsonVertex);

        HugeGraph g = graph(manager, graph);
        Vertex vertex = commit(g, () -> g.addVertex(jsonVertex.properties()));

        return manager.serializer(g).writeVertex(vertex);
    }

可以看到 所有的起點就是需要 創(chuàng)建一個 HugeGraph對象,Hugegraph 對象里面 包含了 addVertex 方法采蚀。
本文就重點講解 HugeGraph是如何創(chuàng)建的
graph(manager, graph)

    public static HugeGraph graph(GraphManager manager, String graph) {
        HugeGraph g = manager.graph(graph);
        if (g == null) {
            throw new NotFoundException(String.format(
                      "Graph '%s' does not exist",  graph));
        }
        return g;
    }
實際是使用graphManager的map疲牵,根據(jù) graph名字獲取對象。
那么graphManager 是關(guān)鍵對象

構(gòu)建GraphManager

hugegraph 使用GraphManager直接獲取HugeGraph對象   
對于GraphManger對象

    private final Map<String, Graph> graphs;
    private final HugeAuthenticator authenticator;

    public GraphManager(HugeConfig conf) {
        this.graphs = new ConcurrentHashMap<>();

        if (conf.get(ServerOptions.AUTHENTICATOR).isEmpty()) {
            this.authenticator = null;
        } else {
            this.authenticator = HugeAuthenticator.loadAuthenticator(conf);
        }

        this.loadGraphs(conf.getMap(ServerOptions.GRAPHS));
        this.checkBackendVersionOrExit();
        this.restoreUncompletedTasks();
        this.addMetrics(conf);
    }

由于hugegraph是支持多圖的搏存,所有有GrappManager保存一個 多圖的引用map瑰步。
在構(gòu)建GraphManager對象的時候
最重要的一步是
this.loadGraphs(conf.getMap(ServerOptions.GRAPHS));

    private void loadGraph(String name, String path) {
        final Graph graph = GraphFactory.open(path);
        this.graphs.put(name, graph);
        LOG.info("Graph '{}' was successfully configured via '{}'", name, path);

        if (this.requireAuthentication() &&
            !(graph instanceof HugeGraphAuthProxy)) {
            LOG.warn("You may need to support access control for '{}' with {}",
                     path, HugeFactoryAuthProxy.GRAPH_FACTORY);
        }
    }

可以看到  關(guān)鍵的一句 final Graph graph = GraphFactory.open(path);
這個 Graph 和GraphFactory 都是 tinkerpop的標(biāo)準(zhǔn)接口。
path參數(shù)就是 我們的圖的配置文件璧眠,默認(rèn)是 conf/hugegraph.properties.

在配置文件中 (conf/hugegraph.propreties)我們有一行: 
gremlin.graph=com.baidu.hugegraph.HugeFactory
這一行指定了具體創(chuàng)建圖的 工廠類缩焦,查看 HugeFactory 的open方法:

    public static synchronized HugeGraph open(Configuration config) {
        HugeConfig conf = new HugeConfig(config);
        String name = conf.get(CoreOptions.STORE);
        HugeGraph graph = graphs.get(name);
        if (graph == null || graph.closed()) {
            graph = new HugeGraph(conf);
            graphs.put(name, graph);
        } else {
            String backend = conf.get(CoreOptions.BACKEND);
            E.checkState(backend.equals(graph.backend()),
                         "Graph name '%s' has been used by backend '%s'",
                         name, graph.backend());
        }
        return graph;
    }

這里面 調(diào)用了 HugeGraph的 構(gòu)造方法 
graph = new HugeGraph(conf);

下面看看 HugeGraph 到底是如何構(gòu)造的?

構(gòu)建 HugeGraph 對象

    public HugeGraph(HugeConfig configuration) {
        this.configuration = configuration;

        this.schemaEventHub = new EventHub("schema");
        this.indexEventHub = new EventHub("index");

        final int limit = configuration.get(CoreOptions.RATE_LIMIT);
        this.rateLimiter = limit > 0 ? RateLimiter.create(limit) : null;

        this.taskManager = TaskManager.instance();

        this.features = new HugeFeatures(this, true);

        this.name = configuration.get(CoreOptions.STORE);
        this.closed = false;
        this.mode = GraphMode.NONE;

        LockUtil.init(this.name);

        try {
            this.storeProvider = this.loadStoreProvider();
        } catch (BackendException e) {
            String message = "Failed to init backend store";
            LOG.error("{}: {}", message, e.getMessage());
            throw new HugeException(message);
        }

        this.tx = new TinkerpopTransaction(this);

        this.taskManager.addScheduler(this);

        this.variables = null;
    }

- rateLimiter  設(shè)置hugegraph 增刪改查的節(jié)點速度
- features   設(shè)置hugegraph 對于tinkerpop的特性支持责静,目前hugegraph是對tinkerpop的一個標(biāo)準(zhǔn)子集
- LockUtil.init(this.name)  初始化圖上的鎖袁滥,對于圖的操作有很多需要異步加鎖的地方,鎖機制后面專門講解
-   this.storeProvider = this.loadStoreProvider() 加載 存儲模塊灾螃。hugegraph支持多種存儲終端题翻,在這里根據(jù)配置信息初始化存儲終端
- 設(shè)置對應(yīng)的事務(wù)對象  this.tx = new TinkerpopTransaction(this);

初始化 storeProvider

    private BackendStoreProvider loadStoreProvider() {
        String backend = this.configuration.get(CoreOptions.BACKEND);
        LOG.info("Opening backend store '{}' for graph '{}'",
                 backend, this.name);
        return BackendProviderFactory.open(backend, this.name);
    }

調(diào)用 BackendProviderFactory.open(backend, this.name) 方法

    public static BackendStoreProvider open(String backend, String graph) {
        if (InMemoryDBStoreProvider.matchType(backend)) {
            return InMemoryDBStoreProvider.instance(graph);
        }

        Class<? extends BackendStoreProvider> clazz = providers.get(backend);
        BackendException.check(clazz != null,
                               "Not exists BackendStoreProvider: %s", backend);

        assert BackendStoreProvider.class.isAssignableFrom(clazz);
        BackendStoreProvider instance = null;
        try {
            instance = clazz.newInstance();
        } catch (Exception e) {
            throw new BackendException(e);
        }

        BackendException.check(backend.equalsIgnoreCase(instance.type()),
                               "BackendStoreProvider with type '%s' " +
                               "can't be opened by key '%s'",
                               instance.type(), backend);

        instance.open(graph);
        return instance;
    }

使用反射的方法 獲取 BackendStoreProvider  對象, 對于 hugegraph 提供了多個 provider腰鬼,
根據(jù)配置信息獲取具體的Provider嵌赠。

看下在哪里配置了不同的provider?
hugegraph 有一個子module熄赡, hugegraph-dist姜挺, 這里面有相應(yīng)的配置信息

下面代碼來自 RegisterUtil

    public static void registerCassandra() {
        // Register config
        OptionSpace.register("cassandra",
                "com.baidu.hugegraph.backend.store.cassandra.CassandraOptions");
        // Register serializer
        SerializerFactory.register("cassandra",
                "com.baidu.hugegraph.backend.store.cassandra.CassandraSerializer");
        // Register backend
        BackendProviderFactory.register("cassandra",
                "com.baidu.hugegraph.backend.store.cassandra.CassandraStoreProvider");
    }

初始化 transcation

this.tx = new TinkerpopTransaction(this);

TinkerpopTransaction 繼承自 tinkerpop 的抽象類  AbstractThreadLocalTransaction ,
該抽象類實現(xiàn)了 tinkerpop的 Transaction 接口彼硫,定了以tinkerpop的事務(wù)標(biāo)準(zhǔn)炊豪。

從TinkerpopTransaction 來看凌箕, hugegraph 定義了 GraphTransaction 和schemaTransaction

    private class TinkerpopTransaction extends AbstractThreadLocalTransaction {

        private AtomicInteger refs;

        private ThreadLocal<Boolean> opened;

        // Backend transactions
        private ThreadLocal<GraphTransaction> graphTransaction;
        private ThreadLocal<SchemaTransaction> schemaTransaction;

        private SchemaTransaction schemaTransaction() {
            /*
             * NOTE: this method may be called even tx is not opened,
             * the reason is for reusing backend tx.
             * so we don't call this.verifyOpened() here.
             */

            SchemaTransaction schemaTx = this.schemaTransaction.get();
            if (schemaTx == null) {
                schemaTx = openSchemaTransaction();
                this.schemaTransaction.set(schemaTx);
            }
            return schemaTx;
        }

        private GraphTransaction graphTransaction() {
            /*
             * NOTE: this method may be called even tx is not opened,
             * the reason is for reusing backend tx.
             * so we don't call this.verifyOpened() here.
             */

            GraphTransaction graphTx = this.graphTransaction.get();
            if (graphTx == null) {
                graphTx = openGraphTransaction();
                this.graphTransaction.set(graphTx);
            }
            return graphTx;
        }

實際通過 openGraphTransaction()  和  openSchemaTransaction(); 來創(chuàng)建事務(wù)對象。
hugegraph 的 addvertex  以及 對schema 的修改都是通過 這兩個對象的接口實現(xiàn)词渤。

對于 hugegraph 的事務(wù)管理牵舱,將在下一章重點接收。
到目前為止缺虐,  hugegraph對象就創(chuàng)建好了芜壁,接口以使用相應(yīng)的方法。
請看下回分解志笼。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末沿盅,一起剝皮案震驚了整個濱河市把篓,隨后出現(xiàn)的幾起案子纫溃,更是在濱河造成了極大的恐慌,老刑警劉巖韧掩,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件紊浩,死亡現(xiàn)場離奇詭異,居然都是意外死亡疗锐,警方通過查閱死者的電腦和手機坊谁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來滑臊,“玉大人口芍,你說我怎么就攤上這事」途恚” “怎么了鬓椭?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長关划。 經(jīng)常有香客問我小染,道長,這世上最難降的妖魔是什么贮折? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任裤翩,我火速辦了婚禮,結(jié)果婚禮上调榄,老公的妹妹穿的比我還像新娘踊赠。我一直安慰自己,他們只是感情好每庆,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布扣孟。 她就那樣靜靜地躺著,像睡著了一般鸽斟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上剩燥,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天灭红,我揣著相機與錄音变擒,去河邊找鬼寝志。 笑死材部,一個胖子當(dāng)著我的面吹牛乐导,可吹牛的內(nèi)容都是我干的苦丁。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼旺拉,長吁一口氣:“原來是場噩夢啊……” “哼鹦聪!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起泽本,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤规丽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后冰抢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體艘狭,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年尽超,在試婚紗的時候發(fā)現(xiàn)自己被綠了似谁。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片巩踏。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡塞琼,死狀恐怖目代,靈堂內(nèi)的尸體忽然破棺而出榛了,到底是詐尸還是另有隱情煞抬,我是刑警寧澤革答,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布战坤,位于F島的核電站,受9級特大地震影響残拐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜溪食,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望错沃。 院中可真熱鬧,春花似錦枢析、人聲如沸玉掸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽司浪。三九已至,卻和暖如春啊易,著一層夾襖步出監(jiān)牢的瞬間认罩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工劫拗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留间校,地道東北人。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓酒繁,卻偏偏與公主長得像滓彰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子州袒,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,097評論 1 32
  • 昨天去玩揭绑,看到鏡頭里的自己,很生氣郎哭,很傷心——怎么到處都是圓的 我看到我的肉他匪,不開森,那個曾經(jīng)風(fēng)一樣的少年呢夸研?怎么...
    金剛心農(nóng)場夢想沙盤閱讀 149評論 0 2
  • 現(xiàn)代人什么都很急亥至,很浮躁悼沈。急著去戀愛,急著去證明愛或不愛抬闯,再急著分手井辆。 很多年前有一個女同事,年紀(jì)不小溶握,其貌不揚杯缺,...
    愛U閱讀 334評論 0 0
  • 思想:今兒情緒高漲的給大家買了早餐,一起布置了大廳睡榆,雖然沒有很好萍肆,但是基本滿足了一個不錯的營業(yè)環(huán)境∨塾埽現(xiàn)在客戶的角度...
    小雙雙_18c5閱讀 131評論 0 0
  • 一天,小兔子出來散步塘揣,它走河邊突然聽到咕咚的聲音包雀,嚇的它拔腿就跑,一邊跑一邊叫:“咕咚來了亲铡,大家快逃命啊...
    w小亦閱讀 496評論 0 0