專利名稱:多個線程對文檔的并發(fā)利用的制作方法
多個線程對文檔的并發(fā)利用背景電子文檔在當(dāng)今的工作環(huán)境中無所不在。例如,數(shù)百萬的人每天使用和生成文字 處理文檔、電子表格文檔,及其他種類的文檔。隨著電子文檔的重要性提高,人們期望軟件 應(yīng)用提供用于操縱電子文檔的更強(qiáng)大的工具。例如,人們期望文字處理應(yīng)用提供準(zhǔn)確的語 法和拼寫檢查工具。然而,這樣的工具常常計(jì)算量很大。由于這樣的工具計(jì)算量很大,因此,使用這樣 的工具會導(dǎo)致用戶很容易發(fā)現(xiàn)的延遲。這樣的延遲會導(dǎo)致用戶感到受挫,因此,應(yīng)該盡量最 少化。近年來,計(jì)算機(jī)的性能已經(jīng)提高。然而,這種提高中的大部分是由于單個計(jì)算機(jī)現(xiàn) 在可以使用多個處理單元這一事實(shí)。例如,老式計(jì)算機(jī)只有一個處理單元,因此只能一次執(zhí) 行一個程序。較新的計(jì)算機(jī)可以具有多個處理單元,因此可以同時執(zhí)行多個程序。在某些情況下,在多個處理單元上執(zhí)行的多個程序需要與電子文檔中的相同數(shù)據(jù) 進(jìn)行交互。例如,如果第一程序?qū)⑾螂娮游臋n中的某些數(shù)據(jù)寫入而同時第二程序嘗試讀取 該數(shù)據(jù),則第二程序可能會讀取損壞的數(shù)據(jù)。對此問題的典型的解決方案是在程序讀取數(shù) 據(jù)之前程序鎖定電子文檔中的數(shù)據(jù)。當(dāng)一個程序鎖定數(shù)據(jù)時,沒有其他程序可以向數(shù)據(jù)寫 入。因此,如果另一線程希望向數(shù)據(jù)寫入而數(shù)據(jù)被鎖定,則另一線程不得不等到數(shù)據(jù)被解 鎖。迫使另一線程等待會導(dǎo)致用戶很容易發(fā)現(xiàn)的延遲。概述一種計(jì)算系統(tǒng)并發(fā)地執(zhí)行構(gòu)造器線程和至少一個讀取器線程。構(gòu)造器線程通過修 改文檔的活動表示來修改文檔。讀取器線程使用文檔的非活動表示來對文檔執(zhí)行操作。文 檔的活動表示和文檔的非活動表示存儲在計(jì)算系統(tǒng)的存儲器中。文檔的活動表示和文檔的 非活動表示不包括相同數(shù)據(jù)在存儲器中的不同副本。當(dāng)讀取文檔的任何非活動表示中的數(shù) 據(jù)時,確保邏輯一致性,而不鎖定文檔的任何非活動表示中的任何數(shù)據(jù)。提供本概述是為了介紹一些概念。這些概念在以下詳細(xì)描述中進(jìn)一步描述。本概 述并不旨在標(biāo)識出所要求保護(hù)的主題的關(guān)鍵特征或必要特征,也不旨在用于幫助確定所要 求保護(hù)的主題的范圍。附圖簡述
圖1是示出了示例計(jì)算系統(tǒng)的框圖。圖2示出了示例文檔樹和表示文檔樹的元素陣列。圖3示出了文檔的示例表示。圖4示出了當(dāng)插入元素時文檔的示例表示。圖5示出了當(dāng)刪除元素時文檔的示例表示。圖6示出了當(dāng)在現(xiàn)有片段內(nèi)插入附加元素時文檔的示例表示。圖7示出了示例索引樹。圖8示出了用屬于索引樹的較新版本的替換節(jié)點(diǎn)覆蓋的示例索引樹。圖9是示出了當(dāng)應(yīng)用啟動時由應(yīng)用執(zhí)行的示例操作的流程圖。
圖10是示出了示例元素插入操作的流程圖。
圖11是示出了示例元素插入操作的延續(xù)的流程圖。
圖12是示出了示例元素插入操作的進(jìn)一步延續(xù)的流程圖。
圖13是示出了示例元素插入操作的進(jìn)一步延續(xù)的流程圖。
圖14是示出了示例元素刪除操作的流程圖。
圖15是示出了示例元素刪除操作的延續(xù)的流程圖。
圖16是示出了示例元素刪除操作的延續(xù)的流程圖。
圖17是示出了示例元素刪除操作的延續(xù)的流程圖。
圖18是示出了讀取器線程的示例操作的流程圖。
圖19是示出了讀取器線程的示例操作的流程圖。
圖20是示出了示例計(jì)算設(shè)備的框圖。
詳細(xì)描述
圖I是示出了示例計(jì)算系統(tǒng)100的框圖。如圖I的示例所示,用戶102使用計(jì)算系統(tǒng)100來訪問應(yīng)用104。應(yīng)用104可使用戶102與文檔106進(jìn)行交互。在各實(shí)施例中,應(yīng)用104可以是各種類型的應(yīng)用。例如,應(yīng)用104可以是MICROSOFT WORD 文字處理應(yīng)用、MICROSOFT OUTLOOKiiilli信系統(tǒng)、_MK:ROSOFT EXCEL i[l jN€格應(yīng)用、MICROSOFT ONENOTE 筆記記錄應(yīng)用,或其他類型的文字處理應(yīng)用、通信/電子郵件應(yīng)用、電子表格應(yīng)用、筆記記錄應(yīng)用,或其他類型的可使用戶與文檔進(jìn)行交互的應(yīng)用。因此,文檔106可以是各種類型的文檔。例如,文檔106可以是文字處理文檔、網(wǎng)頁、電子郵件消息、電子表格文檔,或另一種類型的文檔。在各實(shí)施例中,用戶102可以以各種方式與文檔106進(jìn)行交互。例如,在某些實(shí)施例中,用戶102可以查看或編輯文檔106中的內(nèi)容。
為向用戶102顯示文檔106,應(yīng)用104將文檔106的內(nèi)部表示轉(zhuǎn)換為向用戶102示出的文檔。例如,文檔106的表示可包括指示應(yīng)用104如何顯示文檔106的大量的數(shù)據(jù)。應(yīng)用104解釋此數(shù)據(jù),以向用戶102顯示文檔106。然而,此數(shù)據(jù)一般不向用戶102顯示。
應(yīng)用104使用由計(jì)算系統(tǒng)100執(zhí)行的多個線程來使用戶102能夠與文檔106進(jìn)行交互。線程是程序的可以獨(dú)立于程序的其他部分執(zhí)行的一部分。應(yīng)用104所使用的線程可以在計(jì)算系統(tǒng)100的不同的處理單元上并發(fā)地執(zhí)行。因此,線程中的兩個或更多會試圖同時訪問文檔106的表示中的相同數(shù)據(jù)。線程中的兩個或更多同時訪問相同數(shù)據(jù)是不希望的,因?yàn)闀l(fā)生意外的結(jié)果。例如,當(dāng)用戶102向計(jì)算系統(tǒng)100提供輸入以用新單詞(例如, “l(fā)eopard”)來替換文檔106中的老單詞(例如,“tiger”)時,一個線程更新文檔106的表示中的適當(dāng)?shù)臄?shù)據(jù),以將新單詞替換為老單詞。同時,另一線程對文檔進(jìn)行拼寫檢查。如果進(jìn)行拼寫檢查的線程讀取適當(dāng)?shù)臄?shù)據(jù)而更新的線程正在更新適當(dāng)?shù)臄?shù)據(jù),則進(jìn)行拼寫檢查的線程可以讀取表示新單詞中的某一部分(例如,"Ieop”)的數(shù)據(jù)和表示老單詞中的某一部分 (例如,“ger”)的數(shù)據(jù)。進(jìn)行拼寫檢查的線程可能看到單詞為“l(fā)eopger”,并指示新單詞拼寫錯誤,盡管新單詞“l(fā)eopard”拼寫正確并向用戶102顯示正確。這在邏輯上不一致。
為避免此情況,應(yīng)用104使用文檔106的多個表示。如圖I的示例所示,線程包括構(gòu)造器線程108。如在本說明書中別處所描述的,構(gòu)造器線程108通過修改文檔106的活動表示來修改文檔106。文檔106的活動表示存儲在計(jì)算系統(tǒng)100的存儲器中。在構(gòu)造器線程108完成修改文檔106的活動表示之后,文檔106的活動表示變?yōu)槲臋n106的非活動表
除構(gòu)造器線程108之外,應(yīng)用104使用一個或多個讀取器線程IlOA到IlON(統(tǒng)稱為“讀取器線程” 110)。讀取器線程110使用文檔106的一個或多個非活動表示來對文檔 106執(zhí)行操作。這樣的操作幫助應(yīng)用104提供各種類型的功能。例如,文檔106可以是諸如 MICROSOFT WORD 文檔之類的文字處理文檔。在此示例中,讀取器線程110中的一個對文檔106中的文本執(zhí)行拼寫檢查操作。在另一示例中,讀取器線程110中的一個使文檔106準(zhǔn)備好供打印。在再一個示例中,讀取器線程110中的一個將文檔106保存到本地或遠(yuǎn)程數(shù)據(jù)存儲系統(tǒng)中。在再一個示例中,讀取器線程110中的一個使用文檔106的非活動表示以向用戶102顯示文檔106。在再一個示例中,讀取器線程110中的一個在用戶102 向文檔106中鍵入數(shù)據(jù)時對文檔106重標(biāo)頁碼。在再一個示例中,當(dāng)單詞橫跨多行時,讀取器線程110中的一個標(biāo)識要插入連字符的位置。
構(gòu)造器線程108是修改文檔106的任何表示中的數(shù)據(jù)的唯一線程。即,讀取器線程110不修改文檔106的活動表示或文檔106的任何非活動表示。相反地,讀取器線程110 可以指示構(gòu)造器線程108修改文檔106。構(gòu)造器線程108不修改文檔106的任何非活動表示中的任何數(shù)據(jù)。
在構(gòu)造器線程108完成修改文檔106的活動表示的操作之后,文檔106的活動表示變?yōu)槲臋n106的非活動表示。文檔106的此非活動表示可供讀取器線程110使用。為再次修改文檔106,構(gòu)造器線程108生成文檔106的新活動表示,修改文檔106的該新活動表示,并使文檔106的此新活動表示成為文檔106的非活動表示。
由于沒有線程修改文檔106的任何非活動表示,因此,當(dāng)讀取器線程110讀取文檔 106的非活動表示中的數(shù)據(jù)時,確保了邏輯一致性,而不鎖定文檔106的非活動表示中的任何數(shù)據(jù)。換言之,沒有當(dāng)讀取器線程110中的一個嘗試讀取數(shù)據(jù)時另一個并發(fā)地執(zhí)行的線程會向該相同數(shù)據(jù)寫入的危險。
每當(dāng)文檔106被修改時都生成文檔106的完全獨(dú)立的表示會消費(fèi)計(jì)算系統(tǒng)100的存儲器中的大量的空間。此外,每當(dāng)文檔106被修改時生成文檔的完全獨(dú)立的表示會計(jì)算量很大。因此,文檔106的活動表示和文檔106的非活動表示不包括相同數(shù)據(jù)在存儲器中的不同副本。例如,文檔106的活動表示和文檔106的非活動表示兩者都可以包括表示文檔106的相同部分的數(shù)據(jù)。在此示例中,在存儲器中沒有該數(shù)據(jù)的兩個獨(dú)立的副本。相反地,文檔106的活動表示和文檔106的非活動表示兩者都引用存儲器中的該數(shù)據(jù)的相同副本。
圖2示出了示例文檔樹202和元素陣列202。在內(nèi)部,文檔106被表示成諸如文檔樹200之類的文檔樹。文檔樹200是文檔元素的層次結(jié)構(gòu)。這些文檔元素通常不向用戶 102顯示,而是被應(yīng)用104用來確定如何向用戶102顯示文檔106。
文檔樹200中的文檔元素包括表示文檔106內(nèi)的結(jié)構(gòu)的元素。例如,在圖2的示例中,文檔樹200包括作為整體來表示文檔106的文檔元素204。在此示例中,文檔樹200 包括表示文檔106內(nèi)的段落的文檔元素206和文檔元素208。由于文檔元素206(即,段落) 和文檔元素208 (即,另一個段落)表示文檔106內(nèi)的東西,因此,文檔元素206和文檔元素 208在文檔樹200中的文檔元素204之下。
此外,在圖2的示例中,文檔樹200還包括文檔元素210、文檔元素212,以及文檔元素214。文檔元素210和文檔元素212表示由文檔元素206所表示的段落內(nèi)的文本的順串。例如,文檔元素210和文檔元素212可以表示由文檔元素206所表示的段落中的句子。 由于文檔元素210和文檔元素212表示由文檔元素206所表示的段落內(nèi)的東西,因此,文檔元素210和文檔元素212在文檔樹200中的文檔元素206之下。文檔元素214表示由文檔元素208所表示的段落內(nèi)的文本的順串。由于文檔元素214表示由文檔元素208所表示的段落內(nèi)的東西,因此,文檔元素214在文檔樹200中的文檔元素208之下。
文檔樹200中的文檔元素可以具有各種屬性。在圖2的示例中,文檔元素204可包括將“Times New Roman”設(shè)置為文檔106的默認(rèn)字體的屬性。在此示例中,文檔元素208 可包括替換默認(rèn)字體并將“Arial”設(shè)置為由文檔元素208所表示的段落的字體的屬性。此外,在此示例中,文檔元素214可包括使由文檔元素214所表示的文本的順串帶下劃線的屬性。
在概念上,計(jì)算機(jī)存儲器看起來象一行插槽。該行中的每一個插槽都具有不同的地址。例如,該行中的一個插槽可以具有地址“37”,該行中的下一插槽可以具有地址“38” 等等。每一個插槽都可以存儲數(shù)據(jù)。由于計(jì)算機(jī)存儲器看起來象一行插槽,因此,計(jì)算機(jī)存儲器在概念上是一維結(jié)構(gòu)。相比之下,文檔樹200是二維結(jié)構(gòu)(即,文檔樹200具有高度和寬度)。為將文檔樹200 (二維結(jié)構(gòu))存儲在計(jì)算機(jī)存儲器(一維結(jié)構(gòu))中,需要將文檔樹200 表不為一維結(jié)構(gòu)。
元素陣列202是表示文檔樹200的示例一維結(jié)構(gòu)。元素陣列202包括元素216A、 216B、218A、218B、220A、220B、222A、222B、224A、224B、226A,以及 226B。元素 216A 和 216B 對應(yīng)于文檔樹200中的文檔元素204。元素216A是打開的元素,元素216B是對應(yīng)于元素216A 的關(guān)閉的元素。打開的元素和對應(yīng)的關(guān)閉元素之間的陣列中的元素表示低于由打開的元素和對應(yīng)的關(guān)閉的元素所表示的文檔元素下面的文檔元素。
元素216A和216B之間的元素陣列202中的元素對應(yīng)于文檔元素204下面的文檔樹200中的文檔元素。元素218A和218B對應(yīng)于文檔樹200中的文檔元素206。元素218A 和218B之間的元素陣列202中的元素對應(yīng)于文檔元素206下面的文檔樹200中的文檔元素。元素220A和220B對應(yīng)于文檔樹200中的文檔元素210。由于在文檔元素210下面的文檔樹200中沒有文檔元素,因此,在元素220A和220B之間的元素陣列202中沒有元素。 元素222A和222B對應(yīng)于文檔樹200中的文檔元素212。由于在文檔元素210下面的文檔樹200中沒有文檔元素,因此,在元素222A和222B之間的元素陣列202中沒有元素。元素 224A和224B對應(yīng)于文檔樹200中的文檔元素208。元素224A和224B之間的元素陣列202 中的元素對應(yīng)于文檔元素208下面的文檔樹200中的文檔元素。元素226A和226B對應(yīng)于文檔樹200中的文檔元素214。由于在文檔元素214下面的文檔樹200中沒有文檔元素,因此,在元素226A和226B之間的元素陣列202中沒有元素。
在用戶102處理文檔106時,用戶102可能希望在由文檔元素206所表示的段落和由文檔元素208所表示的段落之間添加新段落。因此,文檔樹200將被更新,以包括文檔元素204下面的新文檔元素。新文檔元素表示新段落。為表示更新的文檔樹200,將需要在元素陣列202中的元素218B和224A之間添加新的一對元素。該對新元素對應(yīng)于新文檔元素。
如上文所提及的,計(jì)算機(jī)存儲器在概念上是一行插槽。表示元素陣列202的數(shù)據(jù)存儲在計(jì)算機(jī)存儲器中的這樣的插槽中。為在元素陣列202中的兩個元素之間插入新元素,構(gòu)造器線程108可以通過將新元素之后的元素陣列202中的所有元素復(fù)制到該行插槽的下游的插槽中,為新元素騰出插槽,然后,將新元素存儲到騰出的插槽中。例如,元素218B 可以存儲在插槽“ 37 ”,元素224A可以存儲在插槽“ 38 ”,元素226A可以存儲在插槽“ 39 ”, 元素226B可以存儲在插槽“40”,元素224B可以存儲在插槽“41”,而元素216B可以存儲在插槽“41”。在此示例中,為在元素218B和元素224A之間插入元素,計(jì)算系統(tǒng)100可以將元素216B復(fù)制到插槽“43”,將元素224B復(fù)制到插槽“42”,將元素226B復(fù)制到插槽“41”, 將元素226A復(fù)制到插槽“40”,并將元素224A復(fù)制到插槽“39”。在此示例中,構(gòu)造器線程 108可以將新元素存儲在插槽“37”和“38”中。如此示例演示的,如果構(gòu)造器線程108將使用此方法,構(gòu)造器線程108可能必須執(zhí)行大量的復(fù)制操作來將元素插入到元素陣列202中。 類似地,如果構(gòu)造器線程108將在元素被從元素陣列202中刪除時移動元素陣列202中的元素,則構(gòu)造器線程108可能必須執(zhí)行大量的復(fù)制操作來從元素陣列202中刪除元素。
并非在新元素被插入到元素陣列202中時復(fù)制元素,構(gòu)造器線程108將新元素添加到真實(shí)元素陣列的一端中。因此,真實(shí)元素陣列中的元素不一定被排序,以便對應(yīng)于另一個文檔元素下面的文檔元素的元素在對應(yīng)于其他文檔元素的元素之間。如本說明書所描述的,文檔106的表示包括索引樹、片段描述符表,以及這樣的真實(shí)元素陣列。索引樹和片段描述符表指示真實(shí)元素陣列中的元素在虛擬元素陣列中的哪里。虛擬元素陣列是文檔樹 200的一維表示。虛擬元素陣列中的元素被排序,以便對應(yīng)于另一個文檔元素下面的文檔元素的元素在對應(yīng)于其他文檔元素的元素之間。
圖3是示出了文檔106的示例表示的框圖。文檔106的表示包括索引樹300、片段描述符表302,以及真實(shí)元素陣列304。索引樹300和片段描述符表302是指示真實(shí)元素陣列304中的元素在虛擬元素陣列306中的哪里的數(shù)據(jù)結(jié)構(gòu)。
如圖3的示例所示,真實(shí)元素陣列304包含元素308A、308B、310A、310B、312A,以及 312B。元素308A、308B、310A、310B、312A,以及312B對應(yīng)于文檔106的文檔樹中的每一個文檔元素。對于虛擬元素陣列306中的每一個給定元素,如果給定元素在虛擬元素陣列306中的打開的元素和關(guān)閉的元素之間,則給定元素表示文檔樹中的低于由打開的元素和關(guān)閉的元素所表示的文檔樹中的文檔元素的文檔元素。虛擬元素陣列306還包含元素308A、308B、 310A、310B、312A,以及312B。然而,虛擬元素陣列306不實(shí)際存在于計(jì)算機(jī)存儲器中。
在諸如圖3的示例中所示出的之類的某些實(shí)施例中,當(dāng)應(yīng)用104最初加載文檔106 時,真實(shí)元素陣列304中的元素被適當(dāng)?shù)嘏判?。換言之,真實(shí)元素陣列304中的對應(yīng)于低于另一文檔元素的文檔元素的每一個元素都在對應(yīng)于其他文檔元素的元素之間。因此,當(dāng)應(yīng)用104最初加載文檔106時,真實(shí)元素陣列304可以與虛擬元素陣列306相同。
片段描述符表302包含一組一個或多個片段描述符。片段描述符表302中的片段描述符中的每一個都是標(biāo)識真實(shí)元素陣列304的不同的片段的數(shù)據(jù)結(jié)構(gòu)。真實(shí)元素陣列 304的片段是真實(shí)元素陣列304中的一組一個或多個連續(xù)的元素。例如,元素308A、310A, 以及310B可以是真實(shí)元素陣列304的片段,而元素312B和308B可以是真實(shí)元素陣列304 的另一片段。
在各實(shí)施例中,片段描述符是以各種方式實(shí)現(xiàn)的。例如,在某些實(shí)施例中,片段描述符指定片段的最左邊的元素的真實(shí)偏移量以及片段的最右邊的元素的真實(shí)偏移量。在本說明書中,當(dāng)一個元素比另一元素更接近于陣列的開始處時,可以說陣列中的元素在陣列中的另一個元素的左邊。類似地,當(dāng)一個元素比另一元素更遠(yuǎn)離陣列的開始處時,可以說陣列中的元素在陣列中的另一個元素的右邊。在其他實(shí)施例中,片段描述符被實(shí)現(xiàn)為具有真實(shí)偏移屬性和長度屬性的數(shù)據(jù)結(jié)構(gòu)。元素的真實(shí)偏移量指示從真實(shí)元素陣列304的開始處到元素的距離。片段描述符的真實(shí)偏移屬性指示片段中的最左邊的元素的真實(shí)偏移量。片段描述符的長度屬性指示片段的長度。片段描述符的此實(shí)現(xiàn)用于整個本說明書中。然而, 應(yīng)該理解,在其他實(shí)施例中,也可以使用片段描述符的其他實(shí)現(xiàn)。
片段描述符的真實(shí)偏移屬性可以以各種方式指示真實(shí)偏移量。例如,在某些實(shí)施例中,真實(shí)偏移屬性可以指示從真實(shí)元素陣列304的開始處到元素的字節(jié)的數(shù)量。在其他實(shí)施例中,真實(shí)偏移屬性可以指示真實(shí)元素陣列304的開始處和元素之間的元素的數(shù)量。 在整個本說明書中描述了真實(shí)偏移屬性指示了元素的數(shù)量的各實(shí)施例。然而,應(yīng)該理解,在某些實(shí)施例中,真實(shí)偏移屬性可以以其他方式指示與真實(shí)元素陣列304的開始處的距離。
片段描述符的長度屬性以各種方式指示片段的長度。例如,在某些實(shí)施例中,長度屬性可以指示片段中的字節(jié)的數(shù)量。在其他實(shí)施例中,長度屬性可以指示片段中的元素的數(shù)量。在整個本說明書中描述了長度屬性指示了元素的數(shù)量的各實(shí)施例。然而,應(yīng)該理解, 在其他實(shí)施例中,長度屬性可以以其他方式指示片段的長度。
當(dāng)計(jì)算系統(tǒng)100最初加載文檔106時,在真實(shí)元素陣列304中只有一個片段。因此,片段描述符表302包括單個片段描述符314。片段描述符314具有真實(shí)偏移屬性0,從而指示從真實(shí)元素陣列304的開始處開始的片段。片段描述符314具有長度屬性6,表示片段是六個元素長。
索引樹300包括一個或多個索引節(jié)點(diǎn)的層次結(jié)構(gòu)。索引樹300中的索引節(jié)點(diǎn)中的每一個都對應(yīng)于片段描述符表302中的不同的片段描述符。如圖3的示例所示,片段描述符表302中只有一個片段描述符314。因此,索引樹300包含單個索引節(jié)點(diǎn)316。
在各實(shí)施例中,索引樹300中的索引節(jié)點(diǎn)是以各種方式實(shí)現(xiàn)的。例如,在某些實(shí)施例中,索引樹300中的索引節(jié)點(diǎn)被實(shí)現(xiàn)為具有左子節(jié)點(diǎn)屬性、右子節(jié)點(diǎn)屬性,以及描述符屬性的數(shù)據(jù)結(jié)構(gòu)。在這樣的實(shí)施例中,如果索引節(jié)點(diǎn)在索引樹300中具有左子索引節(jié)點(diǎn),則索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性指示索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性。如果索引節(jié)點(diǎn)在索引樹300中具有右子索引節(jié)點(diǎn),則索引節(jié)點(diǎn)的右子節(jié)點(diǎn)屬性指示索引節(jié)點(diǎn)的右子節(jié)點(diǎn)屬性。索引節(jié)點(diǎn)的描述符屬性指示片段描述符表302中的片段描述符。在圖3的示例中,索引節(jié)點(diǎn)316的描述符屬性指示片段描述符314。在整個本說明書中描述了其中索引節(jié)點(diǎn)被實(shí)現(xiàn)為具有左子節(jié)點(diǎn)屬性、右子節(jié)點(diǎn)屬性,以及描述符屬性的數(shù)據(jù)結(jié)構(gòu)的各實(shí)施例。然而,應(yīng)該理解,在其他實(shí)施例中,索引節(jié)點(diǎn)是以其他方式實(shí)現(xiàn)的。
圖4是示出了當(dāng)插入元素時文檔106的示例表示的框圖。如圖4的示例所示,元素402A、402B、404A、以及404B被插入在真實(shí)元素陣列304的一端。元素402A和402B表示低于由元素310A和310B所表示的文檔元素的文檔元素。元素404A和404B表示低于由元素310A和310B所表示的文檔元素的文檔元素。因此,在虛擬元素陣列306中,元素402A、 402B、404A,以及404B在元素3IOA和3IOB之間。
以前,真實(shí)元素陣列304中的所有元素都被適當(dāng)?shù)嘏判?。因此,只需要一個片段描述符314來指示真實(shí)元素陣列304的包括元素308A和308B之間的元素的真實(shí)元素陣列10304的片段。當(dāng)元素402A、402B、404A、以及404B被插入到真實(shí)元素陣列304中時,真實(shí)元素陣列304中的元素不再被適當(dāng)?shù)嘏判?。相反,真?shí)元素陣列304中的元素被分成三個片段包含屬于元素402A、402B、404A,以及404B的左側(cè)的元素(即,元素308A和310A)的真實(shí)元素陣列304的片段,包含元素402A、402B、404A,以及404B的真實(shí)元素陣列304的片段, 以及,包含屬于元素402A、402B、404A,以及404B的右側(cè)的元素(S卩,元素310B、312A、312B, 以及308B)的真實(shí)元素陣列304的片段。
片段描述符的屬性的值不能改變是片段描述符表302的屬性。此屬性可以確保, 讀取器線程110可以從片段描述符中讀取數(shù)據(jù),而無需考慮構(gòu)造器線程108在讀取器線程 110正在讀取片段描述符中的數(shù)據(jù)時會改變片段描述符中的數(shù)據(jù)的可能性。
由于片段描述符的屬性的值不改變,并且由于片段描述符只能指示真實(shí)元素陣列 304中的一個片段,因此,需要附加片段描述符。為添加附加片段描述符,構(gòu)造器線程108 生成片段描述符406、片段描述符408,以及片段描述符410。片段描述符406、片段描述符 408,以及片段描述符410構(gòu)成片段描述符表302的活動版本。片段描述符表302的活動版本是文檔106的活動表不的一部分。
片段描述符406替換片段描述符314。然而,構(gòu)造器線程108不立即刪除片段描述符314。相反地,片段描述符314繼續(xù)作為文檔106的非活動表示中的片段描述符表302 的非活動版本的一部分而存在。因此,讀取器線程110在構(gòu)造器線程108正在對片段描述符表302的活動版本中的片段描述符執(zhí)行操作時可以使用片段描述符314。
片段描述符406標(biāo)識包含元素308A和310A的真實(shí)元素陣列304的片段。請注意, 片段描述符406是片段描述符314的克隆(即,副本),只是片段描述符406的長度屬性不同于片段描述符314的長度屬性。片段描述符408標(biāo)識包含元素310B、312A,312B,以及308B 的真實(shí)元素陣列304的片段。片段描述符410標(biāo)識包含元素402A、402B、404A,以及404B的真實(shí)元素陣列304的片段。
索引樹300中的索引節(jié)點(diǎn)可以最多具有兩個子節(jié)點(diǎn)。索引樹300中的索引節(jié)點(diǎn)的兩個子樹的高度相差至多一個。例如,當(dāng)索引節(jié)點(diǎn)的左子樹的深度是I時,索引節(jié)點(diǎn)的右子樹的深度無法是3。在另一示例中,當(dāng)左子樹的深度是I時,索引節(jié)點(diǎn)的右子樹的深度可以是2、I或O。在某些實(shí)施例中,索引樹300是AVL樹、B樹、紅-黑樹,或另一種二叉樹。
索引樹300具有排序?qū)傩?。排序?qū)傩砸?guī)定,對于索引樹300中的每一個索引節(jié)點(diǎn), 與索引節(jié)點(diǎn)的左子樹中的索引節(jié)點(diǎn)相關(guān)聯(lián)的元素具有小于與索引節(jié)點(diǎn)相關(guān)聯(lián)的元素的虛擬偏移量的虛擬偏移量。此外,與索引節(jié)點(diǎn)的右子樹中的索引節(jié)點(diǎn)相關(guān)聯(lián)的元素具有大于與索引節(jié)點(diǎn)相關(guān)聯(lián)的元素的虛擬偏移量的虛擬偏移量。當(dāng)元素位于由索引節(jié)點(diǎn)所指示的片段描述符所指示的片段中時,元素與索引節(jié)點(diǎn)相關(guān)聯(lián)。元素的虛擬偏移量是從虛擬元素陣列306的開始處到虛擬元素陣列306中的元素的位置的距離。
另外,索引節(jié)點(diǎn)的屬性的值不能改變也是索引樹300的屬性。此屬性可以確保,讀取器線程Iio可以從索引節(jié)點(diǎn)中讀取數(shù)據(jù),而無需考慮構(gòu)造器線程108在讀取器線程110 正在讀取索引節(jié)點(diǎn)中的數(shù)據(jù)時會改變索引節(jié)點(diǎn)中的數(shù)據(jù)的可能性。
為在元素402A、402B、404A,以及404B被插入到真實(shí)元素陣列304中時保持這些屬性,構(gòu)造器線程108生成索引節(jié)點(diǎn)412,414,以及416。索引節(jié)點(diǎn)412,414,以及416構(gòu)成索引樹300的活動版本。索引樹300的活動版本是文檔106的活動表示的一部分。
索引節(jié)點(diǎn)414替換索引節(jié)點(diǎn)316。然而,構(gòu)造器線程108不立即刪除索引節(jié)點(diǎn)316。 相反地,索引節(jié)點(diǎn)316繼續(xù)作為文檔106的非活動表示中所包括的索引樹300的非活動版本的一部分而存在。因此,讀取器線程110在構(gòu)造器線程108正在執(zhí)行操作以修改索引樹 300的活動版本時可以使用索引節(jié)點(diǎn)316。索引節(jié)點(diǎn)412指示片段描述符406,索引節(jié)點(diǎn)414 指示片段描述符410,而索引節(jié)點(diǎn)416指示片段描述符408。
索引節(jié)點(diǎn)412位于索引節(jié)點(diǎn)414的左子樹中。因此,索引節(jié)點(diǎn)412與具有小于與索引節(jié)點(diǎn)414相關(guān)聯(lián)的元素的虛擬偏移量的虛擬偏移量的元素相關(guān)聯(lián)。索引節(jié)點(diǎn)416位于索引節(jié)點(diǎn)414的右子樹中。因此,索引節(jié)點(diǎn)416與具有大于與索引節(jié)點(diǎn)414相關(guān)聯(lián)的元素的虛擬偏移量的虛擬偏移量的元素相關(guān)聯(lián)。
在圖4的示例中,文檔106的活動表示包括索引樹300的活動版本,片段描述符表 302的活動版本以及真實(shí)元素陣列304。當(dāng)構(gòu)造器線程108完成插入元素402A、402B、404A, 以及404B的操作時,索引樹300的活動版本包括索引節(jié)點(diǎn)412、414,以及416,片段描述符表302的活動版本包括片段描述符406、408以及410。文檔106的非活動表示包括索引樹 300的非活動版本,片段描述符表302的非活動版本以及真實(shí)元素陣列304。索引樹300的非活動版本僅僅包括索引節(jié)點(diǎn)316。片段描述符表302的非活動版本僅僅包括片段描述符 314。
圖5示出了當(dāng)刪除元素時文檔106的示例表示。如圖5的示例所示,從虛擬元素陣列306中刪除元素402A和402B。在真實(shí)元素陣列304中,元素402A和404B之后的元素不移動。S卩,在真實(shí)元素陣列304中,當(dāng)從虛擬元素陣列306中刪除元素402A和402B時,不使元素404A靠近元素308B。然而,在虛擬元素陣列306中,表現(xiàn)為好像元素402A和402B已經(jīng)完全消失。
當(dāng)元素402A和402B被刪除時,片段描述符410的真實(shí)偏移屬性和長度屬性的值需要改變,以便指示片段不包括元素402A和402B。如上文所提及的,片段描述符的屬性的值不能改變是片段描述符表302的屬性。因此,構(gòu)造器線程108生成片段描述符500。片段描述符500、片段描述符408,以及片段描述符406構(gòu)成片段描述符表302的活動版本。片段描述符500替換片段描述符410。片段描述符500的真實(shí)偏移屬性和長度屬性具有適當(dāng)?shù)闹怠?br>
盡管構(gòu)造器線程108生成了片段描述符500,但是,索引節(jié)點(diǎn)414的描述符屬性仍指示片段描述符410。如上文所提及的,索引節(jié)點(diǎn)的屬性的值不能改變是索引樹300的屬性。因此,構(gòu)造器線程108生成新索引節(jié)點(diǎn)502。索引節(jié)點(diǎn)502、414,以及416構(gòu)成索引樹 300的活動版本。索引節(jié)點(diǎn)502替換索引節(jié)點(diǎn)414。索引節(jié)點(diǎn)502的描述符屬性指示片段描述符500。構(gòu)造器線程108不立即刪除索引節(jié)點(diǎn)414。這可使讀取器線程110在構(gòu)造器線程108修改索引樹300的活動版本和片段描述符表302的活動版本時繼續(xù)使用索引節(jié)點(diǎn) 414和片段描述符410。
應(yīng)該理解,索引節(jié)點(diǎn)316和片段描述符314仍可以存在,供不使用索引節(jié)點(diǎn)414作為索引樹300的根節(jié)點(diǎn)的讀取器線程110使用。根索引節(jié)點(diǎn)是沒有先輩節(jié)點(diǎn)的索引節(jié)點(diǎn)。 然而,為了清楚起見,圖5中省略了索引節(jié)點(diǎn)316和片段描述符314。
圖6示出了當(dāng)在現(xiàn)有片段內(nèi)插入附加元素時文檔106的示例表示。如圖6的示例中,構(gòu)造器線程108將元素600A和600B插入到真實(shí)元素陣列304中。在虛擬元素陣列306中,元素600A和600B屬于元素312A和312B之間。換言之,元素600A和600B表示低于由文檔樹200中的元素312A和312B所表示的文檔元素的文檔元素。
為確保元素600A和600B在虛擬元素陣列306中具有正確的位置,構(gòu)造器線程108 創(chuàng)建新片段描述符602。片段描述符602標(biāo)識包含元素600A和600B的真實(shí)元素陣列304 的片段。由于包含元素600A和600B的片段在邏輯上在包含元素310B、312A、312B,以及 308B的片段內(nèi)發(fā)生,因此,構(gòu)造器線程108生成片段描述符604和606。片段描述符406、 606、500、604,以及602構(gòu)成片段描述符表302的活動版本。片段描述符604指示包含具有大于元素600A和600B的虛擬偏移量的虛擬偏移量的元素的真實(shí)元素陣列304的片段。片段描述符606指示包含具有小于元素600A和600B的虛擬偏移量的虛擬偏移量的元素的真實(shí)元素陣列304的片段。片段描述符606替換片段描述符408。
然后,構(gòu)造器線程108生成索引節(jié)點(diǎn)608和610。索引節(jié)點(diǎn)608的描述符屬性指示片段描述符606。索引節(jié)點(diǎn)610的描述符屬性指示片段描述符604。由于索引節(jié)點(diǎn)608和 610與元素600A和600B的左邊和右邊的元素相關(guān)聯(lián),因此,索引節(jié)點(diǎn)608和610需要是與元素600A和600B相關(guān)聯(lián)的索引節(jié)點(diǎn)的子節(jié)點(diǎn)。因此,索引節(jié)點(diǎn)416的左子節(jié)點(diǎn)屬性、右子節(jié)點(diǎn)屬性,以及描述符屬性將需要改變。由于索引節(jié)點(diǎn)416不被允許改變,因此,構(gòu)造器線程108生成索引節(jié)點(diǎn)612以替換索引節(jié)點(diǎn)416。索引節(jié)點(diǎn)612的左子節(jié)點(diǎn)屬性指示索引節(jié)點(diǎn)608。索引節(jié)點(diǎn)612的右子節(jié)點(diǎn)屬性指示索引節(jié)點(diǎn)610。索引節(jié)點(diǎn)612的描述符屬性指不片段描述符602。
此外,索引節(jié)點(diǎn)502的右子節(jié)點(diǎn)屬性還應(yīng)該改變以指示新索引節(jié)點(diǎn)612。由于索引節(jié)點(diǎn)502不被允許改變,因此,構(gòu)造器線程108生成索引節(jié)點(diǎn)614。索引節(jié)點(diǎn)614的左子節(jié)點(diǎn)屬性繼續(xù)指示索引節(jié)點(diǎn)412,索引節(jié)點(diǎn)614的右子節(jié)點(diǎn)屬性指示索引節(jié)點(diǎn)612,而索引節(jié)點(diǎn)614的描述符屬性繼續(xù)指示片段描述符500。因此,在圖6的示例中,索引節(jié)點(diǎn)614、412、 612,608,以及610構(gòu)成索引樹300的活動版本。
應(yīng)該理解,圖4、5,以及6只示出了構(gòu)造器線程108對索引樹300和片段描述符表 302執(zhí)行的動作的某些組合,以維持真實(shí)元素陣列304和虛擬元素陣列306之間的適當(dāng)?shù)年P(guān)系O
圖7示出了示例索引樹700。索引樹700包括15個索引節(jié)點(diǎn)702到730。在圖7 的示例中,在索引節(jié)點(diǎn)內(nèi)示出了索引節(jié)點(diǎn)的左子樹的大小。例如,索引節(jié)點(diǎn)702的左子樹的大小是七,因?yàn)樵谒饕?jié)點(diǎn)702的左子樹中有七個索引節(jié)點(diǎn)。
索引節(jié)點(diǎn)的左子樹的大小不改變是索引樹700的屬性。因此,在構(gòu)造器線程108將在任何索引節(jié)點(diǎn)的左子樹中的索引節(jié)點(diǎn)添加到索引樹700中的任何時間,構(gòu)造器線程108 為索引節(jié)點(diǎn)的所有先輩索引節(jié)點(diǎn)生成替換索引節(jié)點(diǎn)。然而,為將單個的索引節(jié)點(diǎn)添加到索引樹700中,構(gòu)造器線程108不需要為不是新索引節(jié)點(diǎn)的先輩索引節(jié)點(diǎn)的索引節(jié)點(diǎn)生成任何替換。圖4和6的示例演示了此屬性。
圖8示出了用屬于索引樹700的較新版本的替換節(jié)點(diǎn)來覆蓋的索引樹700。在圖8 的示例中,構(gòu)造器線程108將索引節(jié)點(diǎn)802添加到索引樹700中。因此,構(gòu)造器線程108生成替換索引節(jié)點(diǎn)804、806、808,以及810。在索引樹700的較高版本中,替換索引節(jié)點(diǎn)804、 806,808,以及810替換索引節(jié)點(diǎn)718、708、704,以及702。
圖9是示出了當(dāng)應(yīng)用104啟動時由應(yīng)用104執(zhí)行的示例操作900的流程圖。如圖9的示例所示,當(dāng)應(yīng)用104啟動時(902)操作900開始。在各實(shí)施例中,應(yīng)用104響應(yīng)于各種事件而啟動。例如,在某些實(shí)施例中,當(dāng)用戶102指示計(jì)算系統(tǒng)100的操作系統(tǒng)啟動應(yīng)用 104時,應(yīng)用104啟動。在其他實(shí)施例中,應(yīng)用104響應(yīng)于來自另一應(yīng)用的請求而啟動。
在應(yīng)用104啟動之后,應(yīng)用104從本地或遠(yuǎn)程數(shù)據(jù)存儲系統(tǒng)將文檔106讀取到存儲器(904)中。在某些實(shí)施例中,應(yīng)用104不在啟動之后立即將文檔106讀取到存儲器中, 而是在讀取文檔106之前等待某個事件。例如,當(dāng)應(yīng)用104接收到來自用戶102的打開文檔106的輸入時,應(yīng)用104可以讀取文檔106。當(dāng)應(yīng)用104將文檔106讀取到存儲器中時, 應(yīng)用104將表示文檔106中的文檔元素的元素存儲在真實(shí)元素陣列304中。
接下來,應(yīng)用104生成片段描述符表302 (906)。如圖3的示例所示,片段描述符表302最初只包含一個片段描述符。然后,應(yīng)用104生成索引樹300 (908)。如圖3的示例所示,索引樹300最初只包含一個索引節(jié)點(diǎn)。索引節(jié)點(diǎn)的描述符屬性指示片段描述符表 302中的片段描述符。
在生成片段描述符表302和索引樹300之后,應(yīng)用104設(shè)直當(dāng)如樹指針以指不索引樹300中的單個索引節(jié)點(diǎn)(910)。如下面參考圖19所描述的,讀取器線程110使用當(dāng)前樹指針以確定索引樹300的最近可用的非活動版本的根索引節(jié)點(diǎn)。
在應(yīng)用104設(shè)置當(dāng)前樹指針之后,應(yīng)用104喚醒構(gòu)造器線程108(912)。喚醒線程是使線程開始運(yùn)行的過程。在構(gòu)造器線程108醒來之后,構(gòu)造器線程108可以響應(yīng)于用戶的修改文檔106的輸入,來修改文檔106的活動表不。
每當(dāng)構(gòu)造器線程108接收到修改文檔106的輸入時,構(gòu)造器線程108執(zhí)行生成文檔106的新活動表示的操作。在構(gòu)造器線程108完成該操作之后,文檔106的新的活動表示變?yōu)榭晒┳x取器線程110使用的文檔106的非活動表示。例如,在某些實(shí)施例中,構(gòu)造器線程108執(zhí)行元素插入操作和元素刪除操作。每當(dāng)構(gòu)造器線程108執(zhí)行元素插入操作時,構(gòu)造器線程108都生成文檔106的新活動表示,其中,虛擬元素陣列306包括一個或多個附加元素。在元素插入操作結(jié)束時,文檔106的新的活動表示變?yōu)榭晒┳x取器線程110使用的文檔106的非活動表示。圖10-13示出了元素插入操作的示例實(shí)現(xiàn)。每當(dāng)構(gòu)造器線程108 執(zhí)行元素刪除操作時,構(gòu)造器線程108都生成文檔106的新活動表示,其中,虛擬元素陣列 306包括較少的元素。在元素刪除操作結(jié)束時,文檔106的新的活動表示變?yōu)榭晒┳x取器線程110使用的文檔106的非活動表示。圖14-18示出了元素刪除操作的示例實(shí)現(xiàn)。
接下來,應(yīng)用104喚醒一個或多個讀取器線程110(914)。一個或多個讀取器線程 110中的每一個都執(zhí)行最初檢查當(dāng)前樹指針以確定索引樹300的最近可用的非活動版本的根索引節(jié)點(diǎn)的操作。在由讀取器線程110執(zhí)行的操作的整段時期內(nèi),讀取器線程110使用該索引節(jié)點(diǎn)和由該索引節(jié)點(diǎn)的左和右子節(jié)點(diǎn)屬性所指示的索引節(jié)點(diǎn)來訪問真實(shí)元素陣列304 中的元素。換言之,在由讀取器線程110執(zhí)行的操作的過程中,讀取器線程110不開始查看索引樹300的較新版本。讀取器線程110可以執(zhí)行重復(fù)的操作。當(dāng)由讀取器線程110中的一個執(zhí)行的操作重復(fù)時,讀取器線程可以再次查看當(dāng)前樹指針以確定索引樹300的最近可用的非活動版本的根索引節(jié)點(diǎn)。
由于構(gòu)造器線程108和讀取器線程110可以并發(fā)地執(zhí)行,由于構(gòu)造器線程108不修改文檔106的非活動表示,并且由于讀取器線程110不從文檔106的活動表示中讀取,因此,確保了文檔106的非活動表示的邏輯一致性,而不鎖定文檔106的非活動表示中的數(shù)據(jù)。因此,構(gòu)造器線程108可以在讀取器線程110并發(fā)地從文檔106的一個或多個非活動表示中讀取給定元素時從文檔106的活動表示中刪除同一個給定元素。在此示例中,給定元素表示文檔106的文檔樹中的同一個文檔。
圖10是示出了示例元素插入操作1000的流程圖。如圖10的示例所示,當(dāng)構(gòu)造器線程108接收到指示元素將被插入到文檔106中的輸入時(1002),元素插入操作1000開始。在各實(shí)施例中,構(gòu)造器線程108可以以各種方式接收這樣的輸入。例如,構(gòu)造器線程 108可以監(jiān)聽來自應(yīng)用104的用戶的鍵盤輸入。在另一示例中,構(gòu)造器線程108可以監(jiān)聽來自應(yīng)用104的另一線程或另一應(yīng)用的插入元素的指令。
響應(yīng)于接收到輸入,構(gòu)造器線程108將一個或多個元素插入到真實(shí)元素陣列304 中(1004)。插入的元素變?yōu)檎鎸?shí)元素陣列304的新的片段。在各實(shí)施例中,構(gòu)造器線程108 以各種方式將元素插入到真實(shí)元素陣列304中。例如,在某些實(shí)施例中,對于至少某些類型的文檔元素,構(gòu)造器線程108將打開的元素和關(guān)閉的元素插入到真實(shí)元素陣列304中。在這樣的實(shí)施例中,對于其他類型的元素,構(gòu)造器線程108將單個元素插入到真實(shí)元素陣列304 中。
接下來,構(gòu)造器線程108設(shè)置當(dāng)前節(jié)點(diǎn)指針以指示索引樹300的最近可用的非活動版本的根索引節(jié)點(diǎn)(1006)。在本說明書中,當(dāng)前索引節(jié)點(diǎn)是由當(dāng)前節(jié)點(diǎn)指針?biāo)甘镜乃饕?jié)點(diǎn)。此外,在本說明書中,當(dāng)前片段描述符還是由當(dāng)前索引節(jié)點(diǎn)所指示的片段描述符。 此外,在本說明書中,當(dāng)前片段描述符還是由當(dāng)前片段描述符所指示的真實(shí)元素陣列304 的片段。
在設(shè)置當(dāng)前節(jié)點(diǎn)指針之后,構(gòu)造器線程108確定新片段的虛擬偏移量是否小于當(dāng)前片段的虛擬偏移量(1008)。新片段是包含插入的元素的真實(shí)元素陣列304的片段。新片段的虛擬偏移量是從虛擬元素陣列306的開始處到插入的元素的最左邊的元素的距離。當(dāng)前片段的虛擬偏移量是從虛擬元素陣列306的開始處到當(dāng)前片段中的最左邊的元素的距離。
如果新片段的虛擬偏移量小于當(dāng)前片段的虛擬偏移量(1008的“是”),則構(gòu)造器線程108使當(dāng)前索引節(jié)點(diǎn)進(jìn)棧到堆棧上(1010)。在各實(shí)施例中,構(gòu)造器線程108以各種方式使當(dāng)前索引節(jié)點(diǎn)進(jìn)棧到堆棧上。例如,在某些實(shí)施例中,構(gòu)造器線程108通過使指向當(dāng)前索引節(jié)點(diǎn)的指針進(jìn)棧到堆棧上來使當(dāng)前索引節(jié)點(diǎn)進(jìn)棧到堆棧上。
在使當(dāng)前索引節(jié)點(diǎn)進(jìn)棧到堆棧上之后,構(gòu)造器線程108設(shè)置當(dāng)前節(jié)點(diǎn)指針以指示當(dāng)前索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性(1012)。通過設(shè)置當(dāng)前節(jié)點(diǎn)指針以指示當(dāng)前索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性,當(dāng)前索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性變?yōu)椤爱?dāng)前”索引節(jié)點(diǎn)。然后,構(gòu)造器線程108再次確定新片段的虛擬偏移量是否小于當(dāng)前片段的虛擬偏移量(1008)。只要新片段的虛擬偏移量小于當(dāng)前片段的虛擬偏移量,構(gòu)造器線程108就持續(xù)重復(fù)步驟1010和1012。
如果新片段的虛擬偏移量不小于當(dāng)前片段的虛擬偏移量(1008的“否”),則構(gòu)造器線程108確定新片段的虛擬偏移量是否與當(dāng)前片段的虛擬偏移量相同(1014)。如果構(gòu)造器線程108確定新片段的虛擬偏移量與當(dāng)前片段的虛擬偏移量相同(1014的“是”),則構(gòu)造器線程108執(zhí)行圖11中所示出的操作“A”。在構(gòu)造器線程108執(zhí)行操作“A”之后,構(gòu)造器線程108執(zhí)行圖13中所示出的操作“C”,以完成元素插入操作1000。
如果構(gòu)造器線程108確定新片段的虛擬偏移量不與當(dāng)前片段的虛擬偏移量相同(1014的“否”),則構(gòu)造器線程108確定新片段的虛擬偏移量是否在當(dāng)前片段的虛擬偏移量的范圍內(nèi)(1016)。如果構(gòu)造器線程108確定新片段的虛擬偏移量在當(dāng)前片段的的虛擬偏移量的范圍內(nèi)(1016的“是”),則構(gòu)造器線程108執(zhí)行圖12中所示出的操作“B”。在構(gòu)造器線程108執(zhí)行操作“B”之后,構(gòu)造器線程108執(zhí)行圖13中所示出的操作“C”,以完成元素插入操作1000。
如果構(gòu)造器線程108確定新片段的虛擬偏移量不在當(dāng)前片段的虛擬偏移量的范圍內(nèi)(1016的“否”),則構(gòu)造器線程108使當(dāng)前索引節(jié)點(diǎn)進(jìn)棧到堆棧上(1018)。在使當(dāng)前索引節(jié)點(diǎn)進(jìn)棧到堆棧上之后,構(gòu)造器線程108設(shè)置當(dāng)前節(jié)點(diǎn)指針以指示當(dāng)前索引節(jié)點(diǎn)的右子節(jié)點(diǎn)屬性(1020)。通過設(shè)置當(dāng)前節(jié)點(diǎn)指針以指示當(dāng)前索引節(jié)點(diǎn)的右子節(jié)點(diǎn)屬性,當(dāng)前索引節(jié)點(diǎn)的右子節(jié)點(diǎn)屬性變?yōu)椤爱?dāng)前”索引節(jié)點(diǎn)。在設(shè)置當(dāng)前節(jié)點(diǎn)指針以指示當(dāng)前索引節(jié)點(diǎn)的右子節(jié)點(diǎn)屬性之后,構(gòu)造器線程108再次確定新片段的虛擬偏移量是否小于當(dāng)前片段的虛擬偏移量(1008),依次類推。
圖11是示出了示例元素插入操作1000的延續(xù)1100的流程圖。如圖11的示例所示,當(dāng)構(gòu)造器線程108克隆當(dāng)前索引節(jié)點(diǎn)時(1102),延續(xù)1100開始。在本說明書中,每當(dāng)構(gòu)造器線程108 “克隆”當(dāng)前索引節(jié)點(diǎn)時,構(gòu)造器線程108生成此處被稱為克隆的當(dāng)前索引節(jié)點(diǎn)的新索引節(jié)點(diǎn)??寺〉漠?dāng)前索引節(jié)點(diǎn),至少一開始,與當(dāng)前索引節(jié)點(diǎn)具有相同左子節(jié)點(diǎn)屬性、右子節(jié)點(diǎn)屬性,以及描述符屬性。以此方式,如果當(dāng)前索引節(jié)點(diǎn)具有左子節(jié)點(diǎn)屬性,則當(dāng)前索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性變?yōu)榭寺〉漠?dāng)前索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性。此外,如果當(dāng)前索引節(jié)點(diǎn)具有右子節(jié)點(diǎn)屬性,則當(dāng)前索引節(jié)點(diǎn)的右子節(jié)點(diǎn)屬性變?yōu)榭寺〉漠?dāng)前索引節(jié)點(diǎn)的右子節(jié)點(diǎn)屬性。此外,當(dāng)構(gòu)造器線程108克隆當(dāng)前索引節(jié)點(diǎn)時,構(gòu)造器線程108配置克隆的當(dāng)前節(jié)點(diǎn)的描述符屬性以指示當(dāng)前片段描述符。
在克隆當(dāng)前索引節(jié)點(diǎn)之后,構(gòu)造器線程108生成新索引節(jié)點(diǎn)(1104)。類似于其他索引節(jié)點(diǎn),新索引節(jié)點(diǎn)具有左子節(jié)點(diǎn)屬性、右子節(jié)點(diǎn)屬性,以及描述符屬性。構(gòu)造器線程108 設(shè)置新索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性以指示當(dāng)前索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性(1106)。以此方式, 當(dāng)前索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性變?yōu)樾滤饕?jié)點(diǎn)的左子節(jié)點(diǎn)屬性。
接下來,構(gòu)造器線程108配置克隆的索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性以指示新索引節(jié)點(diǎn) (1108)。以此方式,新索引節(jié)點(diǎn)變?yōu)榭寺〉漠?dāng)前索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性。
然后,構(gòu)造器線程108生成新片段描述符(1110)。新片段描述符指示包含插入的元素的真實(shí)元素陣列304的片段。然后,構(gòu)造器線程108設(shè)置新索引節(jié)點(diǎn)的描述符屬性以指示新片段描述符(1112)。
然后,構(gòu)造器線程108重新平衡當(dāng)前子樹(1114)。在重新平衡當(dāng)前子樹之后,構(gòu)造器線程108執(zhí)行圖13中所示出的操作“C”以完成元素插入操作1000。當(dāng)前子樹是克隆的當(dāng)前索引節(jié)點(diǎn)的左子樹,克隆的當(dāng)前索引節(jié)點(diǎn),以及克隆的當(dāng)前索引節(jié)點(diǎn)的右子樹。
當(dāng)當(dāng)前子樹被重新平衡時,當(dāng)前子樹中的索引節(jié)點(diǎn)被重新排列,以便索引樹中的每一個節(jié)點(diǎn)的左子樹的深度和右子樹的深度相差不超過一個。此外,當(dāng)當(dāng)前子樹被重新平衡時,當(dāng)前子樹還維持排序?qū)傩?。排序?qū)傩砸?guī)定,對于當(dāng)前子樹中的每一個給定索引節(jié)點(diǎn), 給定索引節(jié)點(diǎn)的左子樹中的索引節(jié)點(diǎn)與具有小于與給定索引節(jié)點(diǎn)相關(guān)聯(lián)的元素的虛擬偏移量的虛擬偏移量的元素相關(guān)聯(lián),而給定索引節(jié)點(diǎn)的右子樹中的索引節(jié)點(diǎn)與具有大于與給定索引節(jié)點(diǎn)相關(guān)聯(lián)的元素的虛擬偏移量的虛擬偏移量的元素相關(guān)聯(lián)。已知有多個現(xiàn)有的用于重新平衡諸如當(dāng)前索引樹之類的AVL樹的“樹旋轉(zhuǎn)”算法。
為在重新平衡過程中重新排列當(dāng)前樹中的索引節(jié)點(diǎn),構(gòu)造器線程108改變當(dāng)前子樹中的某些索引節(jié)點(diǎn)的左或右子節(jié)點(diǎn)屬性。如果構(gòu)造器線程108需要改變當(dāng)前子樹中的給定索引節(jié)點(diǎn)的左或右子節(jié)點(diǎn)屬性,則在改變給定索引節(jié)點(diǎn)的左或右子節(jié)點(diǎn)屬性之前,構(gòu)造器線程108克隆給定索引節(jié)點(diǎn)。
圖12是示出了示例元素插入操作1000的延續(xù)1200的流程圖。如圖12的示例所示,當(dāng)構(gòu)造器線程108克隆當(dāng)前索引節(jié)點(diǎn)時(1202),延續(xù)1200開始。然后,構(gòu)造器線程108 生成第一新索引節(jié)點(diǎn)(1204)。如果存在當(dāng)前索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性,則構(gòu)造器線程108 配置第一新索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性以指示當(dāng)前索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性(1206)。以此方式,當(dāng)前索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性變?yōu)榈谝恍滤饕?jié)點(diǎn)的左子節(jié)點(diǎn)屬性。然后,構(gòu)造器線程 108配置克隆的當(dāng)前索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性以指示第一新索引節(jié)點(diǎn)(1208)。以此方式, 第一新索引節(jié)點(diǎn)變?yōu)榭寺〉漠?dāng)前索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性。
接下來,構(gòu)造器線程108克隆當(dāng)前片段描述符(1212)。當(dāng)構(gòu)造器線程108克隆當(dāng)前片段描述符時,構(gòu)造器線程108生成此處被稱為克隆的當(dāng)前片段描述符的新片段描述符。 克隆的當(dāng)前片段描述符最初與當(dāng)前片段描述符具有相同偏移屬性和長度屬性。構(gòu)造器線程 108修改克隆的當(dāng)前片段描述符(1212)。構(gòu)造器線程108修改克隆的當(dāng)前片段描述符,以便當(dāng)前片段僅限于具有小于插入的元素的虛擬偏移量的虛擬偏移量的元素。例如,如果當(dāng)前片段包括具有真實(shí)偏移量10到20的元素,則當(dāng)前片段描述符的長度屬性是21。在此示例中,插入的元素具有具有真實(shí)偏移量15和16的元素的虛擬偏移量之間的虛擬偏移量。因此,在此示例中,構(gòu)造器線程108修改克隆的當(dāng)前片段描述符的長度屬性,以便長度屬性具有值6而不是21。然后,構(gòu)造器線程108配置第一新索引節(jié)點(diǎn)的描述符屬性以指示克隆的當(dāng)前片段描述符(1214)。
接下來,構(gòu)造器線程108生成第一新片段描述符(1216)。第一新片段描述符指示當(dāng)前片段。然后,構(gòu)造器線程108配置克隆的當(dāng)前索引節(jié)點(diǎn)的描述符屬性以指示第一新的片段描述符(1218)。
然后,構(gòu)造器線程108生成第二新索引節(jié)點(diǎn)(1220)。如果當(dāng)前索引節(jié)點(diǎn)的右子節(jié)點(diǎn)屬性存在,則構(gòu)造器線程108配置第二新索引節(jié)點(diǎn),以便當(dāng)前索引節(jié)點(diǎn)的右子節(jié)點(diǎn)屬性是第二新索引節(jié)點(diǎn)的右子節(jié)點(diǎn)屬性(1222)。接下來,構(gòu)造器線程108配置克隆的當(dāng)前索引節(jié)點(diǎn)的右子節(jié)點(diǎn)屬性,以便克隆的當(dāng)前索引節(jié)點(diǎn)的右子節(jié)點(diǎn)屬性指示第二新索引節(jié)點(diǎn) (1224)。
然后,構(gòu)造器線程108生成第二新片段描述符(1226)。第二新片段描述符指示以前在當(dāng)前片段中的具有大于插入的的元素的虛擬偏移量的虛擬偏移量的元素。例如,如果當(dāng)前片段包括具有真實(shí)偏移量10到20的元素并且最左邊的插入的元素具有在具有真實(shí)偏移量15和16的元素的虛擬偏移量之間的虛擬偏移量,則第二新片段描述符具有偏移屬性 16和長度屬性5。在此示例中,具有16和20之間的真實(shí)偏移量的元素是以前在當(dāng)前片段中的并且具有大于插入的元素的虛擬偏移量的虛擬偏移量的元素。
然后,構(gòu)造器線程108配置第二新索引節(jié)點(diǎn)的描述符屬性以指示第二新片段描述符(1228)。在配置第二新索引節(jié)點(diǎn)的描述符屬性以指示第二新片段描述符之后,構(gòu)造器線程108,在必要時重新平衡當(dāng)前子樹(1230)。在重新平衡當(dāng)前子樹之后,構(gòu)造器線程108執(zhí)行圖13中所示出的操作“C”以完成元素插入操作1000。
圖13是示出了示例元素插入操作1000的延續(xù)1300的流程圖。如圖13的示例所示,當(dāng)構(gòu)造器線程108設(shè)置當(dāng)前節(jié)點(diǎn)指針以指示克隆的當(dāng)前索引節(jié)點(diǎn)時(1302),延續(xù)1300 開始。以此方式,克隆的當(dāng)前索引節(jié)點(diǎn)變?yōu)椤爱?dāng)前”索引節(jié)點(diǎn)。
接下來,構(gòu)造器線程108確定堆棧上是否有任何索引節(jié)點(diǎn)(1304)。如果在堆棧上有一個或多個索引節(jié)點(diǎn),則構(gòu)造器線程108使一索引節(jié)點(diǎn)從堆棧中退棧(1306)。然后,構(gòu)造器線程108克隆該已退棧索引節(jié)點(diǎn)(1308)。當(dāng)構(gòu)造器線程108克隆已退棧索引節(jié)點(diǎn)時,構(gòu)造器線程108生成此處被稱為克隆的已退棧索引節(jié)點(diǎn)的新索引節(jié)點(diǎn)。當(dāng)構(gòu)造器線程108克隆已退棧索引節(jié)點(diǎn)時,克隆的已退棧索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性、右子節(jié)點(diǎn)屬性,以及描述符屬性與已退棧索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性、右子節(jié)點(diǎn)屬性,以及描述符屬性相同。
在克隆已退棧索引節(jié)點(diǎn)之后,構(gòu)造器線程108確定與已退棧索引節(jié)點(diǎn)相關(guān)聯(lián)的片段的虛擬偏移量是否小于與當(dāng)前索引節(jié)點(diǎn)相關(guān)聯(lián)的片段的虛擬偏移量(1310)。如果與已退棧索引節(jié)點(diǎn)相關(guān)聯(lián)的片段的虛擬偏移量小于與當(dāng)前索引節(jié)點(diǎn)相關(guān)聯(lián)的片段的虛擬偏移量 (1310的“是”),則構(gòu)造器線程108設(shè)置克隆的已退棧索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性以指示當(dāng)前索引節(jié)點(diǎn)(1312)。以此方式,當(dāng)前索引節(jié)點(diǎn)變?yōu)榭寺〉囊淹藯K饕?jié)點(diǎn)的左子節(jié)點(diǎn)屬性。
否則,如果與已退棧索引節(jié)點(diǎn)相關(guān)聯(lián)的片段的虛擬偏移量不小于(S卩,大于)與當(dāng)前索引節(jié)點(diǎn)相關(guān)聯(lián)的片段的虛擬偏移量(1310的“否”),則構(gòu)造器線程108設(shè)置克隆的已退棧索引節(jié)點(diǎn)的右子節(jié)點(diǎn)屬性以指示當(dāng)前索引節(jié)點(diǎn)(1314)。以此方式,當(dāng)前索引節(jié)點(diǎn)變?yōu)榭寺〉囊淹藯K饕?jié)點(diǎn)的右子節(jié)點(diǎn)屬性。
在設(shè)置克隆的已退棧索引節(jié)點(diǎn)的左或右子節(jié)點(diǎn)屬性之后,構(gòu)造器線程108設(shè)置當(dāng)前節(jié)點(diǎn)指針,以指示克隆的已退棧索引節(jié)點(diǎn)(1316)。以此方式,克隆的已退棧索引節(jié)點(diǎn)變?yōu)椤爱?dāng)前”索引節(jié)點(diǎn)。在設(shè)置當(dāng)前節(jié)點(diǎn)指針以表示克隆的已退棧索引節(jié)點(diǎn)之后,構(gòu)造器線程 108再次確定堆棧上是否有任何索引節(jié)點(diǎn)(1304)。如果在堆棧上有索引節(jié)點(diǎn),則構(gòu)造器線程108重復(fù)步驟1306、1308、1310、1312或1314、1316,以及1318。否則,如果在堆棧上沒有索引節(jié)點(diǎn),則構(gòu)造器線程108設(shè)置當(dāng)前樹指針以指示當(dāng)前索引節(jié)點(diǎn)(1320)。在設(shè)置當(dāng)前樹指針以指示當(dāng)前索引節(jié)點(diǎn)之后,元素插入操作1000完成。此外,在構(gòu)造器線程108設(shè)置當(dāng)前樹指針之后,文檔106的活動表示變?yōu)槲臋n106的最近可用的非活動表示。
圖14是示出了示例元素刪除操作1400的流程圖。如圖14的示例所示,當(dāng)構(gòu)造器線程108接收到指示元素將被從文檔106中刪除的輸入時(1402),元素刪除操作1400開始。
響應(yīng)于接收到輸入,構(gòu)造器線程108設(shè)置當(dāng)前節(jié)點(diǎn)指針以指示索引樹300的最近可用的非活動版本最近的根索引節(jié)點(diǎn)(1404)。換言之,構(gòu)造器線程108設(shè)置當(dāng)前節(jié)點(diǎn)指針等于當(dāng)前樹指針。
接下來,構(gòu)造器線程108確定最左邊的刪除的元素的虛擬偏移量是否小于當(dāng)前片段的虛擬偏移量(1406)。當(dāng)前片段是由當(dāng)前索引節(jié)點(diǎn)所指示的片段描述符所指示的真實(shí)元素陣列304的片段。如果最左邊的刪除的元素的虛擬偏移量小于當(dāng)前片段的虛擬偏移量 (1406的“是”),則構(gòu)造器線程108使當(dāng)前索引節(jié)點(diǎn)進(jìn)棧到堆棧上(1408)。在使當(dāng)前索引節(jié)點(diǎn)進(jìn)棧到堆棧上之后,構(gòu)造器線程108設(shè)置當(dāng)前節(jié)點(diǎn)指針以指示當(dāng)前索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性(1410)。以此方式,當(dāng)前索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性變?yōu)椤爱?dāng)前”索引節(jié)點(diǎn)。在設(shè)置當(dāng)前18節(jié)點(diǎn)指針之后,構(gòu)造器線程108再次確定最左邊的刪除的元素的虛擬偏移量是否小于當(dāng)前片段的虛擬偏移量(1406)。只要最左邊的刪除的元素的虛擬偏移量小于當(dāng)前片段的虛擬偏移量,構(gòu)造器線程108就持續(xù)重復(fù)步驟1408和1410。
如果最左邊的刪除的元素的虛擬偏移量不小于當(dāng)前片段的虛擬偏移量(1406的 “不是”),則構(gòu)造器線程108確定最左邊的刪除的元素的虛擬偏移量是否與當(dāng)前片段的虛擬偏移量相同(1412)。如果構(gòu)造器線程108確定最左邊的刪除的元素的虛擬偏移量與當(dāng)前片段的虛擬偏移量相同(1412的“是”),則構(gòu)造器線程108執(zhí)行圖15中所示出的操作“A”。在構(gòu)造器線程108執(zhí)行操作“A”之后,構(gòu)造器線程108執(zhí)行圖18中所示出的操作“C”,以完成元素刪除操作1400。
如果構(gòu)造器線程108確定最左邊的刪除的元素的虛擬偏移量不與當(dāng)前片段的虛擬偏移量相同(1412的“否”),則構(gòu)造器線程108確定最左邊的刪除的元素是否在當(dāng)前片段的虛擬偏移量的范圍內(nèi)(1414)。如果構(gòu)造器線程108確定最左邊的刪除的元素的虛擬偏移量在當(dāng)前片段的的虛擬偏移量的范圍內(nèi)(1414的“是”),則構(gòu)造器線程108執(zhí)行圖16中所示出的操作“B”。在構(gòu)造器線程108執(zhí)行操作“B”之后,構(gòu)造器線程108執(zhí)行圖18中所示出的操作“C”,以完成元素刪除操作1400。
否則,如果構(gòu)造器線程108確定最左邊的刪除的元素的虛擬偏移量不在當(dāng)前片段的虛擬偏移量的范圍內(nèi)(1414的“否”),則構(gòu)造器線程108使當(dāng)前索引節(jié)點(diǎn)進(jìn)棧到堆棧上(1416)。然后,構(gòu)造器線程108設(shè)置當(dāng)前節(jié)點(diǎn)指針以指示當(dāng)前索引節(jié)點(diǎn)的右子節(jié)點(diǎn)屬性 (1418)。以此方式,當(dāng)前索引節(jié)點(diǎn)的右子節(jié)點(diǎn)屬性變?yōu)椤爱?dāng)前”索引節(jié)點(diǎn)。在設(shè)置當(dāng)前節(jié)點(diǎn)指針以指示當(dāng)前索引節(jié)點(diǎn)的右子節(jié)點(diǎn)屬性之后,構(gòu)造器線程108確定最左邊的刪除的元素的虛擬偏移量是否小于當(dāng)前片段的虛擬偏移量(1406)。構(gòu)造器線程108持續(xù)執(zhí)行步驟 1406、1408、1410、1412、1414、1416,以及1418,直到最左邊的刪除的元素的虛擬偏移量與當(dāng)前片段的虛擬偏移量相同或者最左邊的刪除的元素在當(dāng)前片段的虛擬偏移量的范圍內(nèi)。
圖15是示出了示例元素刪除操作1400的延續(xù)1500的流程圖。如圖15的示例所示,當(dāng)構(gòu)造器線程108確定刪除的元素是否是當(dāng)前片段中的全部元素(1502)時,延續(xù)1500 開始。
如果刪除的元素不是當(dāng)前片段中的全部元素(1502的“否”),則構(gòu)造器線程108克隆當(dāng)前片段描述符(1504)。當(dāng)構(gòu)造器線程108克隆當(dāng)前片段描述符時,構(gòu)造器線程108生成此處被稱為克隆的當(dāng)前片段描述符的新片段描述符。克隆的當(dāng)前片段描述符最初與當(dāng)前片段描述符具有相同偏移屬性和長度屬性。
然后,構(gòu)造器線程108修改克隆的當(dāng)前片段描述符的偏移屬性,以便真實(shí)偏移屬性指示當(dāng)前片段在最右邊刪除的元素之后的當(dāng)前片段中的最左邊的元素的虛擬偏移量處啟動(1506)。例如,如果當(dāng)前片段包括真實(shí)偏移量10到20處的元素,而真實(shí)偏移量10和 11處的元素將被從文檔106的活動表示中刪除,則構(gòu)造器線程108修改當(dāng)前片段描述符的真實(shí)偏移屬性,以便真實(shí)偏移屬性是12。這是圖4的示例中所示出的情況。
然后,構(gòu)造器線程108克隆當(dāng)前索引節(jié)點(diǎn)(1508)。在克隆當(dāng)前索引節(jié)點(diǎn)之后,構(gòu)造器線程108配置克隆的當(dāng)前索引節(jié)點(diǎn)的描述符屬性以指示克隆的當(dāng)前片段描述符(1510)。 然后,構(gòu)造器線程108設(shè)置當(dāng)前節(jié)點(diǎn)指針以指示克隆的當(dāng)前索引節(jié)點(diǎn)(1512)。在設(shè)置當(dāng)前節(jié)點(diǎn)指針之后,構(gòu)造器線程108執(zhí)行圖18中所示出的操作“C”以完成元素刪除操作1400。
否則,如果刪除的元素是當(dāng)前片段中的元素中的全部(1502的“是”),則構(gòu)造器線程108確定當(dāng)前索引節(jié)點(diǎn)是否具有左子節(jié)點(diǎn)屬性(1514)。如果當(dāng)前索引節(jié)點(diǎn)具有左子節(jié)點(diǎn)屬性(1514的“是”),則構(gòu)造器線程108執(zhí)行圖16中所示出的操作“D”,然后執(zhí)行圖18中所示出的操作“C”,以完成元素刪除操作1400。
另一方面,如果當(dāng)前索引節(jié)點(diǎn)沒有左子節(jié)點(diǎn)屬性(1514的“否”),則構(gòu)造器線程 108確定當(dāng)前索引節(jié)點(diǎn)是否具有右子節(jié)點(diǎn)屬性(1516)。如果構(gòu)造器線程108確定當(dāng)前索引節(jié)點(diǎn)具有右子節(jié)點(diǎn)屬性(1518的“是”),則構(gòu)造器線程108克隆當(dāng)前索引節(jié)點(diǎn)(1518)。在克隆當(dāng)前索引節(jié)點(diǎn)之后,構(gòu)造器線程108配置克隆的當(dāng)前索引節(jié)點(diǎn)的描述符屬性以指示由當(dāng)前索引節(jié)點(diǎn)的右子節(jié)點(diǎn)屬性所指示的片段描述符(1520)。然后,構(gòu)造器線程108配置克隆的當(dāng)前索引節(jié)點(diǎn)的右子節(jié)點(diǎn)屬性以指示沒有索引節(jié)點(diǎn)(1522)。然后,構(gòu)造器線程108設(shè)置當(dāng)前節(jié)點(diǎn)指針以指示克隆的當(dāng)前索引節(jié)點(diǎn)(1512)。在設(shè)置當(dāng)前節(jié)點(diǎn)指針之后,構(gòu)造器線程 108執(zhí)行圖18中所示出的操作“C”以完成元素刪除操作1400。
如果當(dāng)前索引節(jié)點(diǎn)沒有右子節(jié)點(diǎn)屬性(1516的“否”),則構(gòu)造器線程108使索引節(jié)點(diǎn)從堆棧中退棧(1524)。已退棧索引節(jié)點(diǎn)是當(dāng)前索引節(jié)點(diǎn)的父節(jié)點(diǎn)。然后,構(gòu)造器線程108 克隆已退棧索引節(jié)點(diǎn)(1526)。接下來,構(gòu)造器線程108配置克隆的已退棧索引節(jié)點(diǎn)以便不指示當(dāng)前索引節(jié)點(diǎn)(1528)。以此方式,構(gòu)造器線程108從文檔106的活動表示中刪除當(dāng)前索引節(jié)點(diǎn)。然后,構(gòu)造器線程108設(shè)置當(dāng)前節(jié)點(diǎn)指針以指示克隆的已退棧索引節(jié)點(diǎn)(1530)。 以此方式,克隆的已退棧索引節(jié)點(diǎn)變?yōu)椤爱?dāng)前”索引節(jié)點(diǎn)。然后,構(gòu)造器線程108執(zhí)行圖18 中所示出的操作“C”以完成元素刪除操作1400。
圖16是示出了元素刪除操作1400的延續(xù)1600的流程圖。如圖16的示例所示, 當(dāng)構(gòu)造器線程108克隆當(dāng)前索引節(jié)點(diǎn)時(1602),延續(xù)1600開始。接下來,構(gòu)造器線程108 確定在當(dāng)前索引節(jié)點(diǎn)的左子樹中是否只有單個節(jié)點(diǎn)(1604)。如果在當(dāng)前索引節(jié)點(diǎn)的左子樹中只有單個節(jié)點(diǎn)(1604的“是”),則構(gòu)造器線程108配置克隆的當(dāng)前索引節(jié)點(diǎn)的描述符屬性以表示由當(dāng)前索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性所指示的片段描述符(1606)。以此方式,構(gòu)造器線程108從片段描述符表302的活動版本中刪除當(dāng)前片段描述符。接下來,構(gòu)造器線程108 配置克隆的當(dāng)前索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性以指示沒有其他索引節(jié)點(diǎn)(1608)。以此方式,構(gòu)造器線程108從索引樹300的活動版本中刪除左子節(jié)點(diǎn)屬性。
如果在當(dāng)前索引節(jié)點(diǎn)的左子樹中有一個以上的索引節(jié)點(diǎn)(1604的“否”),則構(gòu)造器線程108配置克隆的當(dāng)前索引節(jié)點(diǎn)的描述符屬性以表示由當(dāng)前索引節(jié)點(diǎn)的左子樹中的最右邊索引節(jié)點(diǎn)所指示的片段描述符(1610)。以此方式,構(gòu)造器線程108從片段描述符表的活動版本中刪除最初當(dāng)前索引節(jié)點(diǎn)所指示的片段描述符。為便于說明,本說明書將當(dāng)前索引節(jié)點(diǎn)的左子樹中的最右邊索引節(jié)點(diǎn)稱為“最右邊索引節(jié)點(diǎn)”。接下來,構(gòu)造器線程108 克隆當(dāng)前索引節(jié)點(diǎn)下面的最右邊索引節(jié)點(diǎn)的先輩索引節(jié)點(diǎn)(1612)。例如,如果在當(dāng)前索引節(jié)點(diǎn)和最右邊索引節(jié)點(diǎn)之間在索引樹300中有三個索引節(jié)點(diǎn),則構(gòu)造器線程108克隆這三個索引節(jié)點(diǎn)。
在克隆先輩索引節(jié)點(diǎn)之后,構(gòu)造器線程108配置最右邊索引節(jié)點(diǎn)的父節(jié)點(diǎn)的右子節(jié)點(diǎn)屬性以不指示任何索引節(jié)點(diǎn)(1614)。以此方式,從索引樹300的活動版本中刪除最右邊索引節(jié)點(diǎn)。然后,構(gòu)造器線程108連接最右邊索引節(jié)點(diǎn)的克隆的先輩索引節(jié)點(diǎn)(1616)。 例如,如果在當(dāng)前索引節(jié)點(diǎn)和最右邊索引節(jié)點(diǎn)之間在索引樹300中有三個索引節(jié)點(diǎn),則構(gòu)造器線程108配置這三個索引節(jié)點(diǎn)的克隆節(jié)點(diǎn)的左或右子節(jié)點(diǎn)屬性,以使得這三個索引節(jié)點(diǎn)的克隆節(jié)點(diǎn)具有與這三個索引節(jié)點(diǎn)相同的父子關(guān)系。
然后,構(gòu)造器線程108設(shè)置當(dāng)前節(jié)點(diǎn)指針以指示克隆的當(dāng)前索引節(jié)點(diǎn)(1618)。在設(shè)置當(dāng)前節(jié)點(diǎn)指針之后,構(gòu)造器線程108執(zhí)行圖18中所示出的操作“C”以完成元素刪除操作 1400。
圖17是示出了元素刪除操作1400的進(jìn)一步延續(xù)1700的流程圖。如圖17的示例所示,當(dāng)構(gòu)造器線程108克隆當(dāng)前片段描述符時(1702),延續(xù)1700開始。如上文所討論的, 當(dāng)前片段描述符是由當(dāng)前索引節(jié)點(diǎn)所指示的片段描述符。當(dāng)構(gòu)造器線程108克隆當(dāng)前片段描述符時,構(gòu)造器線程108生成此處被稱為克隆的當(dāng)前片段描述符的新片段描述符。至少一開始,克隆的當(dāng)前片段描述符與當(dāng)前片段描述符具有相同偏移屬性和長度屬性。接下來, 構(gòu)造器線程108克隆當(dāng)前索引節(jié)點(diǎn)(1704)。
然后,構(gòu)造器線程108確定在當(dāng)前片段中是否有具有大于刪除的元素的虛擬偏移量的虛擬偏移量的元素(1706)。如果在當(dāng)前片段中沒有具有大于刪除的元素的虛擬偏移量的虛擬偏移量的元素(1706的“否”),則構(gòu)造器線程108修改克隆的當(dāng)前片段描述符的長度屬性(1708)。構(gòu)造器線程108修改克隆的當(dāng)前片段描述符的長度屬性,以指示真實(shí)元素陣列304的不延伸到最左邊的刪除的元素的片段。例如,如果當(dāng)前片段包括具有真實(shí)偏移量 10到20的元素,而真實(shí)偏移量19和20處的元素將被從文檔106的活動表示中刪除,則構(gòu)造器線程108修改克隆的當(dāng)前片段描述符的長度屬性,以便長度屬性是9而不是11。在修改克隆的當(dāng)前片段描述符的長度屬性之后,構(gòu)造器線程108執(zhí)行圖18中所示出的操作“C” 以完成元素刪除操作1400。
接下來,構(gòu)造器線程108配置克隆的當(dāng)前索引節(jié)點(diǎn)的描述符屬性以指示克隆的當(dāng)前片段描述符(1710)。以此方式,克隆的當(dāng)前片段描述符變?yōu)橛煽寺〉漠?dāng)前索引節(jié)點(diǎn)所指示的片段描述符。在配置克隆的當(dāng)前索引節(jié)點(diǎn)的描述符屬性以指示克隆的當(dāng)前片段描述符之后,構(gòu)造器線程108設(shè)置當(dāng)前節(jié)點(diǎn)指針以指示克隆的當(dāng)前索引節(jié)點(diǎn)(1712)。然后,構(gòu)造器線程108執(zhí)行圖18的示例中所示出的操作“C”以完成元素刪除操作1400。
否則,如果在當(dāng)前片段中有一個或多個具有大于刪除的元素的虛擬偏移量的虛擬偏移量的元素(1706的“是”),則構(gòu)造器線程108修改克隆的當(dāng)前片段描述符的長度屬性, 以便克隆的當(dāng)前片段描述符指示真實(shí)元素陣列304的只延長到最左邊的刪除的元素的片段(1714)。例如,如果當(dāng)前片段包括具有真實(shí)偏移量10到20的元素,而具有真實(shí)偏移量15 和16的元素將被從文檔106的活動表示中刪除,則構(gòu)造器線程108修改克隆的當(dāng)前片段描述符的長度屬性,以便長度屬性是5。
在修改克隆的當(dāng)前片段描述符的長度屬性之后,構(gòu)造器線程108生成新索引節(jié)點(diǎn) (1716)。如果當(dāng)前索引節(jié)點(diǎn)具有左子節(jié)點(diǎn)屬性,則構(gòu)造器線程108配置新索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性以指示當(dāng)前索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性(1718)。以此方式,當(dāng)前索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性變?yōu)樾滤饕?jié)點(diǎn)的左子節(jié)點(diǎn)屬性。然后,構(gòu)造器線程108配置新索引節(jié)點(diǎn)的描述符屬性以指示克隆的當(dāng)前片段描述符(1720)。以此方式,克隆的當(dāng)前片段描述符變?yōu)橛尚碌乃饕?jié)點(diǎn)所指示的片段描述符。
然后,構(gòu)造器線程108生成新片段描述符(1722)。新片段描述符指示包含是具有大于刪除的元素的虛擬偏移量的虛擬偏移量的當(dāng)前片段的一部分的元素的真實(shí)元素陣列304的片段。例如,如果當(dāng)前片段包括具有真實(shí)偏移量10到20的元素并且刪除的元素是具有真實(shí)偏移量15和16的元素,則新片段描述符具有17的真實(shí)偏移屬性和4的長度屬性。
接下來,構(gòu)造器線程108配置克隆的當(dāng)前索引節(jié)點(diǎn)的描述符屬性以指示新的片段描述符(1724)。然后,構(gòu)造器線程108配置克隆的當(dāng)前索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性以指示新索引節(jié)點(diǎn)(1726)。以此方式,新索引節(jié)點(diǎn)變?yōu)榭寺〉漠?dāng)前索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性。然后, 構(gòu)造器線程108重新平衡當(dāng)前子樹(1728)。在重新平衡當(dāng)前子樹之后,構(gòu)造器線程108設(shè)置當(dāng)前節(jié)點(diǎn)指針以指示當(dāng)前子樹的根節(jié)點(diǎn)(1730)。然后,構(gòu)造器線程108執(zhí)行圖18中所示出的操作“C”以完成元素刪除操作1400。
圖18是示出了元素刪除操作1400的進(jìn)一步延續(xù)1800的流程圖。如圖18的示例所示,當(dāng)構(gòu)造器線程108確定堆棧上是否有任何索引節(jié)點(diǎn)時(1802),延續(xù)1800開始。
如果在堆棧上有任何索引節(jié)點(diǎn)(1802的“是”),則構(gòu)造器線程108使索引節(jié)點(diǎn)從堆棧中退棧(1804)。然后,構(gòu)造器線程108克隆已退棧索引節(jié)點(diǎn)(1806)。當(dāng)構(gòu)造器線程108 克隆已退棧索引節(jié)點(diǎn)時,構(gòu)造器線程108生成此處被稱為克隆的已退棧索引節(jié)點(diǎn)的新索引節(jié)點(diǎn)。當(dāng)構(gòu)造器線程108克隆已退棧索引節(jié)點(diǎn)時,克隆的已退棧索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性、 右子節(jié)點(diǎn)屬性,以及描述符屬性與已退棧索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性、右子節(jié)點(diǎn)屬性,以及描述符屬性具有相同值。
在克隆已退棧索引節(jié)點(diǎn)之后,構(gòu)造器線程108確定與已退棧索引節(jié)點(diǎn)相關(guān)聯(lián)的片段的虛擬偏移量是否小于與當(dāng)前索引節(jié)點(diǎn)相關(guān)聯(lián)的片段的虛擬偏移量(1808)。如果與已退棧索引節(jié)點(diǎn)相關(guān)聯(lián)的片段的虛擬偏移量小于與當(dāng)前索引節(jié)點(diǎn)相關(guān)聯(lián)的片段的虛擬偏移量 (1808的“是”),則構(gòu)造器線程108設(shè)置克隆的已退棧索引節(jié)點(diǎn)的左子節(jié)點(diǎn)屬性以指示當(dāng)前索引節(jié)點(diǎn)(1810)。以此方式,當(dāng)前節(jié)點(diǎn)變?yōu)榭寺〉囊淹藯K饕?jié)點(diǎn)的左子節(jié)點(diǎn)屬性。
否則,如果與已退棧索引節(jié)點(diǎn)相關(guān)聯(lián)的片段的虛擬偏移量不小于(S卩,大于)與當(dāng)前索引節(jié)點(diǎn)相關(guān)聯(lián)的片段的虛擬偏移量(1808的“否”),則構(gòu)造器線程108設(shè)置克隆的已退棧索引節(jié)點(diǎn)的右子節(jié)點(diǎn)屬性以表示當(dāng)前索引節(jié)點(diǎn)(1812)。以此方式,當(dāng)前索引節(jié)點(diǎn)變?yōu)榭寺〉囊淹藯K饕?jié)點(diǎn)的右子節(jié)點(diǎn)屬性。
在設(shè)置克隆的已退棧索引節(jié)點(diǎn)的左或右子節(jié)點(diǎn)屬性之后,構(gòu)造器線程108設(shè)置當(dāng)前節(jié)點(diǎn)指針,以指示克隆的已退棧索引節(jié)點(diǎn)(1814)。以此方式,克隆的已退棧索引節(jié)點(diǎn)變?yōu)椤爱?dāng)前”索引節(jié)點(diǎn)。在設(shè)置當(dāng)前節(jié)點(diǎn)指針以指示克隆的已退棧索引節(jié)點(diǎn)之后,構(gòu)造器線程 108再次確定堆棧上是否有任何索引節(jié)點(diǎn)(1802)。如果在堆棧上有索引節(jié)點(diǎn),則構(gòu)造器線程108重復(fù)步驟1804、1806、1808、1810或1812、1814,以及1816。否則,如果在堆棧上沒有索引節(jié)點(diǎn),則構(gòu)造器線程108設(shè)置當(dāng)前樹指針以指示當(dāng)前索引節(jié)點(diǎn)(1818)。在設(shè)置當(dāng)前樹指針以指示當(dāng)前索引節(jié)點(diǎn)之后,元素刪除操作1400完成。此外,在構(gòu)造器線程108設(shè)置當(dāng)前樹指針之后,文檔106的活動表示變?yōu)槲臋n106的最近可用的非活動表示。
圖19是示出了讀取器線程IlOA的示例操作1900的流程圖。雖然操作1900是參考讀取器線程IlOA來描述的,但是,操作1900可以由讀取器線程110中的任何一個來執(zhí)行。
當(dāng)應(yīng)用104喚醒讀取器線程IlOA時,讀取器線程IlOA的操作1900開始。當(dāng)讀取器線程IlOA醒來時,讀取器線程IlOA確定是否存在當(dāng)前非活動的索引樹(1902)。當(dāng)前非活動的索引樹是由當(dāng)前樹指針?biāo)硎镜乃饕龢?。由于?dāng)前樹指針表示索引樹的最近的可用的非活動版本,因此,當(dāng)前索引樹是索引樹的最近可用的非活動版本。讀取器線程IlOA確定當(dāng)當(dāng)前樹指針包含空值時當(dāng)前索引樹不存在。如果當(dāng)前索引樹不存在(1904的“否”),則讀取器線程IlOA隨后再次確定當(dāng)前索引樹是否存在(1904)。讀取器線程IlOA持續(xù)確定當(dāng)前索引樹是否存在,直到當(dāng)前索引樹存在。
如果讀取器線程IlOA確定當(dāng)前索引樹存在(1904的“是”),則讀取器線程IlOA 確定當(dāng)前索引樹是否具有根索引節(jié)點(diǎn)(1906)。在某些實(shí)施例中,當(dāng)前索引樹是可以包含索引節(jié)點(diǎn)的軟件對象。在這樣的實(shí)施例中,當(dāng)這樣的軟件對象被實(shí)例化時,當(dāng)前索引樹可以存在,不管軟件對象是否包含任何索引節(jié)點(diǎn)。如果當(dāng)前索引樹沒有根索引節(jié)點(diǎn)(1906的 “否”),則讀取器線程IlOA隨后再次確定當(dāng)前索引樹是否具有根索引節(jié)點(diǎn)(1906)。讀取器線程11OA持續(xù)確定當(dāng)前索引樹是否具有根索引節(jié)點(diǎn),直到當(dāng)前索引樹具有根索引節(jié)點(diǎn)。
如果當(dāng)前索引樹有根索引節(jié)點(diǎn),則讀取器線程IlOA設(shè)置讀取指針以指示當(dāng)前索引樹的根索引節(jié)點(diǎn)(1908)。如此處所使用的,根讀取節(jié)點(diǎn)是由讀取指針?biāo)硎镜乃饕?jié)點(diǎn)。 然后,讀取器線程IlOA執(zhí)行讀取索引樹中的索引節(jié)點(diǎn)的深度優(yōu)先遍歷(1910)。讀取索引樹是其根讀取節(jié)點(diǎn)是根的索引樹。隨著讀取器線程IlOA遍歷讀取索引樹中的索引節(jié)點(diǎn),讀取器線程IlOA可以對與索引節(jié)點(diǎn)相關(guān)聯(lián)的元素執(zhí)行各種動作。例如,讀取器線程IlOA可以執(zhí)行拼寫檢查操作,該操作檢查與索引節(jié)點(diǎn)相關(guān)聯(lián)的元素中的單詞的拼寫。在另一示例中, 讀取器線程IlOA可以基于與索引節(jié)點(diǎn)相關(guān)聯(lián)的元素中的單詞來更新搜索索引。在再一個示例中,讀取器線程IIOA可以將元素寫入到(例如,保存)到本地或遠(yuǎn)程存儲位置。由于讀取器線程IlOA可以與構(gòu)造器線程108并發(fā)地操作,因此,用戶102可能不會感覺到由于讀取器線程IlOA的操作所造成的構(gòu)造器線程108的性能的任何延遲或速度減慢。
在執(zhí)行讀取索引樹中的索引節(jié)點(diǎn)的完整的遍歷之后,讀取器線程IlOA確定讀取器線程IlOA的操作是否完成(1912)。如果讀取器線程IlOA的操作完成(1912的“是”),則讀取器線程IlOA休眠(1914)。
否則,如果讀取器線程IlOA的操作未完成(1912的“否”),則讀取器線程IlOA設(shè)置讀取指針以指示當(dāng)前索引樹的根索引節(jié)點(diǎn)(1908)。隨著讀取器線程IlOA遍歷讀取索引樹中的索引節(jié)點(diǎn),構(gòu)造器線程108可以并發(fā)地執(zhí)行,執(zhí)行元素插入和/或元素刪除操作。由于構(gòu)造器線程108不會改變讀取索引樹中的任何索引節(jié)點(diǎn)的屬性,因此,確保了來自讀取索引樹的讀取操作的邏輯一致性。然而,構(gòu)造器線程108可以更新當(dāng)前樹指針以表示另一索引樹。因此,當(dāng)讀取器線程IlOA設(shè)置讀取指針以指示當(dāng)前索引樹的根索引節(jié)點(diǎn)時,當(dāng)前索引樹可以是與讀取器線程IlOA剛剛遍歷的讀取索引樹不同的索引樹。以此方式,讀取器線程IlOA開始遍歷最當(dāng)前的索引樹。
圖20是示出了示例計(jì)算設(shè)備2000的框圖。在一些實(shí)施例中,計(jì)算系統(tǒng)100是使用類似計(jì)算設(shè)備2000的一個或多個計(jì)算設(shè)備來實(shí)現(xiàn)的。應(yīng)當(dāng)理解,在其他實(shí)施例中,計(jì)算系統(tǒng)100是使用還具有除了圖20的示例所示的硬件組件之外的硬件組件的計(jì)算設(shè)備來實(shí)現(xiàn)的。
計(jì)算系統(tǒng)是包括一個或多個計(jì)算設(shè)備的系統(tǒng)。計(jì)算設(shè)備是能夠處理信息的物理設(shè)備。計(jì)算設(shè)備的示例類型包括臺式計(jì)算機(jī)、膝上型計(jì)算機(jī)、獨(dú)立服務(wù)器計(jì)算機(jī)、刀片式服務(wù)器計(jì)算機(jī)、移動電話、個人媒體播放器、視頻游戲控制臺、集成到車輛中的計(jì)算機(jī)、電視機(jī)機(jī)頂盒、中間網(wǎng)絡(luò)設(shè)備,及其他類型的能夠處理信息的物理設(shè)備。
在不同的實(shí)施例中,計(jì)算設(shè)備是以不同的方式實(shí)現(xiàn)的。例如,在圖20的示例中,計(jì)算設(shè)備2000包括存儲器2002、處理系統(tǒng)2004、輔助存儲設(shè)備2006、網(wǎng)絡(luò)接口卡2008、視頻接口 2010、顯示設(shè)備2012、外部組件接口 2014、外部存儲設(shè)備2016、輸入設(shè)備2018、打印機(jī) 2020、以及通信介質(zhì)2022。在其他實(shí)施例中,計(jì)算設(shè)備是使用多一些或少一些的硬件組件來實(shí)現(xiàn)的。例如,在另一示例實(shí)施例中,計(jì)算設(shè)備不包括視頻接口、顯示設(shè)備、外部存儲設(shè)備或輸入設(shè)備。
存儲器2002是數(shù)據(jù)存儲系統(tǒng)。數(shù)據(jù)存儲系統(tǒng)是包括一個或多個計(jì)算機(jī)可讀數(shù)據(jù)存儲介質(zhì)的系統(tǒng)。計(jì)算機(jī)可讀數(shù)據(jù)存儲介質(zhì)是存儲可由計(jì)算設(shè)備讀取的數(shù)據(jù)和/或計(jì)算機(jī)可執(zhí)行指令的有形的設(shè)備或制品。在不同的實(shí)施例中,存儲器2002是以不同的方式實(shí)現(xiàn)的。例如,在各實(shí)施例中,存儲器2002是使用各種類型的計(jì)算機(jī)可讀數(shù)據(jù)存儲介質(zhì)來實(shí)現(xiàn)的。計(jì)算機(jī)可讀數(shù)據(jù)存儲介質(zhì)示例類型包括,但不僅限于,動態(tài)隨機(jī)存取存儲器(DRAM)、 雙倍數(shù)據(jù)速率同步動態(tài)隨機(jī)存取存儲器(DDR SDRAM)、延遲縮短的DRAM、DDR2 SDRAM、 DDR3SDRAM、Rambus RAM、固態(tài)存儲器、閃存、只讀存儲器(ROM)、電可擦可編程只讀存儲器, 及其他類型的存儲數(shù)據(jù)的設(shè)備和/或制品。
處理系統(tǒng)2004是包括一個或多個處理單元的系統(tǒng)。處理單元包括有選擇地執(zhí)行軟件指令的一個或多個物理集成電路。在各實(shí)施例中,處理系統(tǒng)2004是以各種方式實(shí)現(xiàn)的。例如,在一個示例實(shí)施例中,處理系統(tǒng)2004被實(shí)現(xiàn)為一個或多個處理核。例如,在此示例實(shí)施例中,處理系統(tǒng)2004可以被實(shí)現(xiàn)為一個或多個Intel Core 2微處理器。在另一不例實(shí)施例中,處理系統(tǒng)2004被實(shí)現(xiàn)為一個或多個單獨(dú)的微處理器。在再一個示例實(shí)施例中, 處理系統(tǒng)2004被實(shí)現(xiàn)為提供專用功能的ASIC。在再一個示例實(shí)施例中,處理系統(tǒng)2004通過使用ASIC并通過執(zhí)行軟件指令來提供專用功能。
在不同的實(shí)施例中,處理系統(tǒng)2004執(zhí)行不同的指令集中的軟件指令。例如,在各實(shí)施例中,處理系統(tǒng)2004執(zhí)行諸如x86指令集、POWER指令集、RISC指令集、SPARC指令集、 IA-64指令集、MIPS指令集之類的指令集和/或其他指令集中的軟件指令。
輔助存儲設(shè)備2006包括一個或多個計(jì)算機(jī)可讀數(shù)據(jù)存儲介質(zhì)。輔助存儲設(shè)備 2006存儲不能被處理系統(tǒng)2004直接訪問的數(shù)據(jù)和軟件指令。換言之,處理系統(tǒng)2004執(zhí)行輸入/輸出操作以從輔助存儲設(shè)備2006檢索數(shù)據(jù)和/或軟件指令。在各實(shí)施例中,輔助存儲設(shè)備2006是通過各種類型的計(jì)算機(jī)可讀數(shù)據(jù)存儲介質(zhì)來實(shí)現(xiàn)的。例如,輔助存儲器設(shè)備 2006可以通過一個或多個磁盤、磁帶驅(qū)動器、⑶-ROM光盤、DVD-ROM光盤、藍(lán)光光盤、固態(tài)存儲設(shè)備、Bernoulli盒式磁帶,和/或其他類型的計(jì)算機(jī)可讀取的數(shù)據(jù)存儲介質(zhì)來實(shí)現(xiàn)。
網(wǎng)絡(luò)接口卡2008使計(jì)算設(shè)備2000能從計(jì)算機(jī)通信網(wǎng)絡(luò)接收數(shù)據(jù)并向其發(fā)送數(shù)據(jù)。在不同的實(shí)施例中,網(wǎng)絡(luò)接口卡2008是以不同的方式實(shí)現(xiàn)的。例如,在各實(shí)施例中, 網(wǎng)絡(luò)接口卡2008被實(shí)現(xiàn)為以太網(wǎng)接口、令牌環(huán)網(wǎng)絡(luò)接口、光纖網(wǎng)絡(luò)接口、無線網(wǎng)絡(luò)接口(例如,WiFi、WiMax等等),或另一種類型的網(wǎng)絡(luò)接口。
視頻接口 2010使計(jì)算設(shè)備2000能向顯示設(shè)備2012輸出視頻信息。在不同的實(shí)施例中,視頻接口 2010是以不同的方式實(shí)現(xiàn)的。例如,在一個示例實(shí)施例中,視頻接口 2010被集成到計(jì)算設(shè)備2000的主板中。在另一示例實(shí)施例中,視頻接口 2010是視頻擴(kuò)展卡。示例類型的視頻擴(kuò)展卡包括由安大略省馬克姆市的ATI Technologies有限公司制造的Radeon 圖形卡、由加利福尼亞州圣克拉拉市的Nvidia (英偉達(dá))公司制造的Geforce圖形卡和其他類型的圖形卡。
在各實(shí)施例中,顯示設(shè)備2012被實(shí)現(xiàn)為各種類型的顯示設(shè)備。顯示設(shè)備的示例類型包括,但不僅限于,陰極射線管顯示器、LCD顯示面板、等離子屏幕顯示面板、觸敏顯示面板、LED屏幕、投影儀,及其他類型的顯示設(shè)備。在各實(shí)施例中,視頻接口 2010以各種方式與顯示設(shè)備2012通信。例如,在各實(shí)施例中,視頻接口 2010通過通用串行總線(USB)連接器、VGA連接器、數(shù)字可視接口(DVI)連接器、S-Video (S視頻)連接器、高清晰度多媒體接口(HDMI)接口、DisplayPort (顯示端口)連接器,或其他類型的連接器來與顯示設(shè)備2012 進(jìn)行通信。
外部組件接口 2014使計(jì)算設(shè)備2000能與外部設(shè)備進(jìn)行通信。在各實(shí)施例中,外部組件接口 2014是以不同的方式實(shí)現(xiàn)的。例如,在一個示例實(shí)施例中,外部組件接口 2014 是USB接口。在其他示例實(shí)施例中,計(jì)算設(shè)備2000是FireWire (火線)接口、串行端口接口、并行端口接口、PS/2接口,和/或使計(jì)算設(shè)備2000能與外部組件進(jìn)行通信的另一種類型的接口。
在不同的實(shí)施例中,外部組件接口 2014使計(jì)算組件2000能與不同的外部組件進(jìn)行通信。例如,在圖20的示例中,外部組件接口 2014使計(jì)算設(shè)備2000能與外部存儲設(shè)備 2016、輸入設(shè)備2018,以及打印機(jī)2020進(jìn)行通信。在其他實(shí)施例中,外部組件接口 2014使計(jì)算組件2000能與多一些或少一些的外部組件進(jìn)行通信。外部組件的其他示例類型包括, 但不僅限于,揚(yáng)聲器、電話充電插孔、調(diào)制解調(diào)器、媒體播放器對接器,其他計(jì)算設(shè)備、掃描儀、數(shù)碼相機(jī)、指紋讀取器、及其他可以連接到計(jì)算設(shè)備2000的設(shè)備。
外部存儲設(shè)備2016是包括一個或多個計(jì)算機(jī)可讀數(shù)據(jù)存儲介質(zhì)的外部組件。計(jì)算設(shè)備2000的不同的實(shí)現(xiàn)與不同類型的外部存儲設(shè)備進(jìn)行連接。外部存儲設(shè)備的示例類型包括,但不僅限于,磁帶驅(qū)動器、閃存模塊、磁盤驅(qū)動器、光盤驅(qū)動器、閃存單元、zip磁盤驅(qū)動器、光學(xué)點(diǎn)播機(jī)、及其他類型的包括一個或多個計(jì)算機(jī)可讀數(shù)據(jù)存儲介質(zhì)的設(shè)備。輸入設(shè)備2018是向計(jì)算設(shè)備2000的提供用戶輸入的外部組件。計(jì)算設(shè)備2000的不同的實(shí)現(xiàn)與不同類型的輸入設(shè)備進(jìn)行連接。輸入設(shè)備的示例類型包括,但不僅限于,鍵盤、鼠標(biāo)、軌跡球、指示筆輸入設(shè)備、鍵盤、話筒、游戲桿、觸敏顯示屏幕,及其他類型的向計(jì)算設(shè)備2000提供用戶輸入的設(shè)備。打印機(jī)2020是向紙張打印數(shù)據(jù)的外部設(shè)備。計(jì)算設(shè)備2000的不同的實(shí)現(xiàn)與不同類型的打印機(jī)進(jìn)行連接。打印機(jī)的示例類型包括,但不僅限于,激光打印機(jī)、噴墨打印機(jī)、照片打印機(jī)、復(fù)印機(jī)、傳真機(jī)、收據(jù)打印機(jī)、點(diǎn)陣打印機(jī),或其他類型的向紙張打印數(shù)據(jù)的設(shè)備。
通信介質(zhì)2022促進(jìn)計(jì)算設(shè)備2000的硬件組件之間的通信。在不同的實(shí)施例中, 通信介質(zhì)2022促進(jìn)計(jì)算設(shè)備2000的不同的組件之間的通信。例如,在圖20的示例中,通信介質(zhì)2022促進(jìn)存儲器2002、處理系統(tǒng)2004、輔助存儲設(shè)備2006、網(wǎng)絡(luò)接口卡2008、視頻接口 2010,以及外部組件接口 2014之間的通信。在計(jì)算設(shè)備2000的不同的實(shí)現(xiàn)中,通信介質(zhì)2022是以不同的方式實(shí)現(xiàn)的。例如,在計(jì)算設(shè)備2000的不同的實(shí)現(xiàn)中,通信介質(zhì)2022 可以被實(shí)現(xiàn)為PCI總線、PCI Express總線、加速圖形端口 (AGP)總線、Infiniband互連、 串行高級技術(shù)附接(ATA)互連、并行ATA互連、光纖信道互連、USB總線,小型計(jì)算系統(tǒng)接口 (SCSI)接口,或另一種類型的通信介質(zhì)。
存儲器2002存儲各種類型的數(shù)據(jù)和/或軟件指令。例如,在圖20的示例中,存儲器2002存儲基本輸入/輸出系統(tǒng)(BIOS)2024、操作系統(tǒng)2026、應(yīng)用軟件2028,以及程序數(shù)據(jù)2030。BIOS 2024包括一組軟件指令,這些軟件指令,在由處理系統(tǒng)2004執(zhí)行時,導(dǎo)致計(jì)算設(shè)備2000啟動。操作系統(tǒng)2026包括一組軟件指令,這些軟件指令,在由處理系統(tǒng)2004執(zhí)行時,導(dǎo)致計(jì)算設(shè)備2000提供協(xié)調(diào)計(jì)算設(shè)備2000的活動和資源共享的操作系統(tǒng)。操作系統(tǒng)的示例類型包括,但不僅限于,MICROSOFT WINDOWS 、Linux、Unix、Apple OSX, Apple OS X iPhone、Palm web0S、Palm OS、Google Chrome OS、Google Android OS,等等。 應(yīng)用軟件1928包括一組軟件指令,這些軟件指令,在由處理系統(tǒng)2004執(zhí)行時,導(dǎo)致計(jì)算設(shè)備2000向計(jì)算設(shè)備2000的用戶提供應(yīng)用。程序數(shù)據(jù)2030是由應(yīng)用軟件2028所生成的和 /或使用的數(shù)據(jù)。
上文所描述的各實(shí)施例是只作為說明來提供的,并且不應(yīng)該被解釋為限制。本領(lǐng)域的技術(shù)人員將輕松地認(rèn)識到,在不遵循此處所示出和描述的示例實(shí)施例和應(yīng)用的情況下可以進(jìn)行各種修改和更改。例如,各實(shí)施例是參考文檔描述的。然而,其他實(shí)施例將本說明書中所描述的技術(shù)應(yīng)用到其他類型的分級數(shù)據(jù)結(jié)構(gòu)。此外,圖形所示出的操作只是示例。在各實(shí)施例中,類似的操作可包括比圖形中所示出的那些多一些或少一些的步驟。此外,在其他實(shí)施例中,類似的操作可包括圖形中所示出的操作的不同的順序的步驟。
權(quán)利要求
1.一種用于對文檔執(zhí)行操作的方法,所述方法包括提供包括一個或多個處理單元和存儲器的計(jì)算系統(tǒng);由所述計(jì)算系統(tǒng)執(zhí)行通過修改所述文檔的活動表示來修改所述文檔的構(gòu)造器線程,所述文檔的所述活動表示存儲在所述存儲器中;以及由所述計(jì)算系統(tǒng)與所述構(gòu)造器線程并發(fā)地執(zhí)行讀取器線程,所述讀取器線程使用所述文檔的非活動表示來對所述文檔執(zhí)行操作,所述文檔的非活動表示存儲在所述存儲器中, 所述文檔的活動表示和所述文檔的非活動表示不包括相同數(shù)據(jù)在所述存儲器中的不同副本,其中,當(dāng)讀取所述文檔的非活動表示中的數(shù)據(jù)時,確保邏輯一致性,而不鎖定所述文檔的非活動表示中的任何數(shù)據(jù)。
2.如權(quán)利要求I所述的方法,其特征在于由所述讀取器線程執(zhí)行的操作不修改所述文檔;每當(dāng)所述構(gòu)造器線程接收到修改所述文檔的輸入時,所述構(gòu)造器線程執(zhí)行創(chuàng)建所述文檔的新表示的操作;并且在所述構(gòu)造器線程完成所述操作之后,所述文檔的所述新表示可供所述讀取器線程使用。
3.如權(quán)利要求I所述的方法,其特征在于所述文檔是文字處理文檔;并且所述方法還包括由所述計(jì)算系統(tǒng)執(zhí)行文字處理應(yīng)用,所述文字處理應(yīng)用使用戶能與所述文檔進(jìn)行交互,所述文字處理應(yīng)用喚醒所述構(gòu)造器線程和所述讀取器線程。
4.如權(quán)利要求I所述的方法,其特征在于所述文檔在內(nèi)部被表示為文檔樹,所述文檔樹是文檔元素的層次結(jié)構(gòu);所述文檔的活動表示包括真實(shí)元素陣列,所述真實(shí)元素陣列包含表示所述文檔樹中的每一個文檔元素的元素;所述文檔的非活動表示包括所述真實(shí)元素陣列;并且所述文檔的活動表示和所述文檔的非活動表示不包括所述真實(shí)元素陣列中的相同元素在所述存儲器中的不同副本。
5.如權(quán)利要求4所述的方法,其特征在于,所述構(gòu)造器線程在所述讀取器線程并發(fā)地從所述文檔的非活動表示中讀取給定元素時從所述文檔的活動表示中刪除所述給定元素, 所述給定元素表示所述文檔樹中的相同文檔元素。
6.如權(quán)利要求4所述的方法,其特征在于所述文檔的活動表示包括索引樹的活動版本和片段描述符表的活動版本,所述片段描述符表包括一組片段描述符,所述片段描述符中的每一個都標(biāo)識所述真實(shí)元素陣列中的一個片段,所述索引樹包括索引節(jié)點(diǎn)的層次結(jié)構(gòu),所述索引節(jié)點(diǎn)中的每一個都指示所述片段描述符中的一個;所述文檔的非活動表示包括所述索引樹的非活動版本和所述片段描述符表的非活動版本;對于所述索引樹中的每一個索引節(jié)點(diǎn),與所述索引節(jié)點(diǎn)的左子樹中的索引節(jié)點(diǎn)相關(guān)聯(lián)的元素具有小于與所述索引節(jié)點(diǎn)相關(guān)聯(lián)的元素的虛擬偏移量的虛擬偏移量,與所述索引節(jié)點(diǎn)的右子樹中的索引節(jié)點(diǎn)相關(guān)聯(lián)的元素具有大于與所述索引節(jié)點(diǎn)相關(guān)聯(lián)的元素的虛擬偏移量的虛擬偏移量,所述虛擬偏移量是與虛擬元素陣列的開始處的偏移量,所述虛擬元素陣列是所述文檔樹的一維表示;并且所述文檔的活動表示和所述文檔的非活動表示在所述存儲器中沒有所述片段描述符表中的相同片段描述符或所述索引樹中的相同索引節(jié)點(diǎn)的不同副本。
7.如權(quán)利要求6所述的方法,其特征在于為了修改所述文檔以包括附加文檔元素,所述構(gòu)造器線程執(zhí)行元素插入操作,所述元素插入操作通過將一個或多個新元素插入到所述真實(shí)元素陣列中,將新片段描述符添加到所述片段描述符表,以及將一個或多個新索引節(jié)點(diǎn)添加到所述索引樹,來生成所述文檔的所述活動表示,所述一個或多個新元素表示所述附加文檔元素;在所述構(gòu)造器線程完成所述元素插入操作之后,所述文檔的所述活動表示變得可供所述讀取器線程使用。
8.一種計(jì)算系統(tǒng),包括包括多個處理單元的的處理系統(tǒng);以及種包括計(jì)算機(jī)可執(zhí)行指令的存儲器,所述計(jì)算機(jī)可執(zhí)行指令在由所述處理系統(tǒng)執(zhí)行時,導(dǎo)致所述計(jì)算系統(tǒng)執(zhí)行通過修改所述文檔的活動表示來修改所述文檔的構(gòu)造器線程,所述文檔的活動表示存儲在所述存儲器中;以及與所述構(gòu)造器線程并發(fā)地執(zhí)行讀取器線程,所述讀取器線程使用所述文檔的非活動表示來對所述文檔執(zhí)行操作,所述文檔的非活動表示存儲在所述存儲器中,所述文檔的活動表示和所述文檔的非活動表示不包括相同數(shù)據(jù)在所述存儲器中的不同副本,其中,當(dāng)讀取所述文檔的非活動表示中的數(shù)據(jù)時,確保邏輯一致性,而不鎖定所述文檔的非活動表示中的任何數(shù)據(jù),所述讀取器線程的操作不修改所述文檔。
9.如權(quán)利要求8所述的計(jì)算系統(tǒng),其特征在于所述文檔在內(nèi)部被表示為文檔樹,所述文檔樹是文檔元素的層次結(jié)構(gòu);所述文檔的活動表示包括真實(shí)元素陣列,所述真實(shí)元素陣列包含表示所述文檔樹中的每一個文檔元素的元素;所述文檔的非活動表示包括所述真實(shí)元素陣列,所述文檔的活動表示和所述文檔的非活動表示不包括所述真實(shí)元素陣列中的相同元素在所述存儲器中的不同副本;所述文檔的活動表示包括索引樹的活動版本和片段描述符表的活動版本,所述片段描述符表包括一組片段描述符,所述片段描述符中的每一個都標(biāo)識所述真實(shí)元素陣列中的一個片段,所述索引樹包括索引節(jié)點(diǎn)的層次結(jié)構(gòu),所述索引節(jié)點(diǎn)中的每一個都指示所述片段描述符中的一個;所述文檔的非活動表示包括所述索引樹的非活動版本和所述片段描述符表的非活動版本;對于所述索引樹中的每一個索引節(jié)點(diǎn),與所述索引節(jié)點(diǎn)的左子樹中的索引節(jié)點(diǎn)相關(guān)聯(lián)的元素具有小于與所述索引節(jié)點(diǎn)相關(guān)聯(lián)的元素的虛擬偏移量的虛擬偏移量,與所述索引節(jié)點(diǎn)的右子樹中的索引節(jié)點(diǎn)相關(guān)聯(lián)的元素具有大于與所述索引節(jié)點(diǎn)相關(guān)聯(lián)的元素的虛擬偏移量的虛擬偏移量,所述虛擬偏移量是與虛擬元素陣列的開始處的偏移量,所述虛擬元素陣列是所述文檔樹的一維表示;并且所述文檔的活動表示和所述文檔的非活動表示在所述存儲器中沒有所述片段描述符表中的相同片段描述符或所述索引樹中的相同索引節(jié)點(diǎn)的不同副本。
10. 一種存儲計(jì)算機(jī)可讀指令的數(shù)據(jù)存儲介質(zhì),所述計(jì)算機(jī)可讀指令在被執(zhí)行時,導(dǎo)致計(jì)算系統(tǒng)執(zhí)行使用戶能與文檔進(jìn)行交互的應(yīng)用,所述文檔在內(nèi)部被表示為文檔樹,所述文檔樹包括文檔元素的層次結(jié)構(gòu),所述應(yīng)用喚醒構(gòu)造器線程和讀取器線程;執(zhí)行所述構(gòu)造器線程,所述構(gòu)造器線程通過修改所述文檔的活動表示來修改所述文檔,所述文檔的活動表示存儲在存儲器中,所述文檔的活動表示包括索引樹的活動版本,片段描述符表的活動版本,以及真實(shí)元素陣列,所述真實(shí)元素陣列包含表示所述文檔樹中的每一個文檔元素的元素,所述片段描述符表包括一組片段描述符,所述片段描述符中的每一個都標(biāo)識所述真實(shí)元素陣列的一個片段,所述索引樹包括索引節(jié)點(diǎn)的層次結(jié)構(gòu),所述索引節(jié)點(diǎn)中的每一個都指示所述片段描述符中的一個;以及與所述構(gòu)造器線程并發(fā)地執(zhí)行所述讀取器線程,所述讀取器線程使用所述文檔的非活動表示來對所述文檔執(zhí)行操作,所述文檔的非活動表示包括所述索引樹的非活動版本, 所述片段描述符表的非活動版本,以及所述真實(shí)元素陣列,所述文檔的所述非活動表示存儲在所述存儲器中,所述文檔的活動表示和所述文檔的非活動表示不包括相同數(shù)據(jù)在所述存儲器中的不同副本,其中,當(dāng)讀取所述文檔的非活動表示中的數(shù)據(jù)時,確保邏輯一致性, 而不鎖定所述文檔的非活動表示中的任何數(shù)據(jù),所述讀取器線程的所述操作不修改所述文檔,其中,對于所述索引樹中的每一個索引節(jié)點(diǎn),與所述索引節(jié)點(diǎn)的左子樹中的索引節(jié)點(diǎn)相關(guān)聯(lián)的元素具有小于與所述索引節(jié)點(diǎn)相關(guān)聯(lián)的元素的虛擬偏移量的虛擬偏移量,與所述索引節(jié)點(diǎn)的右子樹中的索引節(jié)點(diǎn)相關(guān)聯(lián)的元素具有大于與所述索引節(jié)點(diǎn)相關(guān)聯(lián)的元素的虛擬偏移量的虛擬偏移量,所述虛擬偏移量是與虛擬元素陣列的開始處的偏移量,所述虛擬元素陣列是所述文檔樹的一維表示。
全文摘要
一種計(jì)算系統(tǒng)并發(fā)地執(zhí)行生成器線程和讀取器線程。構(gòu)造器線程通過修改文檔的活動表示來修改文檔。讀取器線程使用文檔的非活動表示來對文檔執(zhí)行操作。文檔的活動表示和文檔的非活動表示存儲在計(jì)算系統(tǒng)的存儲器中。文檔的活動表示和文檔的非活動表示不包括相同數(shù)據(jù)在存儲器中的不同副本。當(dāng)讀取文檔的非活動表示中的數(shù)據(jù)時,確保邏輯一致性,而不鎖定文檔的非活動表示中的任何數(shù)據(jù)。
文檔編號G06F9/06GK102939581SQ201180025941
公開日2013年2月20日 申請日期2011年5月16日 優(yōu)先權(quán)日2010年5月27日
發(fā)明者C·W·派克 申請人:微軟公司