• <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>

            不會飛的鳥

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

            Lucene索引文件格式分析

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

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

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

            二、Lucene索引文件格式

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

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

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

            數(shù)據(jù)類型 所占字節(jié)長度(字節(jié)) 說明
            Byte 1 基本數(shù)據(jù)類型,其他數(shù)據(jù)類型以此為基礎(chǔ)定義
            UInt32 4 32位無符號整數(shù),高位優(yōu)先
            UInt64 8 64位無符號整數(shù),高位優(yōu)先
            VInt 不定,最少1字節(jié) 動態(tài)長度整數(shù),每字節(jié)的最高位表明還剩多少字節(jié),每字節(jié)的低七位表明整數(shù)的值,高位優(yōu)先??梢哉J(rèn)為值可以為無限大。其示例如下
            字節(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的長度,Chars則表示了String的值

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

            Lucene索引文件格式分析

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

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

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

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

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

              分析完索引文件格式,我們接下來應(yīng)該著手對存儲抽象也就是org.apache.lucenestore中的源碼做一些分析。我們先不著急分析這部分,而是分析圖2.1中基礎(chǔ)結(jié)構(gòu)封裝那一部分,因為這是整個系統(tǒng)的基石,然后我們在下一部分再來分析存儲抽象。

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

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

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

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

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

              總的來說,這兩個基礎(chǔ)類包中含有的類都比較簡單,通過閱讀源代碼,可以很容易的理解,因此這里不作過多的展開。

            四、存儲抽象

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

            Lucene索引文件格式分析

              圖 3.3 存儲抽象實現(xiàn)UML圖(一)

            Lucene索引文件格式分析

              圖 3.4 存儲抽象實現(xiàn)UML圖(二)

            Lucene索引文件格式分析

              圖 3.4 存儲抽象實現(xiàn)UML圖(三)

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

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

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

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

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

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

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

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

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

              表 3.4 基礎(chǔ)類包cLucene::util

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

              表 3.3 基礎(chǔ)類包cLucene::document

            說明
            Document C/C++語言版本的實現(xiàn),與java實現(xiàn)版本類似
            Field C/C++語言版本的實現(xiàn),與java實現(xiàn)版本類似
            DateField 沒有實現(xiàn),直接利用OpenTop庫中的ot::StringUtil

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

            posted on 2008-11-25 16:49 不會飛的鳥 閱讀(727) 評論(0)  編輯 收藏 引用

            99精品国产综合久久久久五月天| 国内精品久久久久久中文字幕| 无码人妻久久一区二区三区 | 久久久久se色偷偷亚洲精品av| 亚洲精品国产自在久久| 亚洲va久久久噜噜噜久久男同| 国产精品久久久久久久久免费| 欧美一级久久久久久久大| 午夜人妻久久久久久久久| 精品无码久久久久久国产| 中文无码久久精品| 久久97久久97精品免视看| 久久精品国产亚洲AV蜜臀色欲| 国产L精品国产亚洲区久久| 亚洲色欲久久久综合网东京热| 久久精品国产国产精品四凭| 精品久久久久久久无码| 亚洲精品无码久久千人斩| 久久久久久久久久久免费精品| 久久精品国产99国产电影网| 久久午夜福利无码1000合集| 久久久久久亚洲AV无码专区| 色欲久久久天天天综合网| 新狼窝色AV性久久久久久| 国产精品午夜久久| 欧美综合天天夜夜久久| 丰满少妇人妻久久久久久| 亚洲精品无码久久久久去q| 99久久免费国产精品特黄| 欧美久久久久久午夜精品| 久久国产香蕉视频| 国产69精品久久久久9999| 青青国产成人久久91网| 日本免费一区二区久久人人澡 | 免费国产99久久久香蕉| 久久久久久久免费视频| 日日狠狠久久偷偷色综合免费| 精品国产乱码久久久久久浪潮| 久久这里只精品国产99热| 亚洲国产精品婷婷久久| 91精品国产91久久久久久青草 |