基於片段的串行化系統與方法
2023-07-06 18:53:56 1
專利名稱:基於片段的串行化系統與方法
技術領域:
本發明涉及計算,尤其涉及數據對象的存儲與發送。
(2)背景技術串行化可被定義為將對象實例的狀態存儲到存儲介質的過程。在此過程中,對象的公有欄位和私有欄位以及類名被轉換成字節流,隨即寫到數據流中。當對象隨後被反串行化時,可創建原始對象的一個精確複製。
考慮活動計算機存儲器中的對象,例如具有描述人物的數據的對象。該人物對象有若干子組件成員,例如名字、地址、社會保險號、電話號碼、配偶、身高及體重。此人的名字對於一特定應用程式可能是重要的,而身高與體重可能不是。因而,名字可以駐留在活動存儲器中,在那裡它可被修改,而諸如體重及身高等其它欄位被驅出活動存儲器來為其它數據騰出空間。最後,該應用程式可能不再需要此人物對象,可將其持久化或發送到另一計算機。要持久化或發送一對象,該對象必須被串行化,這是指以有用的、可檢索的方式來格式化對象。
在上例中,對象(例如人物對象)的成員對於同一個類的所有對象通常是統一的。例如,每個人物對象有名字、地址、社會保險號、電話號碼、配偶、身高與體重。這些信息隨著人物不同而變化,且對於某些人來說信息可能是不可用的(「空」),但對於人物類的所有人物對象通常呈現同樣的成員欄位的存在。由此,人物類可被認為是類屬人物對象。人物對象是人物類的一個實例。類及類的實例的這一概念存在於許多程式語言中。無論牽涉到哪種程式語言,串行化通常都是在類的實例上進行的,從而生成串行化的對象。
對象可由具有各種類型數據的成員組成。成員可以是原語的或複合的。原語成員的例子有「串」,例如人物對象的名字成員,它是一串字母;及「整數」,例如人物對象的社會保險號,它是一個整數。複合成員的例子有「集合」,例如電話號碼成員,它包含一個以上原語——在本例中,一個以上整數;「嵌套」,它是具有超越簡單原語成員的某一結構的成員,例如電話號碼的集合,或指向另一人物對象的配偶成員;以及「子類型」,諸如假定的「美國地址」類型,它可以是地址類型的子類型,從而假定地聲明附加的成員,諸如美國區域或美國郵政信箱。成員可以用許多不同的方式來描述,且以任何數量的模式彼此相關。因而,將諸如人物對象等對象串行化涉及有效地處理可能包括在對象中的各個成員及那些成員的關係。
對象的串行化在業界提出了若干挑戰。串行化的對象應儘可能少地消耗存儲空間。如果對象的大小在串行化時大大增長,則該對象的存儲成本可能太高。因此,壓縮表示是串行化格式的一個重要方面。
串行化的對象也應被有效地實例化到活動存儲器中。如果尋找和同化串行化對象的各個成員的處理成本高的話,會耗盡貴重的處理器資源。類似地,串行化應當慮及在無需實例化整個對象的情況下對象的成員的實例化和更新。例如,將整個人物對象實例化只為讀或更新該人物的社會保險號,是當名字、電話號碼、地址等成員未涉及在操作中時對存儲這些成員所需的活動存儲器的一種浪費。
串行化格式還應支持可包含在對象中的所有數據類型。一種十分基本的串行化格式可能只支持原語,但較複雜的格式應當支持複合成員,諸如上述的嵌套成員、集合成員及子類型成員。儘管串行化格式對於具有很少嵌套與繼承級別的對象應是最優的,因為大多數對象具有這個特性,但它也應當支持多級嵌套與繼承,以確保串行化可靈活地用於大範圍的類。串行化格式還應能靈活處理非常大的成員。例如,某些成員可以是音樂文件、照片或電影,諸如此類的大成員造成串行化的一個難題,這將在下文詳盡地解釋。
以前的串行化格式有幾個顯著的不足。一種此類格式被稱為XML串行化。XML串行化為每個成員提供一個記號(token)。該記號包含標識成員的元數據,成員通常緊跟在令牌之後。因此,XML串行化可形象化為如下(記號1)成員1;(記號2)成員2;(記號3)成員3;等等。這一串行格式的問題是,首先,冗長每個成員的元數據記號的存儲消耗大量磁碟空間。其次,這一格式削弱了檢索,因為為了找到期望的成員必須搜索記號。這可能牽涉高活動存儲器成本,因為讀或更新以此方式串行化的對象的最有效方法可能是將整個對象實例化。
另一種串行化格式是「存儲引擎記錄」格式,也稱「SE記錄」,或簡稱「記錄」格式。這是一種典型的資料庫系統記錄格式。在此串行化格式中,給定類的對象的成員存儲於統一格式化的記錄中。不是提供描述每個成員的元數據,而是有描述一特定類的對象的所有記錄的內容的元數據。這可如圖10所提供的形象化。
SE記錄串行化格式不對每個單獨成員要求元數據,因此是一種較緊湊的串行化技術。相反,它要求訪問描述各成員在磁碟上的布局的元數據,諸如圖10的人物對象元數據表。SE記錄格式的一個弱點是它不能靈活地處理可變長度的成員,諸如當今隨對象保存的許多音樂文件、電影及圖像。更確切地說,SE記錄串行化中的靈活性來自高處理成本。如果使用偏移量表來表示可變長度數據在記錄中的位置,那麼可變長度的成員可以此類格式存儲。存儲偏移量表的後果是,無論何時更新了一可變長度成員,就必須更新跟在其後的所有可變長度數據的位置。這可以比喻為在一數組中間插入字節——插入點右邊的一切必須右移來為插入的新字節騰出空間。
此外,已設計出各種存儲格式以允許資料庫用戶在資料庫內有效地存儲對象。以更靈活的串行化格式能更好地支持這些存儲格式。例如,應與本文提供的串行化格式區別。例如美國專利申請第10/692,225號,代理卷號MSFT 2852/306819.01,題為「System and method for object persi stence in a database store」(資料庫存儲中對象持久化的系統與方法),針對允許用戶將用如C#等面向對象語言所寫的類與方法導入資料庫。它還允許用戶在資料庫中存儲C#對象,以及對該對象調用方法。它向用戶提供多種風格的持久化。用戶能夠定義自己的串行化格式、使用公共語言運行庫(「CLR」)串行化(C#自身提供)、或讓SQL伺服器以其自己的格式存儲對象。這些選項,尤其是後者,提供了性能優勢,因為MICEOSOFT SQLSERVER無須真正實例化一C#對象,即可檢索或更新對象的某些些欄位。當然某些操作,諸如方法調用,仍然要求C#對象的實例化。
類似的背景及相關技術描述可在美國專利申請第10/692,227號,代理卷號MSFT-2850/306820.1,題為「System and method for storing and retrieving afield of a user defined type outside of a database store」(在資料庫存儲外保存及檢索用戶定義類型的欄位的系統與方法)中找到。此申請討論了UDT中的文件流,它可依照本文描述的技術來串行化。諸如此類的高級資料庫技術將受益於更靈活和更高性能的串行化格式。類型地,對串行化對象進行操作的改良技術將更好地支持諸如此類的高級資料庫技術。
因而,串行格式所牽涉的權衡是該格式的元數據盤上存儲器額外開銷、定位成員的活動存儲器額外開銷、定位成員的處理成本、進行更新的額外開銷、處理大欄位的靈活性之間的權衡。根據這些權衡,在業界對於消除關於串行化技術的障礙的有正行成中且迄今未能解決的需求(3)發明內容一種基於片段的串行化方法與系統將一個或多個成員放到片段中。片段可包含頭部及淨荷。頭部能提供關於片段的有用信息,諸如片段類型的指示及片段長度的指示。淨荷可包含對象的一個或多個成員。提供了各種片段類型以高效且靈活地存儲並檢索對象成員。原語成員可存儲在具有記錄格式淨荷的片段中。此配置允許原語的快速定位及更新。大對象(「LOB」)成員可存儲在有用於為LOB和FS成員位置說明位置類型的欄位的片段中。集合可存儲在一系列片段中,第一片段指示集合的開始,一個或多個第二片段將集合元素串行化,終止符片段指示集合的結束。這些及其它片段類型可根據規則來組織,該規則支配生成片段、將成員放到片段中、以及以向該串行化格式提供附加功能的方式來對片段定序。
(4)
圖1是各種片段概念上的圖示,這些片段可用於將對象成員串行化。它示出了一具有包含記錄格式的原語成員的淨荷的二進位片段、一具有非記錄格式淨荷的片段、及一無淨荷的片段。
圖2用片段頭部的詳細視圖示出一片段。該頭部示出用於片段頭部的可能欄位的選擇,並且許多片段頭部可省略所示的某些欄位。
圖3根據本發明的各種實施例示出了若干示例性對象類,在描述中,為這些對象類提供了片段序列。
圖4所示是當對象中沒有嵌套成員時,為對象的原語成員生成片段的步驟的流程圖。
圖5所示是當對象中有嵌套成員時,為對象的原語成員生成片段的步驟的流程圖。
圖6所示是為對象的集合成員生成片段的步驟的流程圖。
圖7所示是為對象的LOB和FS成員生成片段的步驟的流程圖。
圖8所示是將具有各種類型成員的整個對象放到片段中的過程的步驟的流程圖。
圖9示出了當可儲存在資料庫的單獨一列中,根據本發明各種實施例被串行化的對象。
圖10示出了現有技術的記錄串行化格式,其中,為所有記錄提供了元數據,且對應數據符合元數據中指定的格式。
圖11(A-H)示出了根據本發明較佳實施例,用於串行化數據的各種片段類型。
圖12是圖3中所示的tPartTimeEmployee對象的片段序列的頂層圖。此片段序列可對每一級嵌套包含附加片段。
(5)具體實施方式
在以下描述和附圖中闡述某些具體細節,以提供對本發明各實施例的徹底理解。然而,常與計算技術相關聯的某些眾所周知的細節未在以下所揭示的內容中闡述,以避免不必要地使本發明的各實施例模糊不清。並且,相關領域的普通技術人員將能理解,他們能不用以下描述的一個或多個細節來實施本發明的其它實施例。最後,儘管各種方法是參照在以下所揭示的內容中的步驟及序列來描述的,然而諸如此類的描述是為了提供對本發明的實施例的有條理的實現,且這些步驟及步驟序列不應被當作實施本發明所必需的。
本發明的一個目的是提供一種改良的對象串行化的方法與系統,以及提供對串行化對象進行操作的技術。在這點上,給出了一種提供緊湊表示的串行化。以所提供的格式串行化的對象能被有效地實例化到活動存儲器中,從而降低了尋找和同化串行化對象的各個成員的處理成本。類似地,無需實例化整個對象,即可實例化及更新對象的成員。此外,提供了對各種各樣數據類型的支持,包括用戶定義數據類型(「UDT」)。可為具有較少嵌套和繼承級別的對象優化串行化格式,但仍支持多級嵌套與繼承。它能靈活地處理非常大的成員。本發明能提供一種串行化格式,它適用於在單個列中存儲各種類型——例如,作為「人物」對象的子類型的「僱員」對象的一個實例可被存儲在一僅供存儲「人物」對象的列中。最後,該串行化格式允許向類型有效地添加新成員,也稱作有效類型進化。
根據本發明各實施例的基於片段的串行化可被概念化為一種混合格式,除了基於片段的串行化自身獨有的許多方面與優點外,該格式使用如在背景技術中所述的某些XML風格串行化的元素,及亦如背景技術中所述的某些SE記錄串行化的元素。在這點上,對象的成員可被放到片段中。片段在圖1中示出。
參考圖1,片段可包含一頭部,且某些情況下包含一淨荷。頭部可提供關於該片段的有用信息,諸如片段類型的指示,及片段長度的指示。此頭部在某種意義上類似於XML串行化提供的記號,因為對每個片段都給予一個新的頭部,正如在XML串行化上下文中對每個成員都提供一個記號。然而,雖然XML令牌被提供給每個成員,然而圖1的片段可包括一個以上成員。這在片段1中示出,片段1示出一具有包含若干數據成員的淨荷的片段。基於片段的方法能串行化及反串行化各種數據結構,包括但不限於具有簡單原語欄位的對象(整數、串等等),連接的對象的完整圖以及集合。
片段淨荷可包含串行化對象的一個或多個成員,以及任何其它數據。此淨荷可為內部的成員使用SE記錄格式風格的串行化,這允許迅速檢索該淨荷內的成員。諸如此類的記錄格式淨荷是圖1中片段1的一個特性。在這點上,基於片段的串行化具有SE記錄串行化的特徵。可在頭部或其它地方提供描述包括在淨荷中的各個欄位的元數據。因此,可達到緊湊表示及無須實例化整個對象即可檢索個別成員的相應優點。
片段的頭部部分可包含各個欄位,如圖2中所示。圖2示出了一片段,其具有擴展的頭部部分,因而可示出各個可能的欄位。注意圖2中所提供的各個欄位不需被包括在每個片段中。相反,為該片段的淨荷提供有用信息的欄位可被包括在頭部中。圖2的各個欄位將結合各種建議的片段類型的描述,在下文詳細解釋。
為了串行化對象時額外的通用性,本發明的各實施例使用多種類型的片段。各種建議的片段類型在下文闡明。然而,在描述片段類型之前,考慮使用不同片段類型的動機。一個激發因子是為允許可組成對象的各種類型的成員的更好的串行化。回憶背景技術部分,對象常常包含多個不同類型的成員。這些成員可以是,例如●小原語成員。這些是基本類型的成員,諸如整數(「int」)、浮點數及串。
●大原語成員,諸如大對象(「LOB」)及文件流(「FS」)。
●複合成員,諸如集合及嵌套。
●子類型成員。支持繼承的任何類可以有該類包括繼承的成員的實例,該成員進而可以是一子類型的數據。
以上是可能的成員類型的非窮盡列表,且所有成員類型被認為是適用於本文所描述的基於片段的串行化技術的候選類型。
片段類型為了適應可能存在於被串行化的對象中的各種類型的成員,本發明可用若干片段類型來使用。一種或幾種片段類型可能只對一類成員有用,而其它片段類型對多種成員類型有用。
各種片段類型可具有為片段內容定製的不同格式。在以下討論中,首先闡述一種片段類型,接著是對於該類型的一種建議的片段格式的可視描述。斜體的片段屬性是可任選的,且取決於類型列的值。本發明不局限於下文闡述的片段類型。除了此處提供的片段,可根據此文提供的基於片段的串行化的一般原理來開發新的片段類型供使用。
二進位片段-圖11(A)顯示一二進位片段的各種可能的實施例。此片段可包含類型、長度及淨荷欄位。類型欄位可以只是一個字節,或者可以是任意多個字節。當使用該串行化格式時,類型欄位中的額外字節要求額外的存儲器額外開銷。因此頭部欄位中的字節應節約地使用。在這點上,一字節的類型欄位能包括若干位,用於指示片段的各種屬性。一個位可用於指示片段是二進位片段。另一個位可用於指示包含在該片段中的一個或多個成員的類型。例如,如果所有成員都是原語的,可設置一個位來指示此類信息。如果成員是子類型成員,則可設置一個位來如此指示。如果二進位片段是一串行化對象的第一個或唯一一個片段,類型欄位中的一個位可如此指示。類型欄位還可指示包含在一個或多個片段中的對象類型,以及任何附加的有用信息,諸如整個對象中片段的個數與類型。
以單個二進位片段表示的對象可在類型欄位中標記為「自終止」片段,從而消除了對在串行化對象末端包括一終止符片段的任何需求。這個「自終止」標誌可以是片段的類型欄位中一個自終止符位的形式。諸如此類的自終止符位也可位於片段頭部的任何其它欄位中,或在片段淨荷中。由多個片段表示的對象無須設置該自終止符位,因為可以生成終止符片段來標識該串行化對象的終點。
長度欄位最優是2位元組,儘管長度可如上所述地變化。長度欄位可用於指示淨荷的長度。二進位片段中的淨荷可包含任何數據。在一較佳實施例中,淨荷包含對象的所有原語成員。此類片段中的淨荷可以是SE記錄,以允許有效地破解及更新存儲在其中的原語或其它成員。
LOB片段-圖11(B)顯示一LOB片段的各種可能的實施例。此片段可有頭部中的類型、值類型及長度欄位,及一包含LOB或LOB位置信息的淨荷。類型欄位如同在每個片段中一樣,只需是1位元組,在此情形下指示該片段是LOB片段。值類型欄位可提供附加手段來描述LOB片段的內容。可在不希望為LOB屬性用盡類型欄位的字節的實現中添加這一值類型欄位,以包含關於LOB屬性的信息。由此,只有LOB片段有該額外開銷(這裡,每片段有一附加字節)。
存儲在值類型欄位中的信息可描述其中存儲了LOB的位置的類型。允許對LOB成員位置的附加描述提供了處理大值時的靈活性。當LOB數據(與LOB引用相反)儲存在LOB片段中時,應用程式(或計算機用戶)可啟動LOB內聯類型片段的生成、使用8位元組長度、並將LOB內聯。換句話說,LOB能放在LOB片段的淨荷中。如果值類型欄位指示LOB內聯類型,則長度欄位可以是例如8個字節,且淨荷可包含一LOB值。
不總是期望包括與串行化對象內聯的LOB。這是因為LOB會佔去大量空間。因此,值類型欄位可指示LOB指針類型,意味著該片段的淨荷包含指向LOB位置的指針。在此情況下,長度欄位可以是例如2個字節,且淨荷可包含一LOB引用。值類型欄位也可指示LOB延遲類型,意味著該片段淨荷包含對資料庫中假定包含LOB的單元的引用。在此替換情形中,片段長度可以是例如2個字節,且淨荷可包含一單元引用。「單元引用」是表標識符、行標識符及列表示符的組合。當與LOB片段的「路徑」(如下所述)結合,單元引用給出足夠信息以定位實際的LOB數據。任何其它位置類型信息可包含在LOB或FS片段的值類型欄位中。為LOB和FS片段提供此類附加位置類型欄位給予串行格式額外的靈活性,而保持低額外開銷。
注意,如果在特定類的串行化中,特定對象沒有所提供的成員,則本文討論的任何片段可以為空。如果片段為空,可在該片段的類型欄位的一個位中設置此信息。在這點上,長度欄位和淨荷可從圖11(B)的LOB片段中移除,來形成在值類型欄位中指定任一位置的空LOB片段。
FS(文件流)片段-圖11(C)顯示FS片段的各種可能的實施例。如同所有片段一樣,FS片段可具有一指示片段類型(這裡是FS片段)的類型欄位。如同LOB片段,FS片段可包括一值類型欄位。再一次,此欄位可指示FS的各種位置類型。FS可用對象的剩餘部分,或內聯類型(這再次可與較大長度的欄位相關,例如8位元組)來串行化。它可處於指向片段淨荷的位置,在FS上下文中的FS指針類型可指示例如2位元組的長度欄位,及包括恰當FS文件的全局唯一標識符(「GUID」)的淨荷。值類型欄位也可指示FS延遲定位類型,此類型可與例如2位元組的長度,及包含單元引用的淨荷相關。
終止符片段一圖11(D)示出終止符片段的各種可能的實施例。在基於片段的串行化的較佳實現中,僅類型字節與終止符片段有關。這是因為終止符片段的功能是標記串行化對象的結束,或標記串行化對象之內的集合或其它相關片段組的結束。終止符片段可用一指示其為終止符片段的類型欄位來執行此功能,並且無需包括附加信息。然而,隨終止符片段一起包括某些附加信息可能是有用的,且諸如此類的實施例肯定在本文描述的發明的範疇內。
集合起始片段-圖11(E)顯示集合起始片段的各種可能的實施例。此片段可包含類型欄位及例如為2位元組的位欄位。類型欄位可指示該片段為集合起始片段。位欄位可指示集合的屬性。例如,位欄位可指示對應於不按任何特定順序的集合的「無序」集合。它也可指示「有序」集合,表明集合是按特定順序。當此片段僅用於描述集合的目的時,可省略長度欄位,因為集合起始欄位標記了集合的開始,且由此無需包含淨荷。如果集合起始片段包括淨荷,則其可具有一長度欄位來描述該淨荷。然而在本文描述的較佳實施例中,集合起始片段用於標記和描述集合的,它沒有自已的淨荷,因而也無需長度欄位。同樣地,空集合起始片段看起來非常類似圖11(E)中的集合起始片段。集合起始片段為空的情形下的唯一不同是類型欄位中的位被設置,如上結合空LOB片段所述的。
集合元素片段-圖11(F)顯示集合元素片段的各種可能的實施例。這樣的片段中的類型欄位可指示其為集合元素片段。長度欄位可指示集合元素片段淨荷的長度。圖11(F)示出示例性的2子節的長度欄位,它應當足以指示包含集合元素的淨荷的長度。
集合元素片段也可包括定位符欄位。定位符欄位類似於LOB和FS片段的值類型欄位,可用於指示集合元素片段的附加屬性。例如,集合元素片段可有一SE記錄格式的淨荷,如二進位片段的淨荷。通過使用一個位來指示片段是否終止其自身,類型欄位可指示該集合元素片段是否為自終止片段。如果自終止片段位未被設置,則系統可為該片段預期一終止符片段。定位符欄位可用於尋址集合的特定元素,非常類似於FS片段的GUID。然而在集合元素片段的情況下,定位符欄位指示集合內的唯一位置,而不必是全局唯一位置。
關於定位符欄位,較佳的是允許對集合元素中的定位符欄位的某一預期。集合起始片段的位欄位中的一個位可被設置以指示一即將到來的具有定位符欄位的集合元素片段。在這樣的配置中,系統可被配置成減少在集合元素片段中存在的定位符欄位。
空集合元素片段-圖11(H)顯示空集合元素片段的各種可能的實施例。集合元素片段的空表示可包含一指示該片段為空集合元素片段的類型欄位。它們也可包含定位符欄位,但無需包含長度或淨荷欄位,因為空集合元素片段的存在指示該特定的串行化對象沒有對應於一個類的特定方面的數據,而類本是被設計成包含諸如此類的數據的。再次,當沒有成員或其它成員信息包括在淨荷內時,不需要長度欄位來描述淨荷的長度。
空片段-圖11(G)顯示空片段的各種可能的實施例。空片段類似於終止符片段,可用單個類型欄位來表示。再次,此實施可能限於非集合元素空片段的表示。集合元素空片段的描述見下文。
註解和元數據片段一除了上述其它片段外,元數據和註解片段可用於向串行化對象的接收者描述一個或多個片段。此類片段在許多情況下有用,即使它們可能不是反串行化對象所必需的。例如,註解片段可允許用戶檢查關於一特定成員或對象的信息,或插入關於一串行化對象的註解或信息。
總而言之,參考上述各種片段類型的描述,有效串行格式獲得的優點之一是表示額外開銷的減少。表示額外開銷指隨對象存儲的許多附加信息,用於允許該對象被有效地檢索。基於片段的串行化技術的確包含表示額外開銷,但對於該格式的相應靈活性和功能性,已將額外開銷最小化。
片段頭部的第一個欄位是類型欄位。在較佳實施例中,類型欄位消耗1位元組。這使相關的額外開銷最小化。此外,與集合元素片段相關的定位符欄位計入額外開銷。大部分小型無序集合可在消耗不多於4位元組的定位符欄位中恰當表示欄位。然而較大的有序集合可消耗多於4位元組,在這種情況下,定位符欄位可用要求更多表示額外開銷的可變二進位(「varbinary」)欄位取代。定位符欄位使用的額外開銷的確切量被認為是實現細節,並留給理解減少表示額外開銷的動機的本領域的技術人員來判斷,但也要慮及集合的靈活串行化。最後,與若干其它片段類型(見上)相關的長度欄位是表示額外開銷。如上所述,較佳實施例中的長度欄位可以是2位元組或者8位元組長,取決於片段類型。本發明不限於此類欄位的確切字節數,且本文闡述的參數應當被認為是來自有經驗從業者的有用提示,而不是本發明自身的嚴格要求。
將成員放到片段中的規則如上面所解釋的,各種片段類型適用於各種片段成員。為了將一對象串行化,必須判定為特定成員使用哪種片段類型。包含例如原語、嵌套、集合及子類型成員的對象可根據一組規則被分解為片段。儘管本發明不限於片段類型與成員類型間的特定相關,然而已開發出一組有用的規則,並在此節中解釋。注意,這些規則是為了解釋清楚,而不是指示它們必須以特定的順序執行。在實踐中,對應於以下規則的操作可同時執行,片段的生成、填充及定序作為通過對象的成員的處理器步驟來執行。對於對象串行化的這些規則的一示例性應用,參考圖3及下面相應正文。規則如下。
生成片段。本發明的實施例可被認為是致力於基於類型的容器相關片段生成。換言之,對於下面的每一項都可以有一個片段●類中的每一級嵌套,即使該級為空。
●每個集合,即使該集合為空。
●集合的每個元素。
●每個子類型。
●每個LOB和FS屬性。即使其為空。LOB值可內聯存儲,而FS值必須外部保存。
可生成附加片段來配合特定類的需要。類似地,對於某些類的串行化可能不需要上述片段。
一般而言,用頂到底技術可將對象轉換成基於片段的串行化片段。首先,對象中的任何基本類型成員可被串行化,接著串行化子類型。在每個嵌套級,可對所包含成員進行一次掃描,以確定是否有任何嵌套類型、子類型或LOB/FS類型成員。
為原語成員生成片段。一些或所有原語成員可放在一個或多個二進位片段中。一較佳實施例以不同於帶有嵌套成員的對象的方式處理無嵌套成員的對象。這兩種場景在圖4和圖5中描繪。在兩種情況中,非嵌套原語都可放在單個二進位片段中,並用SE記錄格式在那裡串行化。對於無嵌套成員的對象,可生成一二進位片段,以及沒有任何嵌套成員可被放置在該片段的類型欄位中的指示。在各實施例中,包含嵌套成員的對象與不包含嵌套成員的對象間的實際區別可以是,有嵌套成員的對象可被串行化為多個片段,而無嵌套成員的對象可被串行化為單個二進位片段。因此,如果沒有嵌套成員,則在二進位片段的一個欄位中設置一自終止符片段位。可設置該二進位片段的長度欄位來對應於組合的原語成員的長度。該片段隨即可被發放。
參考圖5,如果有嵌套片段,則對於二進位片段的無嵌套成員過程可略作改變,以允許遞歸地串行化嵌套成員。在這種情況下,無需設置自終止符片段位。二進位片段被發放後,可遞歸地將嵌套類型成員處理成它們自己的片段。一從此類遞歸返回,就生成一終止符片段。該終止符片段隨即可被發放。
為集合生成片段。在圖6中提供了生成集合片段的過程的流程圖。當遇到集合成員時,可生成一集合起始片段。如果該集合無序,則位欄位中的位可被設成「無序」。隨後可通過生成集合元素片段,來遞歸地串行化該集合的每個元素,如下所述。當所有元素都被串行化後,生成一終止符片段來指示該集合的結束。
一個集合元素可被串行化為一個或多個片段。如果用一個以上片段表示一集合元素,則該表示可有自己的終止符片段。集合元素的第一個片段可包括一定位符欄位。一欄位的一個目的可以是跟蹤在串行化集合時所處理的多個元素。通過遞增定位符欄位中的計數器來正確地指示串行化的當前元素,該串行化過程可返回到正確的位置,以串行化集合的下一元素。
生成LOB和FS片段。在圖7中提供了示出為LOB和FS成員生成片段的流程圖。如在對各種片段類型的描述中指出的,LOB和FS片段都可被配置成為對應的淨荷指示一種以上位置類型。可在值類型欄位中作出該指示。例如,值類型欄位可將淨荷描述為包含指針的、內聯的、或延遲位置類型。在生成LOB和FS片段時,可從成員確定恰當的值類型。例如,如果LOB要隨對象來串行化,即隨片段內聯存儲,那麼可選擇LOB內聯的值類型,且該LOB可依此串行化。如果相反,LOB存儲於資料庫的單元內而非隨串行化對象存儲,則可隨該對象串行化一LOB引用,且恰當的位置類型可儲存於值類型欄位中。隨即該片段可被發放。
生成子類型片段。子類型片段可以用與任何其它非原語成員的片段相同的方式生成。換言之,如果子類型包含集合成員,則可生成一集合起始片段,以及任意個集合元素片段和一終止符片段,來標記該子類型成員串行化的結束。如果子類型成員是嵌套的LOB成員,則可生成一LOB片段來包含該子類型成員。以類似於為基本類型生成二進位片段的方式,為該子類型生成一二進位片段,該片段包括該子類型中所有小原語成員,諸如整數、浮點等等。
生成其它片段。本文描述的技術可被外推為生成串行化一特定對象或對象類所期望或需要的任何其它片段。
填充片段。儘管實際上可以同時生成與填充片段,然而為解釋本發明的此方面,包括如何填充片段的總體計劃是有用的。此總體計劃在圖8中提供。在將成員放到各種片段類型中時,可遵守下列建議
●除LOB成員外的所有原語成員可存儲在一二進位片段中。此片段的頭部可包含一用於整個對象的類型標識符。此片段的淨荷可包括一存儲引擎記錄。當片段僅包含原語屬性時,則稱其為終止自身。
●每個LOB成員可存儲於一LOB片段中。
●可為每個集合成員生成一集合起始片段。如果該集合成員非空,則該集合起始片段可引用一個或多個集合元素片段。
●為集合成員的各個元素提供一集合元素片段。此片段可以是具有定位符的二進位片段。定位符是可用於尋址集合元素的標籤。
●可為被分解成一個以上片段的每一集合成員生成一終止符片段。該終止符片段標記集合成員的結束。
●具有嵌套片段的片段不終止自己。相反,它具有一終止符片段,該片段出現在嵌套在前述片段內的所有片段之後。
●可為被分解成一個以上片段的每一對象生成一終止符片段。該終止符片段可標記一串行化對象的結束。
●嵌套對象可遞歸地遵循同上的規則。
●為串行化目的,子類型可被當作嵌套對象。
片段序列。片段被存儲在一序列中,該序列構成任何特定類的串行化。如果對象類只包含原語成員,則這些對象可被串行化為自終止的單個片段。具有複合或其它非原語成員的類可被串行化為一個以上片段。如果對類的串行化包含一個以上片段,那麼也可生成一個或多個終止符片段。從起始片段到最後的終止符片段的片段組由片段序列組成,片段序列是此描述中所用的術語。
在實例中對應於子類型的片段可嵌套在基本類型的片段下。用來自圖3的tPerson,tEmployee和tPartTimeEmployee的例子,並暫時假設在每一級僅有由二進位片段描述的原語屬性,則tPartTimeEmployee的一個實例可在圖12提供的圖表中形象地描繪。注意,圖12中tEmployee和tPartTimeEmployee的片段可處於同一嵌套級。
示例性串行化在闡述了若干可能的成員類型、若干片段類型及用於將成員放到片段中的一組示例性規則之後,使用本文描述的串行化格式的實施例的示例性串行化將會證明是有益的。在這點上,圖3提供了若干樣本模式。每個模式代表一對象類,其每一個都有一個或多個各種類型的成員。為討論起見,圖3提供一「人物」對象類,其每一個都具有名字串(原語成員)、年齡整數(也是原語成員)及位置集合(這是嵌套的複合成員)。圖3還提供一個定義「地址」對象的類,每個此類對象有三個原語成員街道、城市和郵編。圖3提供一僱員對象類,該類繼承了所述人物類,因而包括人物類的成員,還包括三個原語成員僱員號、部門及照片(圖像是LOB成員)。兼職僱員類繼承了僱員類,因此除了原語、每星期小時數之外,還包括僱員類的所有成員(包括從人物類繼承的成員)。
參考圖3,考慮其中的模式的實例如何能用上面提供的片段與規則來串行化。例如,具有非空地址集合的tPerson的一個實例可有按下面順序的片段●包含m_name和m_age的二進位片段。
○集合起始片段○對於每個集合元素■具有m_street、m_city、m_zip的集合元素片段。
○用來終止該集合的終止符片段●用來終止tPerson的片段的終止符片段具有非空地址集合的tEmployee的一個實例可有按下面順序的片段●包含m_name和m_age的二進位片段。
○集合起始片段○對於每個集合元素■具有m_street、m_city、m_zip的集合元素片段。
○用來終止該集合的終止符片段○包含m_empNo和m_dept的子類型片段■包含m_image的LOB片段●用來終止tPerson的片段的終止符片段。
參考上述示例性片段序列,注意,出於支持存儲引擎記錄構建/破解代碼的重複使用目的,如同在利用一個或多個片段中的記錄格式的那些實施例中所期望的,較佳的是要求用於本文所述的基於片段的串行化技術的類沒有一級在大小上可以超過7千字節(7k)。在上面所給的例子中,tPerson(不包括相關地址集合)在大小上應當小於7千字節。類似地,每個tAddress應小於7k。注意,儘管揭示此限制是為了遵循法定要求以指示實施本發明的最佳模式,然而允許一級超過7k是被認為本發明的可行的(儘管非最理想的)實現。此限制可在執行時由一串行化庫(「SL」)來強制實行。應當理解,串行化負責識別和解析各種片段。
從上面的例子中,注意,通過將成員放到一個或多個片段中,定位成員的任務就涉及定位其中放入成員的一個或多個片段。如果有一個以上這樣的片段,則可首先定位第一個片段。在這點上,片段相對與串行化的第一個片段的位置可根據元數據來確定。注意,儘管此技術未提供片段的直接可尋址性,然而消除了為每個成員比較記號來標識相關成員表示該類的哪個方面的任務。相反,當被掃描時,串行化元數據可快速地將處理器定向到恰當的片段。
如在上面的示例性串行化中所示的,本發明的另一優點是對象的串行化可在一次完成。串行化器進程可以用自頂向下的方式進行,從基本類型到子類型,從包含類型到嵌套類型。在每一級嵌套,串行化器進程可產生一個或多個片段。這一串行化器從來不會被要求去更新一早先生成的片段,儘管如果期望的話也可配置它這麼做。
應當承認,本文闡述的串行化格式可被配置成支持固定、可變長度及位類型原語成員;嵌套在其它對象中的對象;繼承;內聯與外部LOB(包括文件流);有序集合(經由定位符功能提供適當順序的集合元素的串行化);無序集合;及空值。它還可支持可組成的串行化。在這點上,嵌套對象可從一現存的串行化中提取,而沒有其中串行化該對象的片段容器的痕跡,即,沒有對應於其容器的任何狀態。本發明實施例的此屬性允許整個嵌套對象的插入或更新。
從上面的串行化例子中,還要注意,所提議的串行化格式支持向類添加成員,而無須更新任何其它現存數據。向類添加欄位在使用XKL模式時是很常見的,其中,模式經常通過添加欄位來更新。在這點上,可變更任何類型的片段來添加新成員(原語、集合或嵌套對象),只要它們有NULL的默認值,且被添加到現存類型的末尾。向對象添加型成員無須具有記錄格式串行化的意義,因為以所建議的基於片段的格式存儲的對象可如「字節包」一樣存儲在資料庫的單獨一列中,且可以是任意大。
如在上面的示例性串行化中實施的串行化格式的另一優點是,片段的身份無需隨該片段存儲。相反,可使用片段的路徑來揭示片段身份。該路徑可從所操作的任意給定對象的類型元數據來確定。路徑標識了串行化中的一特定片段。路徑可以是,例如,每個片段中的一組數字,標識了每一嵌套級和子類型級的片段。由於對象的各個欄位駐留在預定的片段中,因此可用路徑來定位它們。從某種意義來說,路徑就像片段的地址。路徑可隨片段存儲,或可通過從第一個串行化片段導航來計算。為了支持類型的嵌入與嵌套,路徑可以說明嵌套級別與子類型級別。
基於片段的串行化格式還允許支持在不實例化對象的情況下對成員的訪問。如前所述,將路徑用作片段標識符,則成員定位進程,或稱導航器,能導航到任何期望的片段。一旦在一片段中確定位置,此進程可允許訪問該片段本身,或訪問以所定位的片段為根的整個片段序列。通過以到每一片段的映射形式向串行化提供目錄,定位片段甚至能更快地完成。這一目錄可將片段存儲在組織成二叉樹的表中。在這一實現中,每行可存儲一個片段,從而允許片段的路徑被用作每個行的部分關鍵字。
導航器還可有效地跳過對一特定操作不重要的片段。對根據本發明串行化的片段的導航可包含對若干開放的嵌套級或子類型成員的追蹤。一旦導航器到達期望的嵌套級或子類型,則該導航器可對該級或子類型的片段數量進行計數。這一片段自己可開始新一級的嵌套。
進一步探討定位以基於片段的格式串行化的對象的成員的優點,訪問原語成員可包含下列簡單操作。首先,導航器可定位一二進位片段。如上所述,原語成員有利地存儲於此類片段中。接下來,所需成員可用標準、最優的記錄破解代碼來提取。也可用標準、最優的記錄構建代碼將其更新。此簡單操作提供了串行化對象的原語成員的高性能定位,該對象可便利地存儲在單個資料庫列中。如上所述,允許以此風格來定位成員的一個優點是,無需實例化整個宿主對象即可更新成員。這允許替換片段或片段序列,而無須實例化整個對象。每個片段可以是自包含的,可配置本發明可,使得片段序列的標識符是起始嵌套片段及終止符片段的存在。這允許更新性能,而無須在其它任何地方修補長度,也免除了標準記錄格式串行化的偏移量表。
根據本文所闡明的技術生成的片段流的存儲可通過將片段流作為LOB存儲來進行。這一LOB可有樹狀結構的存儲格式,其關鍵字是偏移量位置。用來存儲片段流的這一技術提供了取決於LOB大小的可預測插入與刪除時間。它也允許僅更新LOB的部分。對於片段頭部的形狀,串行為片段的對象的在線(on-wire)格式和盤上格式是一樣的。在除了LOB和FS片段以外的片段的情況下,對於線上與盤上的片段無需任何改變。本發明的此方面允許對象能被快速複製到線上,從而提供了從位置到位置傳輸對象的速度的顯著增益。然而要注意,對於LOB和FS片段,片段的內容可能會改變,以提供額外的靈活性。本發明的此方面連同可能片段類型的總結已在上文解釋。
對片段串行化對象的操作對以給定格式串行化的對象執行操作的簡單性、有效性及靈活性是評價該串行化格式性能的有效標準。如本文所述的本發明實施例的特徵是在這點上的顯著增益。當用本節提供的技術進行操作時,這就尤為真實。然而要注意,以下操作列表不應被認為是根據本發明的技術串行化的對象上的操作的窮盡列表,操作技術的描述也不是進行此類操作的唯一方式。下列操作為參考方便而編號,不是指示在執行操作時的任何順序或序列。相反,每個操作可被獨立執行,或聯合任何其它操作執行。
本發明的優點之一是它允許將對象存儲在資料庫表單獨一列中,如圖9所示,而仍舊允許對象內的成員的高性能搜索與更新能力。在這點上,圖9示出了在資料庫單個列中對象的分類。根據本文闡述的本發明的各實施例,該對象被串行化為包含記錄格式的原語成員的第一片段(這是有細分淨荷的灰色片段),以及可以是此描述中闡述的任意片段的後續片段。在接下來關於對串行化對象的操作的描述中,參考圖9,作為本發明的實施例存儲於資料庫的一個列中的情形的參考。
以下示例性操作將參考類屬用戶定義類型(「UDT」)對象以及為串行此類對象而設計的本發明的特定實施例來解釋。提供了可對被儲存為片段流的UDT對象執行的操作的基本算法。
操作1用其路徑唯一標識對象。當UDT被存為片段序列時,序列中的每個片段可由「路徑」來唯一地標識。路徑是步驟序列,其中每個步驟可以確切地是下列之一1.嵌套步驟,它指定片段ID以指示非原語欄位向UDT的每個非原語欄位分配一唯一片段ID。片段ID從1開始。這包括●其內的大對象(LOB)欄位——諸如無界的或很大長度的字符/二進位數據。這些欄位的每一個都被存儲為單獨的片段。
●其內的文件流欄位,即只是指向文件的指針,該文件包含實際數據並駐於資料庫之外。這些欄位的每一個都被存儲為單獨的片段。
●其內可以是另一UDT(將一UDT嵌套在另一個裡也被稱為UDT的合成)或另一UDT的集合的欄位。例如,UDT A可有UDT B類型的欄位b。此例中,b可被儲存為單個自終止片段,或者如果B有非原語欄位或是另一UDT的子類型,則b可被儲存為片段序列。
注意,當分配片段ID時,無需考慮從超類型繼承的非原語欄位。因而,如果UDT Q是UDT P的子類型,當為UDT Q的非原語欄位分配片段ID時,不考慮P的欄位,儘管Q繼承了所有那些欄位。
還要注意,UDT的非原語欄位是按其片段ID的升序排列的。
2.指定深度的繼承步驟這表明該片段位於哪個子類型段中。可以回憶基本類型的原語和非原語欄位排列在子類型的原語和非原語欄位之前。假設UDT R是UDT Q的子類型,UDT Q是UDT P的子類型。類型R的對象的布局將看起來如下[P的原語欄位的片段]...P的非原語欄位的零個或多個片段...∥此處開始Q段...Q的非原語欄位的零個或多個片段...[R的原語欄位的片段]∥此處開始R段...R的非原語欄位的零個或多個片段...指定深度為2的繼承步驟將指示Q段,而指定深度為3的繼承步驟將指示R段。無需繼承步驟來指示P段。
3.指定定位符的集合成員步驟(定位符唯一地標識了集合的成員。向集合成員分配從1開始的定位符。當集合對象被刪除時,導致定位符中的一個『空隙』,後續成員插入重新使用該定位符。因而,如果沒有刪除成員,則有N個成員的集合的成員將具有從1到N的定位符。)可以回憶,如果UDT A是UDT C的集合,則包含兩個成員的類型A的對象將看起來如下[指示集合開始的片段][指示成員1開始的片段]∥此處有成員1的定位符...成員1的嵌套類型、子類型的0或多個片段(若需要)...[指示成員2開始的片段]∥此處有成員2的定位符...成員2的嵌套類型、子類型的0或多個片段(若需要)...[集合的終止符]指示成員1的定位符的集合成員步驟將指示成員1的段,而指示成員2的定位符的集合成員步驟將指示成員2的段。
複合UDT中的任何片段可用嵌套步驟、定位符步驟和繼承步驟的適當排列來唯一地定位。
包含按該順序的n個步驟S1,S2,...,Sn的路徑被表示為S1.S2...Sn。並且,如果P是路徑,用記號size(P)來表示P中的步驟數,並用P[i]來表示P的第i個步驟,其中i>0。
操作2,在字節流上實現片段流。多年以來,資料庫支持有界和無界長度的字符/二進位數據。在字符/二進位數據之上提供字節流接口是一種已知的技術。字節流接口包括諸如下面的方法1.從某一指定的偏移量『s』開始讀取『n』個字節。
2.從某一指定的偏移量『s』開始插入『n』個字節。概念上,從偏移量『s』開始的預先存在的數據被移動了『n』個字節,所造成的『空隙』用所提供的『n』個字節填充。然而,當字節流較大時,各實現足夠聰明,不會實際地移動大量數據。它們使用構建在字節流之上的索引結構來達到目的。
3.1的變體,其中,以支持字節流接口的對象的形式請求讀取的數據。
4.2的變體,其中,以支持字節流接口的另一對象的形式提供要插入的新數據。
5.用所提供的數據替換從某一指定偏移量『s』開始的『n』個字節。注意,所提供的數據可以為『空』,這種情形下的效果是移除從偏移量『s』開始的『n』個字節。
6.5的變體,其中,以支持字節流接口的對象的形式來提供新數據。
注意,上面列表試圖成為代表性而不是窮舉性的。如前面所提及的,UDT被儲存為片段流。片段流可在字節流之上實現。
操作3根據路徑信息定位片段。考慮表示UDT的片段流。本節解釋給定其路徑後如何定位其中的片段。
如果路徑有效,則必須找到對應於該路徑的片段,除非在半路遇到空UDT,這種情形下不能繼續遍歷,並且可認為該片段未找到。例如,當在『部門』UDT中尋找『經理』欄位時,如果『部門』對象的片段自身是空片段,那麼此方法返回FALSE來指示『經理』的片段未找到。
注意,方案進化引入另一情況,其中對應於路徑的片段可能丟失,即使該路徑有效。這裡是LocateFragment(定位片段)的基本算法。最初,FragmentStream(片段流)對象中的currentPath(當前路徑)是空路徑,當前片段是第一片段。BOOLEANFragmentStreamLocateFragment(Path目標路徑){∥假設targetPath有N個步驟,第k個步驟為Sk。
∥此循環的第i次迭代結束時,當前路徑將是S1.S2...Si∥For(i=1;i<=N;i++){∥此級遇到空UDT。目標路徑有更多步驟,∥但我們無法繼續遍歷。返回未找到。
∥If(當前片段是空片段)Return FALSE;∥這將移到下一級的第一片段∥因此一新步驟會被添加到當前路徑∥且其將有i個步驟。
GetNextFragment;∥稼0段∥這將繼續前進直到currentPath的第i個步驟
∥與targetPath的第i個步驟匹配。
AdvanceTillStep(i,targetPath);∥見第0段}∥找到該片段,且現在正處於該位置。
Return TRUE;}FragmentStreamAdvanceTillStep。為補充定位片段,還可使用此「前進至步驟」操作。此方法根據下面規則比較兩個步驟。首先,如果一『嵌套步驟』的片段ID小於另一『嵌套步驟』的片段ID,則前者小於後者。第二,如果一『繼承步驟』的深度小於另一『繼承步驟』的深度,則前者小於後者。第三,如果一『定位符步驟』的定位符小於另一『定位符步驟』的定位符,則前者小於後者。第四,『嵌套步驟』總是小於『繼承步驟』(因為我們將所有嵌套欄位存儲在子類型欄位之前)。最後,『定位符步驟』與『嵌套步驟』或『繼承步驟』不可比較,試圖進行此類比較是錯誤的。例如,參考下面算法∥前置條件當前路徑的前i-1個步驟已經與目標路徑的前i-1個步驟匹配∥路徑及第i個步驟不大於targetPath的第i個步驟。∥∥後置條件當前路徑的前i個步驟已經與目標路徑的前i-1個步驟匹配。FragmentStreamAdvanceTillStep(Step#I,PathtargetPath){While(currentPath[i]<targetPath[i]){∥此函數恰當地更新currentPath∥GetNextFragmentO;∥見第0段}}FragmentStreamGetNextFragment。此外,獲得下一片段的操作可如下實現FragmentStreamGetNextFragment{S=currentPath中的最後一個步驟,或者如果currentPath為空則為NULL;prevFragment=currentFragment;∥通過執行當前位置=當前位置+當前片段長度∥前進至下一片段∥移到下一片段
If(prevFragment是自終止的){If(當前片段是用於嵌套欄位的)遞增S的片段ID ∥S必須是嵌套步驟Else if(當前片段是用於子類型的){IfS是嵌套步驟thenS=深度為2的繼承步驟Else∥S必須是繼承步驟遞增S的深度}Else if(當前片段是用於集合成員的){∥S必須是定位符步驟S=定位符值從此成員獲得的定位符步驟}Else if(當前片段為終止符)從當前路徑中移除步驟S}Else{ 添加如下初始化的新步驟S1If(當前片段是用於嵌套欄位的)S1=片段ID=1的嵌套步驟Else if(當前片段是用於子類型的){S1=深度為2的繼承步驟}Else if(當前片段是用於集合成員的){S1=定位符值從此成員獲得的定位符步驟}Else if(當前片段是終止符){∥無需S1從當前路徑中移除步驟S1}}}操作4選擇原語欄位。原語欄位的選擇首先牽涉用其路徑來定位包含該原語欄位的片段。此片段的淨荷是記錄格式,並具有原語欄位。接下來,可用標準優化記錄操縱代碼來從淨荷中提取該原語欄位。
操作5更新原語欄位。更新原語欄位可三步完成首先,以與選擇原語欄位相同的方式用其路徑定位包含該原語欄位的片段。接下來,作出該片段的淨荷的副本,並用標準優化記錄操縱代碼來替換需用新值更新的原語欄位的舊值。這給出了一個新淨荷,它可以比原始淨荷長或短。第三,通過用新淨荷替換舊淨荷來更新該片段。注意,這可能增加或減少片段的長度,且必須據此調整其長度。
操作6複製整個嵌入的UDT。複製出整個嵌入的UDT首先牽涉到使用如上所述的locateFragment,來根據該嵌入UDT的路徑定位標記該嵌入的UDT的起始的片段。接下來,可用如下解釋的CopyOutFragmentSequence函數來複製出屬於該嵌入的UDT的片段。
為補充複製UDT,可使用FragmentStreamCopyOutFragmentSeuqence函數,該函數使用下面基本算法∥前置條件當前定位於標記嵌入的UDT的起始的片段。∥FragmentSTream對象的currentPath給出了嵌入的UDT的路徑。∥∥將表示該嵌入的UDT的片段流複製到目標FragmentStream∥FragmentStreamCopyOutFragmentSequence(FragmentStream目標){已終止=FALSE;pathToThisUDT=currentPath;∥記住此UDT的路徑。while(1){If(這是被複製的第一片段)(此片段是自終止的)已終止=TRUE;∥注意如果這是被複製的第一片段,並且是集合成員片段,∥那麼剝去定位符,將其按二進位片段複製∥將當前片段複製到目標If(已終止)Break;∥注意這將改變當前路徑、當前片段等等∥GetNextFragment;∥CanContinueNavigation確定是否要複製此片段。∥它也可將已終止設置為TRUE。在下面解釋。∥If(CanContinueNavigation(pathToThisUDT,已終止)){Continue;}}}再進一步,繼續導航函數「FragmentStreamCanContinueNavigation」可遵循此基本算法∥給定到我們正在複製的嵌套UDT的路徑,∥以及當前路徑(在FragmentStream的狀態中可用),∥此方法確定是否要複製下一個片段。
∥並且如果下一個片段是要複製的最後一個片段,它將lastFragment設為TRUE。
BOOLEANFragmentStreamCanContinueNavigation(Path pathToThidUDT,BOOLEAN lastFragment∥輸出參數){If(size(currentPath)==size(pathToThisUDT)){∥在本例中僅餘終止符片段要複製lastFragment=TRUE;retum TRUE;}∥否則,當前路徑的步驟數必須大於pathToThisUDT中的步驟數∥指示當前片段是嵌套在正在複製的UDT中∥Return TRUE}操作7移除嵌入的UDT的所有片段。類似於CopyOutFragmentSequence,提供了方法DeleteFragmentSequence來刪除屬於一嵌入的UDT的所有片段。對於每個片段,底層的ByteStream(字節流)類可用於移除該片段的字節。如果該片段是文件流片段,則需要特殊處理來實際刪除底層文件。
操作8用新UDT更新嵌入的UDT。一種被發明人稱作「FragmentStreamReplaceFragmentSequence」的算法可首先用其路徑來定位一嵌入的UDT,接下來用DeleteFragmentSequence來刪除屬於該嵌入的UDT的所有片段,最後讀取新UDT的片段,並將它們插入到當前位置。底層字節流類也可用於放置新片段的字節。當需要創建具有恰當數據的文件,且指向該文件的指針需要放到該片段中時,需要特殊處理來插入文件流片段。
操作9插入集合成員。考慮將以FragmentStream對象形式提供的UDT對象A作為代表對象B的GragmentStream對象的集合中的成員插入。下面的算法被發明者稱為FragmentStreamInsertCollectionElement首先用到該集合的路徑在B中定位該集合。接下來,找到定位符和插入位置。如前面所提及的,如果早些時候刪除了集合成員,它導致定位符中的一個『空隙』。如果有任何諸如此類的空隙存在,則該未使用的定位符被分配給新成員,並插入其以使得所有成員按定位符的升序排列。否則,向新成員分配比最後一個成員大1的定位符,並將其插到最後一個成員之後。注意,A的第一片段須作修改來放入定位符。
操作10刪除集合成員。一種發明人稱為「FragmentStreamDeleteCollectionElement」的算法能用其定位符來指定要刪除的成員。刪除首先牽涉到用其路徑來定位集合,接下來在該集合內定位要刪除的成員。注意,給定其路徑來定位片段是較簡單的問題,因為這裡只是處理定位符步驟。因而可為此使用LocateFragment方法中類似的邏輯。接下來,一旦位於屬於要刪除的成員的第一片段,調用DeleteFragmentSequence。
操作11更新整個集合或單個集合成員。用一不同集合來替換整個集合是以與用另一UDT替換一嵌入的UDT相同的方式進行的。類似地,一旦定位了集合成員,可以用與更新嵌入的UDT相同的方式將其更新。
操作12選擇或更新UDT的多個欄位。當選擇或更新多個欄位時,執行下面的優化首先,將選擇/更新排序。兩個步驟的比較與排序已在上面解釋。路徑可被視為一串步驟,且可在路徑上定義「字典」順序。參考下面算法INTComparePath(Path P1,Path P2){minSteps=MIN(size(P1),size(P2))for(i=1;i<=minSteps;i++){If(Pi[i]<P2[i])Return-1;∥P1<P2Else if(P1[i]>P2[i])Return1;∥P1>P2}∥與兩者都匹配的第一個minStepsIf(size(P1)<size(P2))Return-1;∥P1<P2Else if(size(P1)>size(P2))Returnl; ∥P1>P2ElseReturn0; ∥P1=P2
}各個欄位是按到包含它們的片段的路徑的升序來選擇或更新的。注意,此排序與各個片段出現在片段流中的順序相同。多個原語欄位可位於同一片段中。在這種情形下,一旦訪問了包含它們的片段,就使用標準記錄操縱代碼來有效地選擇或更新所有期望的欄位,而無需再次訪問此片段。通過如上所述地進行,即使在複合UDT中,選擇或更新UDT的所有期望欄位最多需要經過其片段流一次。
操作13增強LocateFragment來利用當前位置。前面對LocateFragment算法的描述總是在片段流的起始處開始。然而,LocateFragment只在定位包含需選擇或更新的第一個欄位的片段時才需要從頭開始。為定位包含需選擇或更新的後續欄位的片段,locateFragment可從當前位置開始。LocateFragment所需的增強在下面簡略地提及。這裡有兩種基本情況1.currentPath==prefix(targetPath),即currentPath中的所有步驟與targetPath中的步驟相匹配,但目標路徑有一些額外的步驟。在此情況中,locateFragment可從I=size(currentPath)+1的迭代開始,而不是從i=0的迭代開始。
2.對於某一k<sizeof(currentPath),currentPath的前k個步驟與targetPath中的前k個步驟相匹配,但第k+1個步驟不匹配。注意,在此情況中,currentPath[k+1]必須小於targetPath[k+1],因為路徑可能已經按升序來排序。在此情況中,locateFragment也可從i=k+1迭代的AdvanceTil1Step開始。
操作14惰性具體化(Lazy Materialization)。當從服各器向客戶機發送一UDT的串行化時,發送LOB數據及來自文件流欄位的文件數據往往成為最費時的因素。因此片段流管理器可提供一『惰性具體化』選項。
當用『惰性具體化』選項來請求UDT的串行化時,返回『cookies』來代替LOB/文件流數據。調用者隨後可通過傳遞LOB/文件流片段的路徑及『cookie』來請求完整的LOB/文件流數據。該路徑與cookie給出足夠的信息,讓片段流管理器檢索LOB/文件流數據。
操作15方案進化。方案進化指通過添加、移除或修改UDT的欄位(諸如改變欄位的數據類型)來改變UDT,或通過定義新UDT來改變繼承的分層結構。諸如此類的改變可影響已被持久化的UDT實例。一個簡單的解決方案是,當添加新欄位時,確保分配給現存欄位的任何欄位ID和片段ID繼續保持相同。那麼就可以支持向UDT添加新欄位,而無須修改任何預先存在的UDT的持久化實例。
最後,應當理解,本文描述的各種技術可結合硬體或軟體,或在適當時用兩者的組合來實現。因而,本發明的方法與裝置,或其某些方面或部分,可採用包含於有形介質(諸如軟盤、CD-ROM、硬碟或其它機器可讀存儲介質中)的程序代碼(即指令)的形式,其中,當程序代碼被機器(諸如計算機)載入並執行時,該機器成為用於實施本發明的裝置。在執行於可編程計算機的程序代碼的情況下,計算設備一般包括處理器、處理器可讀存儲介質(包括易失性與非易失性存儲器和/或存儲元件)、至少一個輸入設備以及至少一個輸出設備。可實現或利用本發明的用戶界面技術(例如,通過使用數據處理API、可重複使用控制等等)的一個或多個程序較佳地以高級過程語言或面向對象的程式語言來實現,來與計算機系統通信。然而,如有需要,這些程序可用彙編語言或機器語言來實現。無論如何,語言可以是已編譯或已解釋的語言,並與硬體實現相結合。
儘管示例性實施例涉及在一個或多個獨立計算機系統的環境中使用本發明,然而本發明不受此限制,而是可結合任何計算環境(諸如網絡或分布式計算環境)來實現。此外,本發明可在多個處理晶片或設備之內或之間實現,且存儲也可類似地跨越多個設備而實現。此類設備可包括個人計算機、網絡伺服器、手持式設備、巨型計算機、或集成在諸如汽車和飛機等其它系統中的計算機。因此,本發明不應限制於任何單個實施例,而是應當根據所附權利要求書的廣度與範疇來解釋。
附錄A片段確認過程以下算法描述可用於確認片段的頂層計算機進程命令。
class Fragment{public∥---------------------------∥FragType與FragTypeModifier存儲在第一字節中∥---------------------------enum FragType
{FragType_Invalid=0,FragType_Binary=1,FragType_Lob=2,FragType_Fs=3,FragType_CollectionStart=4,FragType_Terminator=5,∥6-7未使用FragType_Max=7,FragType_Bits=3,FragType_Mask=0x7,};enum_FragTypeModifiers{TypeMod_CollectionElement=0x8,TypeMod_SelfTerminator=0x10,TypeMod_NullFragment=0x20,TypeMod_Subtype=0x40,TypeMod_Max=0xF0,TypeMod_Mask=0xF8,};∥------------------------∥第一字節枚舉結束∥------------------------∥------------------------附加位存儲在第二字節中∥------------------------enum_LobFsValueType{ValueType_Pointer=1,ValueType_Inlined=2,ValueType_Delayed=3,
};DECLARE_SAFE_ENUM(LobFsValueType,LobFsValueType);enum_CollectionType{CollType_Unordered=1,};∥-------------------------∥第二字節枚舉結束∥-------------------------};片段確認代碼一種替換設計如下所述,其中串行化的語法以巴科斯-諾爾範式(「BNF」)示出。
引號「」中的符號是終止。例如「自終止二進位片段」表示一個終止。各種終止符號在前面的章節中定義。
尖括號中的符號表示非終止。例如,包含片段是非終止。
花括號{}中的符號指示符號可重複零次或多次。例如,{包含片段}指示可能有零或多個包含片段的實例。
註解片段可存在於流的任何地方。
udt_serialization=「自終止二進位片段」|明確地終止的二進位片段
明確地終止的二進位片段=「開口的二進位片段」嵌套片段
「終止符片段」嵌套片段=包含片段{包含片段}|子類型片段{子類型片段}|包含片段
{包含片段}子類型片段
{子類型片段}包含片段=LOB/FS片段|udt_serialization|集合
子類型片段=「自終止子類型二進位片段」|明確地終止的子類型二進位片段
明確地終止的子類型二進位片段=「開口的子類型二進位片段」{包含片段}「終止符片段」LOB/FS片段=「空LOB/FS片段」|「LOB/FS作為指針片段」|「LOB/FS作為延遲的參考片段」|「LOB/FS作為內聯片段」集合={空集合起始片段}|「集合起始片段」集合元素{集合元素}「終止符片段」集合元素二進位片段=「空集合元素二進位片段」|「自終止集合元素二進位片段」|明確地終止的集合元素二進位片段
明確地終止的集合元素二進位片段=「開口的集合元素二進位片段」
嵌套片段
「終止符片段」註解片段=「自終止片段」
權利要求
1.一種作為一數據對象存儲在一起的一個或多個數據成員,其特徵在於,包含多個順序地存儲的字節;以及在所述多個順序地存儲的字節中表示的至少一個數據成員,其中,所述至少一個數據成員與一數據類型相關;以及在所述多個順序地存儲的字節中用來標識所述至少一個數據成員的數據類型的至少一個類型字節,其中,所述至少一個類型字節處於充分接近所述至少一個數據成員之處。
2.如權利要求1所述的一個或多個數據成員,其特徵在於,所述至少一個數據成員以一種記錄格式存儲,且其中,所述記錄格式定義了所述至少一個數據成員關於所述至少一個類型字節的可預測位置。
3.如權利要求所述的一個或多個數據成員,其特徵在於,還包含所述多個順序地存儲的字節的至少一個長度字節,用於標識所述至少一個數據成員的長度。
4.如權利要求1所述的一個或多個數據成員,其特徵在於,所述至少一個數據成員指示與所述數據對象相關的數據的位置,且所述位置與一位置類型相關,且所述多個順序地存儲的字節中至少一個位置字節用來標識所述位置類型。
5.如權利要求1所述的一個或多個數據成員,其特徵在於,所述至少一個類型字節是所述多個順序地存儲的字節中的第一字節,並指示所述數據對象的開始。
6.如權利要求5所述的一個或多個數據成員,其特徵在於,所述至少一個類型字節指示數據對象的類型。
7.如權利要求1所述的一個或多個數據成員,其特徵在於,所述數據類型是從一組中選出的,該組包含除大對象(「LOB」)外的原語數據類型、大對象(「LOB」)數據類型、文件流(「FS」)數據類型及集合元素數據類型。
8.如權利要求7所述的一個或多個數據成員,其特徵在於,如果所述至少一個數據成員與除LOB外的原語數據類型相關,那麼所述至少一個數據成員以記錄格式存儲,其中,所述記錄格式定義了所述至少一個數據成員關於所述至少一個類型字節的可預測位置。
9.如權利要求1所述的一個或多個數據成員,其特徵在於,所述至少一個類型字節指示所述至少一個數據成員是所述數據對象僅有的一個或幾個成員。
10.如權利要求1所述的一個或多個數據成員,其特徵在於,還包括所述多個順序地存儲的字節中的至少一個集合起始字節,其中,所述至少一個集合起始字節用於指示一系列相關數據成員的開始,所述數據成員存儲在充分接近所述至少一個集合起始字節之處。
11.如權利要求1所述的一個或多個數據成員,其特徵在於,還包括所述多個順序地存儲的字節中的至少一個終止符字節,其中,所述至少一個終止符字節用於指示一系列數據成員的結束。
12.如權利要求1所述的一個或多個數據成員,其特徵在於,還包括所述多個順序地存儲的字節中的至少一個字節,該字節與作為一數據成員集合的一部分的第一數據成員相關,其中,所述少一個字節提供關於作為所述數據成員集合的一部分的第二數據成員的信息。
13.如權利要求1所述的一個或多個數據成員,其特徵在於,還包括存儲在充分接近所述至少一個數據成員之處的至少一個二叉樹(「b樹」)號碼。
14.一種用於存儲或發送由至少一個數據成員組成的數據對象的方法,其特徵在於,包括在多個順序地存儲的字節內表示至少一個數據成員,其中,所述至少一個數據成員與一數據類型相關;以及將所述多個順序地存儲的字節內的至少一個字節專用於標識所述至少一個數據成員的類型信息,其中,所述至少一個字節位於充分接近所述至少一個數據成員之處。
15.如權利要求14所述的方法,其特徵在於,標識所述至少一個數據成員是用記錄格式來完成的,且所述記錄格式定義了所述至少一個數據成員關於所述至少一個類型字節的可測位置。
16.如權利要求14所述的方法,其特徵在於,還包含了將所述多個順序地存儲的字節中的至少一個字節專用於標識所述至少一個數據成員的長度。
17.如權利要求14所述的方法,其特徵在於,所述至少一個數據成員指示與所述數據對象相關的數據位置,且所述位置與一位置類型相關,且所述多個順序地存儲的字節中的至少一個位置字節用於標識所述位置類型。
18.如權利要求14所述的方法,其特徵在於,所述至少一個字節是所述多個順序地存儲的字節中的第一字節,且指示所述數據對象的開始。
19.如權利要求14所述的方法,其特徵在於,所述至少一個類型字節指示一種類型的數據對象。
20.如權利要求14所述的方法,其特徵在於,所述數據類型是從一組中選出的,該組包含除大對象(「LOB」)外的原語數據類型、大對象(「LOB」)數據類型、文件流(「FS」)數據類型及集合元素數據類型。
21.如權利要求20所述的方法,其特徵在於,如果所述至少一個數據成員與除LOB外的原語數據類型相關,那麼所述至少一個數據成員以記錄格式儲存,其中,所述記錄格式定義了所述至少一個數據成員關於所述至少一個類型字節的可預測位置。
22.如權利要求14所述的方法,其特徵在於,所述至少一個類型字節指示所述至少一個數據成員是所述數據對象僅有的一個或幾個成員。
23.如權利要求14所述的方法,其特徵在於,還包含將所述多個順序地存儲的字節中至少一個字節專用於標記一系列相關數據成員的開始,所述數據成員儲存於充分接近所述至少一個集合起始字節之處。
24.如權利要求14所述的方法,其特徵在於,還包括所述多個順序地存儲的字節中的至少一個終止符字節,其中,所述至少一個終止符字節用於指示一系列數據成員的結束。
25.如權利要求14所述的方法,其特徵在於,還包括將所述多個順序地存儲的字節中的至少一個字節專用於提供關於作為所述數據成員集合的一部分的第二數據成員的信息,其中,所述至少一個字節與作為所述數據成員集合的一部分的第一數據成員相關。
26.一種包含用於執行如權利要求14所述方法的指令的計算機可讀介質。
27.一種包含執行如權利要求14所述方法的指令的已調製數據信號。
28.一種儲存或發送由一個或多個數據成員組成的數據對象的方法,其特徵在於,包含將多個順序地定位的字節劃分成至少一個頭部段與至少一個淨荷段,其中,所述至少一個頭部段與所述至少一個淨荷段相互接近地定位;以及在所述淨荷段內表示至少一個數據成員,其中,所述至少一個數據成員與一數據類型相關;以及將所述至少一個數據成員以一種記錄格式放到所述淨荷段中,其中,所述記錄格式定義所述至少一個數據成員關於所述淨荷段中的任何其它成員的可預測位置。
29.如權利要求28所述的方法,其特徵在於,所述至少一個數據成員與一原語數據類型相關。
30.如權利要求28所述的方法,其特徵在於,還包括在所述頭部段中表示淨荷長度。
31.如權利要求28所述的方法,其特徵在於,還包括將所述多個順序地定位的字節進一步劃分成至少一個第二頭部段與至少一個第二淨荷段,其中,所述至少一個第二頭部段與所述至少一個第二淨荷段相互接近地定位;以及在所述至少一個第二淨荷段中表示所述至少一個第二數據成員的位置信息,其中,所述位置信息指定一位置類型的位置;以及在所述第二頭部段中標識所述位置類型。
32.如權利要求31所述的方法,其特徵在於,還包括將一LOB類型數據成員放到所述至少一個第二淨荷段中。
33.如權利要求31所述的方法,其特徵在於,還包括將一FS類型數據成員放到所述至少一個第二淨荷段中。
34.如權利要求31所述的方法,其特徵在於,還包括在所述至少一個第二頭部段中表示一淨荷長度。
35.如權利要求28所述的方法,其特徵在於,還包括將所述多個順序地定位的字節進一步劃分成至少一個第二頭部段;以及用所述至少一個第二頭部段中標記一相關數據成員集合的開始,此集合位於充分接近所述至少一個第二頭部段之處。
36.如權利要求35所述的方法,其特徵在於,還包括在所述至少一個第二頭部段中指示所述相關數據成員的集合是有序還是無序。
37.如權利要求28所述的方法,其特徵在於,還包括將所述多個順序地定位的字節進一步劃分成至少一個第二頭部段;以及用所述至少一個第二頭部段標記所述數據對象的結束。
全文摘要
一種基於片段的串行化方法與系統將一個或多個對象成員放到片段中。片段可包含一頭部及一淨荷。頭部可提供關於該片段的有用信息,諸如片段類型的指示和片段長度的指示。淨荷可包含對象的一個或多個成員。原語成員可用一記錄格式淨荷存儲在一二進位片段中。LOB和FS成員可存儲在具有用於闡明該片段的附加屬性的值類型欄位的片段中。集合可以存儲在一系列片段中,第一片段指示集合的開始,一個或多個第二片段來將集合元素串行化,一終止符片段指示集合的結束。片段串行化的對象使存儲額外開銷最小化,而同時提供快速實例化與低成本的定位與更新。
文檔編號G06F17/00GK1761956SQ200480001714
公開日2006年4月19日 申請日期2004年7月29日 優先權日2004年4月9日
發明者F·S·特瑞克, A·卡爾漢, N·波內坎蒂, S·蘭加拉傑, M·J·茲威林 申請人:微軟公司