• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            不會(huì)飛的鳥

            2010年12月10日 ... 不鳥他們!!! 我要用自己開發(fā)的分布式文件系統(tǒng)、分布式調(diào)度系統(tǒng)、分布式檢索系統(tǒng), 做自己的搜索引擎?。?!大魚有大志!??! ---楊書童

            Lucene索引文件格式分析

            一、Lucene源碼實(shí)現(xiàn)分析的說(shuō)明

              通過(guò)以上對(duì)Lucene系統(tǒng)結(jié)構(gòu)的分析,我們已經(jīng)大致的清楚了Lucene 系統(tǒng)的組成,以及在Lucene系統(tǒng)之上的開發(fā)步驟。接下來(lái),我們?cè)噲D來(lái)分析Lucene項(xiàng)目(采用Lucene 1.2版本)的源碼實(shí)現(xiàn),考察其實(shí)現(xiàn)的細(xì)節(jié)。這不僅僅是我們嘗試用C++語(yǔ)言重新實(shí)現(xiàn)Lucene的必須工作,也是進(jìn)一步做Lucene開發(fā)工作的必要準(zhǔn)備。因此,這一部分所涉及到的內(nèi)容,對(duì)于Lucene上的應(yīng)用開發(fā)也是有價(jià)值的,尤其是本部分所做的文件格式分析。

              由于本文建立在我們的畢設(shè)項(xiàng)目之上,且同時(shí)我們需要實(shí)現(xiàn)cLucene項(xiàng)目,因此很遺憾的我們并沒(méi)有完全的完成Lucene的所有源碼實(shí)現(xiàn)的分析工作。接下來(lái)的部分,我們將涉及的部分為L(zhǎng)ucene文件格式分析,Lucene中的存儲(chǔ)抽象模塊分析,以及Lucene中的索引構(gòu)建邏輯模塊分析。這一部分,我們主要涉及到的是文件格式分析與存儲(chǔ)抽象模塊分析。

            二、Lucene索引文件格式

              在Lucene的web站點(diǎn)上,有關(guān)于 Lucene的文件格式的規(guī)范,其規(guī)定了Lucene的文件格式采取的存儲(chǔ)單位、組織結(jié)構(gòu)、命名規(guī)范等等內(nèi)容,但是它僅僅是一個(gè)規(guī)范說(shuō)明,并沒(méi)有從實(shí)現(xiàn)者角度來(lái)衡量這個(gè)規(guī)范的實(shí)現(xiàn)。因此,我們以下的內(nèi)容,結(jié)合了我們自己的分析與文件格式的定義規(guī)范,以期望給出一個(gè)更加清晰的文件格式說(shuō)明。具體的文檔規(guī)范可以參考后面的文獻(xiàn)2。

              首先在Lucene的文件格式中,以字節(jié)為基礎(chǔ),定義了如下的數(shù)據(jù)類型:

              表 3.1 Lucene文件格式中定義的數(shù)據(jù)類型

            數(shù)據(jù)類型 所占字節(jié)長(zhǎng)度(字節(jié)) 說(shuō)明
            Byte 1 基本數(shù)據(jù)類型,其他數(shù)據(jù)類型以此為基礎(chǔ)定義
            UInt32 4 32位無(wú)符號(hào)整數(shù),高位優(yōu)先
            UInt64 8 64位無(wú)符號(hào)整數(shù),高位優(yōu)先
            VInt 不定,最少1字節(jié) 動(dòng)態(tài)長(zhǎng)度整數(shù),每字節(jié)的最高位表明還剩多少字節(jié),每字節(jié)的低七位表明整數(shù)的值,高位優(yōu)先??梢哉J(rèn)為值可以為無(wú)限大。其示例如下
            字節(jié)1 字節(jié)2 字節(jié)3
            0 00000000

            1 00000001

            2 00000010

            127 01111111

            128 10000000 00000001
            129 10000001 00000001
            130 10000010 00000001
            16383 10000000 10000000 00000001
            16384 10000001 10000000 00000001
            16385 10000010 10000000 00000001
            Chars 不定,最少1字節(jié) 采用UTF-8編碼[20]的Unicode字符序列
            String 不定,最少2字節(jié) 由VInt和Chars組成的字符串類型,VInt表示Chars的長(zhǎng)度,Chars則表示了String的值

              以上的數(shù)據(jù)類型就是Lucene索引文件格式中用到的全部數(shù)據(jù)類型,由于它們都以字節(jié)為基礎(chǔ)定義而來(lái),因此保證了是平臺(tái)無(wú)關(guān),這也是Lucene索引文件格式平臺(tái)無(wú)關(guān)的主要原因。接下來(lái)我們看看Lucene索引文件的概念組成和結(jié)構(gòu)組成。

            Lucene索引文件格式分析

             以上就是Lucene的索引文件的概念結(jié)構(gòu)。Lucene索引index由若干段(segment)組成,每
            一段由若干的文檔(document)組成,每一個(gè)文檔由若干的域(field)組成,每一個(gè)域由若干的項(xiàng)(term)組成。項(xiàng)是最小的索引概念單位,它直接代表了一個(gè)字符串以及其在文件中的位置、出現(xiàn)次數(shù)等信息。域是一個(gè)關(guān)聯(lián)的元組,由一個(gè)域名和一個(gè)域值組成,域名是一個(gè)字串,域值是一個(gè)項(xiàng),比如將“標(biāo)題”和實(shí)際標(biāo)題的項(xiàng)組成的域。文檔是提取了某個(gè)文件中的所有信息之后的結(jié)果,這些組成了段,或者稱為一個(gè)子索引。子索引可以組合為索引,也可以合并為一個(gè)新的包含了所有合并項(xiàng)內(nèi)部元素的子索引。我們可以清楚的看出,Lucene的索引結(jié)構(gòu)在概念上即為傳統(tǒng)的倒排索引結(jié)構(gòu)[21]。
             從概念上映射到結(jié)構(gòu)中,索引被處理為一個(gè)目錄(文件夾),其中含有的所有文件即為其內(nèi)容,這些文件按照所屬的段不同分組存放,同組的文件擁有相同的文件名,不同的擴(kuò)展名。此外還有三個(gè)文件,分別用來(lái)保存所有的段的記錄、保存已刪除文件的記錄和控制讀寫的同步,它們分別是segments, deletable和lock文件,都沒(méi)有擴(kuò)展名。每個(gè)段包含一組文件,它們的文件擴(kuò)展名不同,但是文件名均為記錄在文件segments中段的名字。讓我們看如下的結(jié)構(gòu)圖3.2。Lucene索引文件格式分析

              關(guān)于圖3.2中的各個(gè)文件具體的內(nèi)部格式,在參考文獻(xiàn)3中,均可以找到詳細(xì)的說(shuō)明。接下來(lái)我們從宏觀關(guān)系上說(shuō)明一下這些文件組成。在這些宏觀上的關(guān)系理清楚之后,仔細(xì)閱讀參考文獻(xiàn)3,即可清楚的明白具體的Lucene文件格式。

              每個(gè)段的文件中,主要記錄了兩大類的信息:域集合與項(xiàng)集合。這兩個(gè)集合中所含有的文件在圖3.2中均有表明。由于索引信息是靜態(tài)存儲(chǔ)的,域集合與項(xiàng)集合中的文件組采用了一種類似的存儲(chǔ)辦法:一個(gè)小型的索引文件,運(yùn)行時(shí)載入內(nèi)存;一個(gè)對(duì)應(yīng)于索引文件的實(shí)際信息文件,可以按照索引中指示的偏移量隨機(jī)訪問(wèn);索引文件與信息文件在記錄的排列順序上存在隱式的對(duì)應(yīng)關(guān)系,即索引文件中按照“索引項(xiàng)1、索引項(xiàng)2…”排列,則信息文件則也按照“信息項(xiàng)1、信息項(xiàng)2…”排列。比如在圖3.2所示文件中,segment1.fdx與segment1.fdt之間,segment1.tii與segment1.tis、 segment1.prx、segment1.frq之間,都存在這樣的組織關(guān)系。而域集合與項(xiàng)集合之間則通過(guò)域的在域記錄文件(比如 segment1.fnm)中所記錄的域記錄號(hào)維持對(duì)應(yīng)關(guān)系,在圖3.2中segment1.fdx與segment1.tii中就是通過(guò)這種方式保持聯(lián)系。這樣,域集合和項(xiàng)集合不僅僅聯(lián)系起來(lái),而且其中的文件之間也相互聯(lián)系起來(lái)。此外,標(biāo)準(zhǔn)化因子文件和被刪除文檔文件則提供了一些程序內(nèi)部的輔助設(shè)施(標(biāo)準(zhǔn)化因子用在評(píng)分排序機(jī)制中,被刪除文檔是一種偽刪除手段)。這樣,整個(gè)段的索引信息就通過(guò)這些文檔有機(jī)的組成。

              以上所闡述的,就是 Lucene所采用的索引文件格式?;旧隙?,它是一個(gè)倒排索引,但是Lucene在文件的安排上做了一些努力,比如使用索引/信息文件的方式,從文件安排的形式上提高查找的效率。這是一種數(shù)據(jù)庫(kù)之外的處理方法,其有其優(yōu)點(diǎn)(格式平**立、速度快),也有其缺點(diǎn)(獨(dú)立性帶來(lái)的共享訪問(wèn)接口問(wèn)題等等),具體如何衡量?jī)煞N方法之間的利弊,本文這里就不討論了。

            三、一些公用的基礎(chǔ)類

              分析完索引文件格式,我們接下來(lái)應(yīng)該著手對(duì)存儲(chǔ)抽象也就是org.apache.lucenestore中的源碼做一些分析。我們先不著急分析這部分,而是分析圖2.1中基礎(chǔ)結(jié)構(gòu)封裝那一部分,因?yàn)檫@是整個(gè)系統(tǒng)的基石,然后我們?cè)谙乱徊糠衷賮?lái)分析存儲(chǔ)抽象。

              基礎(chǔ)結(jié)構(gòu)封裝,或者基礎(chǔ)類,由org.apache.lucene.util和org.apache.lucene.document兩個(gè)包組成,前者定義了一些常量和優(yōu)化過(guò)的常用的數(shù)據(jù)結(jié)構(gòu)和算法,后者則是對(duì)于文檔(document)和域(field)概念的一個(gè)類定義。以下我們用列表的方式來(lái)分析這些封裝類,指出其要點(diǎn)。

              表 3.2 基礎(chǔ)類包org.apache.lucene.util

            說(shuō)明
            Arrays 一個(gè)關(guān)于數(shù)組的排序方法的靜態(tài)類,提供了優(yōu)化的基于快排序的排序方法sort
            BitVector C/C++語(yǔ)言中位域的java實(shí)現(xiàn)品,但是加入了序列化能力
            Constants 常量靜態(tài)類,定義了一些常量
            PriorityQueue 一個(gè)優(yōu)先隊(duì)列的抽象類,用于后面實(shí)現(xiàn)各種具體的優(yōu)先隊(duì)列,提供常數(shù)時(shí)間內(nèi)的最小元素訪問(wèn)能力,內(nèi)部實(shí)現(xiàn)機(jī)制是哈析表和堆排序算法

              表 3.3 基礎(chǔ)類包org.apache.lucene.document

            說(shuō)明
            Document 是文檔概念的一個(gè)實(shí)現(xiàn)類,每個(gè)文檔包含了一個(gè)域表(fieldList),并提供了一些實(shí)用的方法,比如多種添加域的方法、返回域表的迭代器的方法
            Field 是域概念的一個(gè)實(shí)現(xiàn)類,每個(gè)域包含了一個(gè)域名和一個(gè)值,以及一些相關(guān)的屬性
            DateField 提供了一些輔助方法的靜態(tài)類,這些方法將java中Date和Time數(shù)據(jù)類型和String相互轉(zhuǎn)化

              總的來(lái)說(shuō),這兩個(gè)基礎(chǔ)類包中含有的類都比較簡(jiǎn)單,通過(guò)閱讀源代碼,可以很容易的理解,因此這里不作過(guò)多的展開。

            四、存儲(chǔ)抽象

              有了上面的知識(shí),我們接下來(lái)來(lái)分析存儲(chǔ)抽象部分,也就是org.apache.lucene.store包。存儲(chǔ)抽象是唯一能夠直接對(duì)索引文件存取的包,因此其主要目的是抽象出和平臺(tái)文件系統(tǒng)無(wú)關(guān)的存儲(chǔ)抽象,提供諸如目錄服務(wù)(增、刪文件)、輸入流和輸出流。在分析其實(shí)現(xiàn)之前,首先我們看一下UML [22]圖。

            Lucene索引文件格式分析

              圖 3.3 存儲(chǔ)抽象實(shí)現(xiàn)UML圖(一)

            Lucene索引文件格式分析

              圖 3.4 存儲(chǔ)抽象實(shí)現(xiàn)UML圖(二)

            Lucene索引文件格式分析

              圖 3.4 存儲(chǔ)抽象實(shí)現(xiàn)UML圖(三)

              圖3.2到3.4展示了整個(gè)org.apache.lucene.store中主要的繼承體系。共有三個(gè)抽象類定義:Directory、 InputStream和OutputStrem,構(gòu)成了一個(gè)完整的基于抽象文件系統(tǒng)的存取體系結(jié)構(gòu),在此基礎(chǔ)上,實(shí)作出了兩個(gè)實(shí)現(xiàn)品:(FSDirectory,F(xiàn)SInputStream,F(xiàn)SOutputStream)和(RAMDirectory,RAMInputStream和 RAMOutputStream)。前者是以實(shí)際的文件系統(tǒng)做為基礎(chǔ)實(shí)現(xiàn)的,后者則是建立在內(nèi)存中的虛擬文件系統(tǒng)。前者主要用來(lái)永久的保存索引文件,后者的作用則在于索引操作時(shí)是在內(nèi)存中建立小的索引,然后一次性的輸出合并到文件中去,這一點(diǎn)我們?cè)诤竺娴乃饕壿嫴糠帜軌蚩吹健4送?,還定以了 org.apache.lucene.store.lock和org.apache.lucene.store.with兩個(gè)輔助內(nèi)部實(shí)現(xiàn)的類用在實(shí)現(xiàn) Directory方法的makeLock的時(shí)候,以在鎖定索引讀寫之前來(lái)讓客戶程序做一些準(zhǔn)備工作。

             ?。‵SDirectory, FSInputStream,F(xiàn)SOutputStream)的內(nèi)部實(shí)現(xiàn)依托于java語(yǔ)言中的io類庫(kù),只是簡(jiǎn)單的做了一個(gè)外部邏輯的包裝。這當(dāng)然要?dú)w功于java語(yǔ)言所提供的跨平臺(tái)特性,同時(shí)也帶了一些隱患:文件存取的效率提升需要依耐于文件類庫(kù)的優(yōu)化。如果需要繼續(xù)優(yōu)化文件存取的效率,應(yīng)該還提供一個(gè)文件與目錄的抽象,以根據(jù)各種文件系統(tǒng)或者文件類型來(lái)提供一個(gè)優(yōu)化的機(jī)會(huì)。當(dāng)然,這是應(yīng)用開發(fā)者所不需要關(guān)系的問(wèn)題。

              (RAMDirectory,RAMInputStream和RAMOutputStream)的內(nèi)部實(shí)現(xiàn)就比較直接了,直接采用了虛擬的文件 RAMFile類(定義于文件RAMDirectory.java中)來(lái)表示文件,目錄則看作一個(gè)String與RAMFile對(duì)應(yīng)的關(guān)聯(lián)數(shù)組。 RAMFile中采用數(shù)組來(lái)表示文件的存儲(chǔ)空間。在此的基礎(chǔ)上,完成各項(xiàng)操作的實(shí)現(xiàn),就形成了基于內(nèi)存的虛擬文件系統(tǒng)。因?yàn)樵趯?shí)際使用時(shí),并不會(huì)牽涉到很大字節(jié)數(shù)量的文件,因此這種設(shè)計(jì)是簡(jiǎn)單直接的,也是高效率的。

              這部分的實(shí)現(xiàn)在理清楚繼承體系后,相當(dāng)?shù)暮?jiǎn)單。因此接下來(lái)的部分,我們可以通過(guò)直接閱讀源代碼解決。接下來(lái)我們看看這個(gè)部分的源代碼如何在實(shí)際中使用的。

              一般來(lái)說(shuō),我們使用的是抽象類提供的接口而不是實(shí)際的實(shí)現(xiàn)類本身。在實(shí)現(xiàn)類中一般都含有幾個(gè)靜態(tài)函數(shù),比如createFile,它能夠返回一個(gè) OutputStream接口,或者openFile,它能夠返回一個(gè)InputStream接口,利用這些接口之中的方法,比如 writeString,writeByte等等,我們就能夠在抽象的層次上處理Lucene定義的數(shù)據(jù)類型的讀寫。簡(jiǎn)單的說(shuō),Lucene中存儲(chǔ)抽象這部分設(shè)計(jì)時(shí)采用了工廠模式(Factory parttern)[23]。我們利用靜態(tài)類的方法也就是工廠來(lái)創(chuàng)建對(duì)象,返回接口,通過(guò)接口來(lái)執(zhí)行操作。

            五、關(guān)于cLucene項(xiàng)目

              這一部分詳細(xì)的說(shuō)明了Lucene系統(tǒng)中所采用的索引文件格式、一些基礎(chǔ)類和存儲(chǔ)抽象。接下來(lái)我們來(lái)敘述一下我們?cè)陧?xiàng)目cLucene中重新實(shí)現(xiàn)這些結(jié)構(gòu)時(shí)候的一些考慮。

              cLucene徹底的遵守了Lucene所定義的索引文件格式,這是Lucene對(duì)于各個(gè)兼容系統(tǒng)的基本要求。在此基礎(chǔ)上,cLucene系統(tǒng)和Lucene系統(tǒng)才能夠共享索引文件數(shù)據(jù)?;蛘哒f(shuō),cLucene生成的索引文件和Lucene生成的索引文件完全等價(jià)。

              在基礎(chǔ)類問(wèn)題上,cLucene同樣封裝了類似的結(jié)構(gòu)。我們同樣列表描述,請(qǐng)和前面的表3.2與3.3對(duì)照比較。

              表 3.4 基礎(chǔ)類包c(diǎn)Lucene::util

            說(shuō)明
            Arrays 沒(méi)有實(shí)現(xiàn),直接利用了STL庫(kù)中的快排序算法實(shí)現(xiàn)
            BitVector C/C++語(yǔ)言版本的實(shí)現(xiàn),與java實(shí)現(xiàn)版本類似
            Constants 常量靜態(tài)類,定義了一些常量,但是與java版本不同的是,這里主要定義了一些宏
            PriorityQueue 這是一個(gè)類型定義,直接利用STL庫(kù)中的std::priority_queue

              表 3.3 基礎(chǔ)類包c(diǎn)Lucene::document

            說(shuō)明
            Document C/C++語(yǔ)言版本的實(shí)現(xiàn),與java實(shí)現(xiàn)版本類似
            Field C/C++語(yǔ)言版本的實(shí)現(xiàn),與java實(shí)現(xiàn)版本類似
            DateField 沒(méi)有實(shí)現(xiàn),直接利用OpenTop庫(kù)中的ot::StringUtil

              存儲(chǔ)抽象的實(shí)現(xiàn)上,也同樣是類似于java實(shí)現(xiàn)。由于我們采用了OpenTop庫(kù),因此同樣得以借助其中對(duì)于文件系統(tǒng)抽象的ot::io包來(lái)解決文件系統(tǒng)問(wèn)題。這部分問(wèn)題與前面一樣,存在優(yōu)化的可能。在實(shí)現(xiàn)的類層次上、對(duì)外接口上,均與java版本的一樣。

            posted on 2008-11-25 16:49 不會(huì)飛的鳥 閱讀(718) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            国产精品久久婷婷六月丁香| 久久精品国产一区二区| 2021精品国产综合久久| 99久久国产免费福利| 一本久久精品一区二区| 久久国产乱子伦免费精品| 久久精品国产99久久丝袜| 中文字幕日本人妻久久久免费 | 91麻豆国产精品91久久久| 久久黄色视频| 老色鬼久久亚洲AV综合| 久久九九免费高清视频| 久久国产亚洲精品麻豆| 久久久久久精品免费免费自慰| 精品久久久久久亚洲精品 | 青青草原综合久久大伊人导航| 亚洲伊人久久大香线蕉综合图片| 色综合久久最新中文字幕| 亚洲国产精品婷婷久久| 无码伊人66久久大杳蕉网站谷歌| 无码任你躁久久久久久久| 国内精品伊人久久久久| 国内精品久久久久久99| 久久午夜无码鲁丝片秋霞| 久久亚洲精品无码观看不卡| 伊人热人久久中文字幕| a高清免费毛片久久| 人妻精品久久无码专区精东影业 | 人妻丰满AV无码久久不卡 | 精品午夜久久福利大片| 亚洲中文字幕无码久久2017| 亚洲欧洲精品成人久久奇米网 | 久久综合九色综合精品| 精品久久久久久久国产潘金莲| 久久久久久久精品成人热色戒| 久久无码精品一区二区三区| 国产免费久久久久久无码| 国产成人精品综合久久久| 久久91这里精品国产2020| 91精品国产91久久久久久青草 | 久久人人爽人爽人人爽av|