(57)【特許請求の範囲】
【請求項１】
エレメントのハイアラーキ構成に対する変更を処理するコンピュータシステムにおける方法であって、
前記ハイアラーキ構成は、少なくとも第１のエレメントと第２のエレメントを含み、前記第２のエレメントは、エレメントのハイアラーキ構成において第１のエレメントの親であることを特徴とし、
前記第１のエレメントにおける変更に対しては、当該第１のエレメントがトランザクションモードであるか直接モードであるかを決定するステップと、
前記第１のエレメントがトランザクションモードであれば、当該変更を第１のエレメントのところでバッファするステップと、
前記第１のエレメントが直接モードであれば、当該変更を第２のエレメントに渡すステップと、を含むことを特徴とする方法。
【請求項２】
エレメントの前記ハイアラーキ構成は、複合文書のためのものであり、前記第１のエレメントは前記複合文書中の第１のオブジェクトのためのものであることを特徴とする請求項１に記載の方法。
【請求項３】
前記第１のエレメントがトランザクションモードであることを特徴とし、
前記第１のエレメントのためのコミットする動作の一部として、前記バッファされた変更を前記第２のエレメントに渡すステップをさらに有する請求項１に記載の方法。
【請求項４】
前記第１のエレメントがトランザクションモードであることを特徴とし、
前記第１のエレメントのための復帰する動作の一部として、前記バッファされた変更を捨てるステップをさらに有する請求項１に記載の方法。
【請求項５】
前記変更が前記第２のエレメントへと渡されたことと、前記第２のエレメントは前記ハイアラーキ構成のルートであることとを特徴とし、
前記第２のエレメントがトランザクションモードであるか直接モードであるかを決定するステップと、
前記第２のエレメントがトランザクションモードであれば、当該変更を第２のエレメントのところでバッファするステップと、
前記第２のエレメントが直接モードであれば、ファイルに変更を行うステップと、をさらに有する請求項１に記載の方法。
【請求項６】
前記第２のエレメントはトランザクションモードか直接モーであることを特徴とし、
前記第２のエレメントのためのコミットする動作の一部として、前記変更を前記ファイルに行うステップをさらに有する請求項５に記載の方法。
【請求項７】
前記変更を行うステップは、前記変更をストレージデバイス中の未使用空間に書き込むステップを含むことを特徴とする請求項５に記載の方法。
【請求項８】
前記変更を行うステップは、前記変更でストレージデバイス中のデータを上書きするステップを含むことを特徴とする請求項５に記載の方法。
【請求項９】
前記変更が前記第２のエレメントへと渡されたことを特徴とし、
前記第２のエレメントがトランザクションモードであるか直接モードであるかを決定するステップと、
前記第２のエレメントがトランザクションモードであれば、当該変更を第２のエレメントのところでバッファするステップと、
前記第２のエレメントが直接モードであれば、エレメントのハイアラーキ構成において前記第２のエレメントの親である第３のエレメントへと前記変更を渡すステップと、をさらに有する請求項１に記載の方法。
【請求項１０】
エレメントのハイアラーキ構成に対する変更を処理するコンピュータシステムにおける方法であって、
前記ハイアラーキ構成中の現在のエレメントのための変更に対しては、当該現在のエレメントがトランザクションモードであるか直接モードであるかを決定するステップと、
前記現在のエレメントがトランザクションモードであれば、前記変更を前記現在のエレメントのところでバッファするステップと、
前記現在のエレメントが直接モードである場合については、前記現在のエレメントが前記ハイアラーキ構成のルートであれば前記変更をファイルに行い、前記現在のエレメントが前記ハイアラーキ構成のルートでなければ、前記現在のエレメントの親のエレメントへと前記変更を渡して当該親のエレメントを現在のエレメントとして使用してこの方法を反復するステップと、を含むことを特徴とする方法。
【請求項１１】
前記現在のエレメントはトランザクションモードであり、かつ、前記ハイアラーキ構成のルートであることを特徴とし、
コミットする動作の一部として、前記変更を前記ファイルに行うステップをさらに有する請求項１０に記載の方法。
【請求項１２】
前記現在のエレメントがトランザクションモードであることを特徴とし、
コミットする動作の一部として、前記バッファされた変更を前記親のエレメントへと渡すステップをさらに有する請求項１０に記載の方法。
【請求項１３】
前記現在のエレメントはトランザクションモードであることを特徴とし、
復帰する動作の一部として、前記バッファされた変更を捨てるステップをさらに有する請求項１０に記載の方法。
【請求項１４】
エレメントの前記ハイアラーキ構成は、複合文書のためのものであり、前記現在のエレメントは前記複合文書中の第１のオブジェクトのためのものであることを特徴とする請求項１０に記載の方法。
【請求項１５】
ルートのエレメントを除き親のエレメントを有する複数のエレメント中に論理的に編成されたデータを変更するコンピュータシステムにおける方法であって、
トランザクションモードのエレメントのためのデータの変更に対しては、トランザクションモードの前記エレメントに関連して当該変更をバッファするステップと、
直接モードのエレメントのためのデータの変更に対しては、直接モードの当該エレメントがトランザクションモードの親のエレメントを有するなら、トランザクションモードの前記親のエレメントに関連して前記変更をバッファし、直接モードの当該エレメントがトランザクションモードの親のエレメントを有しないなら、前記変更に従ってファイル中の前記データを変更するステップと、を有することを特徴とする方法。
【請求項１６】
前記変更がトランザクションモードの前記エレメントに関連してバッファされたことを特徴とし、
トランザクションモードの前記エレメントに関連してバッファされた前記変更をコミットするために、トランザクションモードの前記エレメントがトランザクションモードの親のエレメントを有するなら、トランザクションモードの前記親のエレメントに関連して前記変更をバッファし、トランザクションモードの前記エレメントがトランザクションモードの親のエレメントを有しないなら、前記変更に従って前記ファイル中の前記データを変更するステップをさらに有することを特徴とする請求項１５に記載の方法。
【請求項１７】
前記データを変更する際に、前記変更に従って永続的ストレージ中の前記ファイルの新しい部分を書き込む頑強モードと、
前記データを変更する際に、前記変更に従って永続的ストレージ中の前記ファイルの古い部分を上書きする非頑強モードと、をさらに有することを特徴とする請求項１５に記載の方法。
【請求項１８】
前記変更がトランザクションモードの前記エレメントに関連してバッファされたことを特徴とし、
トランザクションモードの前記エレメントに関連してバッファされた前記変更から復帰するために、前記変更を捨てるステップをさらに有することを特徴とする請求項１５に記載の方法。
【発明の詳細な説明】
【０００１】
【産業上の利用分野】
本発明は、データ記憶方法及びシステムに係り、より詳細には、複合文書にデータを記憶しそしてアクセスする方法及びシステムに係る。
【０００２】
【従来の技術】
コンピュータのオペレーティングシステムは、一般に、ファイルシステムと称するサブシステムを備えている。ファイルシステムは、データをファイルに記憶する。ファイルシステムは、ディスク又は他の長時間記憶媒体に記憶されたデータのアクセスを容易にするためにアプリケーションプログラミングインターフェイス（ＡＰＩ）を備えている。ファイルシステムのＡＰＩは、データをアクセスするためにアプリケーションプログラムによって呼び出される種々の機能を与える。アプリケーションプログラムは、ファイルの内部フォーマットを制御し、どのデータをどのファイルに記憶するかを決定する。ファイルシステムは、通常、ファイルをディレクトリーにグループ分けすることができる。各ディレクトリーは、多数のファイルと、多数のサブディレクトリーとを備えている。サブディレクトリーも、ファイルと、他のサブディレクトリーを備えている。ファイルをディレクトリー及びサブディレクトリーにグループ分けするファイルシステムは、ハイアラーキ式ファイルシステムと称する。
【０００３】
多くのアプリケーションプログラムは、種々の形式のデータをアクセスする必要がある。例えば、ワードプロセスプログラムは、テキスト、グラフ及びスプレッドシートフォーマットのデータを１つの文書に合成することができる。テキストフォーマットは、ワードプロセスプログラムについてはネーティブフォーマットとして知られている。ワードプロセスプログラムのユーザは、ファイルに記憶されたグラフデータ又はスプレッドシートデータのいずれを文書に含ませるかを指定することができる。これを行うために、ワードプロセスプログラムは、グラフプログラム又はスプレッドシートプログラムによって発生されたファイルからデータをインポートすることができる。ワードプロセスプログラムは、一般に、グラフ及びスプレッドシートファイルの内部フォーマットを知る必要があるだけでなく、グラフ及びスプレッドシートデータをいかに表示又はプリントするかも知らねばならない。
【０００４】
多数のフォーマットで記憶されたデータをインポートできる機能があれば、ワードプロセスプログラムの市場性は増大する。しかしながら、特定の非テキストフォーマットのデータをアクセスするようにワードプロセスプログラムを適応させるのは非常に時間がかかり且つ経費もかかる。このようにワードプロセスプログラムを適応させるには、開発者がその特定フォーマットの完全な説明を得て、データをプリント、表示及びおそらくは記憶するためのコードを開発する必要がある。フォーマットが別の業者によって定められたときには、ワードプロセスプログラムをその特定のフォーマットに適応させるのに必要な努力が多大となる。
このような業者は、そのフォーマットの完全な仕様を公表しないこともあるし、通告せずにフォーマットを変更することもある。従って、アプリケーションプログラムの開発者は、ネーティブファイルフォーマットではなくて若干のより一般的なファイルフォーマットのみをサポートするよう選択することになる。
【０００５】
【発明が解決しようとする課題】
これまでに示唆されている１つの解決策は、ワードプロセス文書の一部分である非テキストデータを表示又はプリントするために特定の非テキストフォーマットでデータを発生したアプリケーションプログラムをワードプロセスプログラムで呼び出すことである。例えば、文書にグラフが合体される場合、ワードプロセスプログラムは、そのグラフをプリント又は表示するためのデータを発生したか或いはそのデータを用いて他のタスクを実行したグラフプログラムを呼び出す。
しかしながら、グラフプログラムが特定のワードプロセスプログラムによって呼び出されるように特に開発されてない限り、グラフプログラムを呼び出すことは実際上できない。グラフプログラムは、一般に、データがあるフォーマットでファイルにグラフデータのみと共に記憶されることを予期するものである。
【０００６】
ワードプロセスプログラムが、ワードプロセス文書の一部である非テキストデータをプリント、表示又はその他処理するために他のプログラムを呼び出せるようにする多数の解決策が示唆されている。第１の解決策は、非テキストデータを発生するプログラムがワードプロセス文書の内部フォーマットを知って、その文書から非テキストデータを検索しそしてその検索したデータを処理できるようにこれらプログラムの各々を変更することである。この解決策は、プログラムが各ワードプロセスプログラムの内部フォーマットを知る必要があるので、高価なものとなる。
【０００７】
第２の解決策は、ワードプロセス文書の各成分を個別のファイルに記憶するものである。この解決策を用いると、データワードは各アプリケーションプログラムのネーティブフォーマットで記憶される。従って、アプリケーションプログラムを呼び出してネーティブデータを直接処理することができる。しかしながら、この第２の解決策は、ワードプロセス文書の完全性を損なわせる。ユーザは、通常、オペレーティングシステムのコマンドを用いてファイルを削除することができる。ユーザは、ワードプロセス文書の一部であるファイルの１つを削除することができる。このとき、ワードプロセス文書は、削除されたファイルに対するリンクをもつことになる。
【０００８】
合体される非テキストデータが異なるプログラムに属する他の非テキストデータを追加的に含むときには、遭遇する問題が複雑になる。この状態を、データの任意ネスティングと称している。例えば、ワードプロセス文書がスプレッドシートテーブルを含み、次いで、このテーブルが正当な注釈を含むことがある。ユーザがこの正当な注釈を編集しようとする場合、ワードプロセスプログラムはスプレッドシートプログラムを呼び出し、そして正当性のエディターを呼び出すように指示する。正当性のエディターは、その非テキストデータを探索することができねばならない。
【０００９】
更に、ユーザが非テキストデータをワードプロセス文書内に概念的に配置することにより非テキストデータを編集できると予想し、そしてユーザがワードプロセス文書に対する変更をセーブすると判断したときにその変更しか永久的にセーブしない場合には、更に複雑なことになる。非テキストデータを処理するために呼び出されたプログラムは、行われたいかなる変更もワードプロセスプログラムと整合しなければならない。
【００１０】
１つの解決策は、指定された一時的なファイルに全ての変更をセーブすることをプログラムに告げるフラグをサポートするように各プログラムを変更することである。従って、ワードプロセスプログラムは、完全な１組の変更をワードプロセス文書にセーブするよう選択したときに、非テキストデータを含むファイルを一時的なファイルでオーバーライトする役目を果たす。
【００１１】
もう１つの解決策は、ワードプロセスプログラムが、非テキストデータを変更するプログラムを呼び出す前に、非テキストデータファイルのスナップショットをセーブすることである。従って、ワードプロセスプログラムは、ユーザがワードプロセス文書に対する変更をセーブしないと判断した場合は、非テキストデータを処理するために呼び出されたプログラムによってなされた変更をオーバーライトすることができる。
【００１２】
本発明の目的は、アプリケーションプログラムを複合文書にインターフェイスする方法及びシステムを提供することである。
【００１３】
本発明の別の目的は、複合文書のレイアウトを効率的な仕方で編成する方法及びシステムを提供することである。
【００１４】
本発明の更に別の目的は、任意の記憶媒体に対して複合文書システムを実施する方法及びシステムを提供することである。
【００１５】
【課題を解決するための手段】
本発明の上記及び他の目的は、以下の詳細な説明から明らかとなるように、アプリケーションプログラムを複合文書記憶システムとインターフェイスする方法及びシステムによって達成される。本発明は、複合文書を操作するためにアプリケーションプログラムが使用するインターフェイスを定義する。好ましい実施例では、このインターフェイスは、多層アーキテクチャにおいて実施される。第１の層は、第２の層の機能（関数）を用いて複合文書をアクセスするためにアプリケーションプログラムが使用する方法を与える。第２の層は、複合文書のデータを記憶するための要求を、第３の層の機能を使用して記憶フォーマットにマップする。第３の層は、ファイルに書き込む要求を任意の記憶媒体に対してマップする。
【００１６】
【実施例】
本発明の好ましい実施例においては、オブジェクトは複合文書内にオブジェクトハイアラーキ構成で記憶される。オブジェクトとは、カプセル化されるか、リンクされるか、又は埋め込まれたデータであって、一般には、複合文書を形成するのに使用されるものではなくてアプリケーションによって形成されたものである。（１９９１年のアディソン−ウェスレイ・パブリッシング社出版のバド．Ｔ著の「オブジェクト指向のプログラミングの紹介(An Introduction to Object-Oriented Programming)」と題する参考文献は、オブジェクト指向の概念及び用語について紹介している。）オブジェクトのハイアラーキは、オブジェクトが任意のネストレベルでサブオブジェクトを含むことができるようにする。オブジェクトのハイアラーキは、典型的なファイルシステムのハイアラーキと同様である。
本発明は、オブジェクトハイアラーキ内でオブジェクトを操作するための２つのアブストラクト（抽象的）クラスを与える。第１のアブストラクトクラスは、ＩＳｔｏｒａｇｅインターフェイスと称する。このＩＳｔｏｒａｇｅインターフェイスは、ファイルシステムのディレクトリーがファイル及びサブディレクトリーをグループ分けするのと概念的に同じやり方でオブジェクトをグループ分けするための方法を与える。ＩＳｔｏｒａｇｅインスタンス(instance)は、ストレージ（記憶）に対するインターフェイスである。第２のアブストラクトクラスは、ＩＳｔｒｅａｍインターフェイスと称する。このＩＳｔｒｅａｍインターフェイスは、ファイルシステムのファイルがデータを読み取りそして書き込むのと概念的に同じやり方でデータを読み取りそして書き込むための方法を与える。ストレージは、ストレージインスタンスとストリームを含むことができる。ＩＳｔｒｅａｍインスタンスは、ストリームに対するインターフェイスである。
【００１７】
本発明は、オブジェクトハイアラーキを単一ファイルシステムのファイルにマップするものである。従って、多数のオブジェクトを単一のファイルに記憶することができる。更に、本発明は、ファイルに対して多数のストリーム（マルチストリーム）のインターフェイスを与えるものである。ストリームとは、ファイルに対する入力／出力ハンドルであって、独特のシークポインタへマッピングするものと考えることができる。単一ファイル内の各オブジェクトは、概念的にそれ自身に対する全ストレージを有し、これは多数のストリーム及びストレージを含むことができる。多ストリームのインターフェイスは、各オブジェクトのこれらストリームを単一ファイルシステムのストリームに入念にマップする。更に、本発明は、各オブジェクトが多数のストリームをもつことができるようにする。オブジェクトは、概念的に、ストレージインスタンスに記憶され、そしてそのデータは、ストレージ内の１つ以上のストリーム又はストレージインスタンスに記憶される。
【００１８】
図１は、複合文書のサンプルに対するオブジェクトハイアラーキ構成を示している。ＩＳｔｏｒａｇｅインスタンスは楕円形ブロックで示されており、そしてＩＳｔｒｅａｍインスタンスは方形ブロックで示されている。この複合文書サンプルは、グラフが埋め込まれたワードプロセス文書である。この複合文書はルートＩＳｔｏｒａｇｅインスタンス１０１を含み、これは、ＩＳｔｒｅａｍインスタンス１０２及びＩＳｔｏｒａｇｅインスタンス１０３を含んでいる。ＩＳｔｒｅａｍインスタンス１０２は、ワードプロセスプログラムのネーティブフォーマットのデータを含んでいる。ＩＳｔｏｒａｇｅインスタンス１０３は、埋め込まれたグラフに対応し、ＩＳｔｒｅａｍインスタンス１０４及び１０５を含んでいる。ＩＳｔｒｅａｍインスタンス１０４はグラフのＸＹデータを含み、そしてＩＳｔｒｅａｍインスタンス１０５はグラフのタイトルを含んでいる。ＩＳｔｒｅａｍインスタンス１０４及び１０５は、グラフプログラムのネーティブフォーマットでデータを記憶する。
【００１９】
図２は、マルチストリームインターフェイスと、ファイルシステムと、アプリケーションプログラムとの関係を示すブロック図である。ワードプロセスプログラム２０１及びグラフプログラム２０２は、マルチストリームインターフェイス２０３と対話する。マルチストリームインターフェイス２０３はファイルシステム２０４と対話して、複合文書２０５におけるオブジェクトハイアラーキの記憶に作用する。グラフオブジェクトを操作するために、ワードプロセスプログラム２０１は、標準的なプロセス間通信手段を介してグラフプログラム２０２にメッセージを送り、複合文書内のグラフオブジェクトと、そのオブジェクトにおいて行う動作を識別する。典型的な動作は、グラフオブジェクトを表示又は編集することである。次いで、グラフプログラム２０２は、マルチストリームインターフェイス２０３を経てグラフオブジェクトをアクセスする。
【００２０】
図３は、本発明による複合文書の形成を示すフローチャートである。この例において、ユーザは、ワードプロセスプログラム（クライエント）を用いてテキストデータを入力し、次いで、グラフオブジェクトを文書に挿入することを要求する。この要求に応答して、グラフオブジェクトプログラム（サーバ）がそのグラフオブジェクトをどこに記憶するかを指示するメッセージを送る。次いで、ユーザは、グラフサーバを用いてグラフデータを入力し、そしてグラフサーバはそのグラフオブジェクトを指示されたように記憶し、復帰する。ステップ３０１ないし３０４において、ワードプロセスプログラムは複合文書ファイル（ドキュメントファイル）を形成し、ユーザによって入力されたテキストデータを記憶する。
ステップ３０１において、ワードプロセスプログラムはユーザからテキストデータを受け取る。ステップ３０２において、ワードプロセスプログラムは、マルチストリームインターフェイスによって与えられる関数ＳｔｇＣｒｅａｔｅＤｏｃｆｉｌｅを呼び出すことにより文書ファイルを形成する。この関数は、文書ファイルを形成すると共に、文書ファイルのルートＩＳｔｏｒａｇｅインスタンスであるＩＳｔｏｒａｇｅインスタンスのポインタを返送する。ステップ３０３において、ワードプロセスプログラムは、テキストデータを記憶するためのストリームをルートＩＳｔｏｒａｇｅインスタンス内に形成する。ワードプロセスプログラムは、ルートＩＳｔｏｒａｇｅインスタンスのメソッドＣｒｅａｔｅＳｔｒｅａｍを呼び出し、これは形成されたストリームのＩＳｔｒｅａｍインスタンスに対するポインタを返送する。ステップ３０４では、ワードプロセスプログラムは、ＩＳｔｒｅａｍインスタンスのメソッドＷｒｉｔｅを用いて新たに形成されたストリームにテキストデータを書き込む。次いで、ワードプロセスプログラムは、ユーザからの次の事象の受信を待機する。ステップ３０５及び３０６は、グラフオブジェクトを挿入すべきであるとユーザが指示するときに実行される。ステップ３０５において、ワードプロセスプログラムは、ルートＩＳｔｏｒａｇｅインスタンスのメソッドＣｒｅａｔｅＳｔｏｒａｇｅを呼び出すことにより、グラフオブジェクトを記憶すべきＩＳｔｏｒａｇｅインスタンスをルートＩＳｔｏｒａｇｅインスタンス内に形成する。ステップ３０６では、ワードプロセスプログラムは、グラフオブジェクトを保持すべき新たに形成されたＩＳｔｏｒａｇｅインスタンスを指定するグラフサーバを呼び出す。ステップ３０７ないし３１１において、グラフサーバはグラフオブジェクトを形成し、それを指定されたＩＳｔｏｒａｇｅインスタンスのストレージに記憶する。ステップ３０７において、グラフサーバはユーザからのグラフデータを入力する。ステップ３０８において、グラフサーバは、指定されたＩＳｔｏｒａｇｅインスタンスに対するメソッドＣｒｅａｔｅＳｔｒｅａｍを呼び出すことによりグラフデータのストリームを形成する。ステップ３０９において、グラフサーバは、指定されたＩＳｔｏｒａｇｅインスタンスに対するメソッドＣｒｅａｔｅＳｔｒｅａｍを呼び出すことによりタイトルデータのストリームを形成する。ステップ３１０において、グラフサーバは、グラフデータに対するＩＳｔｒｅａｍインスタンスのメソッドＷｒｉｔｅを呼び出すことにより新たに形成されたストリームにグラフデータを書き込む。ステップ３１１において、グラフサーバは、タイトルデータに対するＩＳｔｒｅａｍインスタンスのメソッドＷｒｉｔｅを呼び出すことにより新たに形成されたストリームにタイトルデータを書き込む。次いで、グラフサーバはワードプロセスプログラムに復帰する。ワードプロセスプログラムは、ユーザが次の事象を入力するのを待機する。
【００２１】
マルチストリームインターフェイス
上記したように、マルチストリームインターフェイスは、ＩＳｔｏｒａｇｅ及びＩＳｔｒｅａｍインターフェイスを定める。ＩＳｔｏｒａｇｅインターフェイス及びＩＳｔｒｅａｍインターフェイスは、本発明のハイアラーキストレージを具現化する１組の純粋な仮想メソッドを定める。純粋な仮想メソッドとは、デクラレーションは有するがコードの具現化をもたないファンクションである。これらインターフェイスは、インターフェイスの特定の具現化とは独立してアプリケーションプログラムを開発できるようにする。好ましい具現化について以下に述べるが、ＩＳｔｏｒａｇｅ及びＩＳｔｒｅａｍインターフェイスを用いたアプリケーションプログラムは、何らかの具現化に添付したときに何ら変更を行わずに実行することができる（具現化のメソッドにリンクすることは除いて）。
【００２２】
ＩＳｔｏｒａｇｅ及びＩＳｔｒｅａｍインターフェイスについて以下に説明する。又、文書ファイルの作成及び開放をサポートする２つの機能についても説明する。
【００２３】
アクセスモード
本発明では、ストレージ及びストリームを種々のアクセスモードで開放することができる。アクセスモードは、エレメント（ストレージ又はストリーム）がトランザクションモードで開放されるか、読み取り又は書き込みモードで開放されるか、拒絶読み取り又は拒絶書き込みモードで開放されるかを制御する。
【００２４】
エレメントがトランザクションモードで開放されるときには、それに対する変更が、トランザクションのコミット又は復帰が指定されるまでバッファされる。
これとは逆に、エレメントが直接モードで開放されるときには、バッファ作用は生じない。概念的には、直接モードは、各変更の直後にコミットが続くトランザクションモードと機能的に同等である。トランザクションモードでは、変更のコミットが親ストレージのトランザクションモードを受ける。各エレメントは、その親ストレージのトランザクション内にネスト構成にされる。従って、ルート記憶のコミットはファイルシステムのファイルを実際に変更する。エレメントにおけるトランザクションをコミットする動作は、変更をその親ストレージインスタンスへ渡す。親ストレージインスタンスは、トランザクションモードで開放されている場合に、そのエレメントのコミットされた変化を累積する。従って、変化は、ルートストレージに向かってアップ方向に浸透する。トランザクションモードにあるときには、エレメントに対する全ての変化がバッファされる。特に、ストレージ内のエレメントの形成又は破壊が取り扱われる。
【００２５】
本発明においては、オブジェクトハイアラーキの種々のレベルでトランザクションモード又は直接モードにおいて開放することができる。以下に詳細に述べるように、ストレージが直接モードで開放され、そしてトランザクションモードで開放されたエレメントを含んでいるときには、次いで、エレメントがそのトランザクションをコミットするときに、これらの変化が親ＩＳｔｏｒａｇｅインスタンスを経て上記の親インスタンスに渡される。
【００２６】
ストレージ又はストリームは、読み取り及び／又は書き込みモードで開放されてもよい。ストリームが読み取りモードで開放されない場合には、ストリームを読み取ろうとする試みはエラーを返送する。ストレージが読み取りモードで開放されるときには、列挙（以下に述べる）方法がイネーブルされる。ストレージが読み取りモードで開放されない場合には、そのエレメントを読み取りモードで開放することができない。
【００２７】
エレメントが書き込みモードで開放された場合には、その変更をコミットすることができる。特に、エレメントが書き込みモードで開放されない限り、コミットを試みると、エラーが返送される。上記したように、エレメントが直接モードで開放されたときには、各変更の後にコミットが行われる。従って、直接モードでは、変更に作用するように書き込みモードを指定しなければならない。
【００２８】
ストレージ又はストリームが拒絶読み取りモードで開放される場合には、ストリームもストレージもその後は読み取りモードで開放することができない。拒絶読み取りモードは、同じ親ＩＳｔｏｒａｇｅインスタンスを経てエレメントを別に開放する場合にのみ有効である。
【００２９】
ストレージ又はストリームが拒絶書き込みモードで開放された場合には、書き込みモードにおいてストリーム又はストレージを開放するその後の要求は禁止される。拒絶書き込みモードは、同じ親ＩＳｔｏｒａｇｅインスタンスを経てエレメントを別に開放する場合にのみ有効である。
【００３０】
ＳｔｇＣｒｅａｔｅＤｏｃｆｉｌｅ
SCODE  StgCreateDocfile(lpszName,grfMode,dwIfThere,reserved,ppstg)
ＳｔｇＣｒｅａｔｅＤｏｃｆｉｌｅ関数は、指定された名称を使用して複合文書としてファイルシステムにファイルを形成し、そのファイル内にルートストレージを形成し、そして指定されたアクセスモードでそのルートストレージを開放する。パラメータｄｗＩｆＴｈｅｒｅは、指定された名称のファイルが存在するときにその関数のふるまいを指定する。このようなファイルが存在する場合に、この関数は、任意にエラーを返送し、それを削除しそして新たなファイルを形成するか、或いはそのファイルを、「ＣＯＮＴＥＮＴ」という名称のストリームを含むルートストレージを含んだファイルと置き換える。ストリームは、古いファイルにあったデータを含む。指定された名称がＮＵＬＬの場合には、独特の名称をもつ一時的な文書ファイルが形成される。この関数は、ルートストレージに対するＩＳｔｏｒａｇｅインスタンスを例示し、そしてそれに対するポインタを返送する。
【００３１】
ＳｔｇＯｐｅｎＳｔｏｒａｇｅ
SCODE  StgOpenStorage(lpszName,pstgPriority,grfMode,subExclude,reserved,ppstgOpen)
ＳｔｇＯｐｅｎＳｔｏｒａｇｅ関数は、指定された名称の既存の複合文書を指定されたアクセスモードで開放する。ファイルが存在しないか又はストレージではない場合には、エラーが返送される。この関数は、開放されたＩＳｔｏｒａｇｅインスタンスに対するポインタを返送する。
【００３２】
ＩＳｔｏｒａｇｅインターフェイス
テーブル１は、ＩＳｔｏｒａｇｅインターフェイスを定めるものである。ＩＳｔｏｒａｇｅインターフェイスのメソッドのパラメータはテーブル２で定められる。
各メソッドのふるまいは、これらテーブルの後に指定する。ＩＳｔｏｒａｇｅインターフェイスは、ＩＳｔｒｅａｍインスタンス及びＩＳｔｏｒａｇｅインスタンスを含むことができ、これらは、親ＩＳｔｏｒａｇｅインスタンスのエレメントと称される。
テーブル１
Class IStorage
｛
仮想  SCODE  Release０=0;
仮想  SCODE  CreateStream(lpsName,grfMode,dwIfThere,reserved,ppstm)=0;  仮想
SCODE  OpenStream(lpsName,grfMode,reserved,ppstm)=0;
仮想  SCODE  CreateStorage(lpszName,grfMode,dwIfThere,reserved,ppstg)=0;
仮想  SCODE  OpenStrage(lpszName,pstgPriority,grfMode,subExclude,reserved,ppst
g)=0;
仮想  SCODE  CopyTo(pstgDest)=0;
仮想  SCODE  Commit(grfCommitFlags)=0;
仮想  SCODE  Revert ０=0;
仮想  SCODE  EnumElements(reserved1,reserved2,reserved3,ppenun)=0;
仮想  SCODE  DestroyElement(lpszName)=0;
仮想  SCODE  RenameElement(lpszOldName,lpszNewName)=0;
仮想  SCODE  Stat(pstatatg)=0.
｝
テーブル２
項目                説明                                            
lpszName            ストリーム又はストレージの名称(IStorage インスタン
ス内の全てのエレメントは同じ名称空間内にある）
grfMode             IStream 又はIStorageインスタンスのアクセスモード
dwIfThere           IStream 又はIStorageインスタンスを形成するときに
は、dwIfThere は、同じ名称のエレメントが既に存在
するときのふるまいを指示する
reserved            ゼロでなければならない
ppstm               IStream インスタンスに対するポインタ
ppstg               IStorageインスタンスに対するポインタ
【００３３】
ＩＳｔｏｒａｇｅ：：Ｒｅｌｅａｓｅ
Ｒｅｌｅａｓｅメソッドは、指定されたＩＳｔｏｒａｇｅインスタンスを閉じ、インスタンスを無効とする。（以下の説明において、「指定された」という語は、メソッドが呼び出されるインスタンスを指し、そして「指示される」という語はパラメータを指すものとする。）好ましい実施例において、ＩＳｔｏｒａｇｅインターフェイスは、レファレンスカウンタを増加するメソッドを含む。Ｒｅｌｅａｓｅメソッドはレファレンスカウンタを減少し、カウントが０に達したときに指定されたインスタンスのみを無効にする。
【００３４】
ＩＳｔｏｒａｇｅ：：ＣｒｅａｔｅＳＴｒｅａｍ
ＣｒｅａｔｅＳＴｒｅａｍメソッドは、指定されたＩＳｔｏｒａｇｅインスタンスのストレージ内に指示された名称の新たなストリームを形成し、そして指定されたアクセスモードでストリームを開放する。パラメータｄｗＩｆＴｈｅｒｅは、指定された名称のエレメントが既に存在するときにこのメソッドのふるまいを指示する。このようなエレメントが存在するときには、このメソッドは任意にエラーを返送するか、又は既存のエレメントを削除して新たなストリームを形成する。このメソッドは、形成されたストリームに対してＩＳｔｒｅａｍインスタンスを例示し、それに対するポインタを返送する。
【００３５】
ＩＳｔｏｒａｇｅ：：ＯｐｅｎＳｔｒｅａｍ
ＯｐｅｎＳｔｒｅａｍメソッドは、指定されたＩＳｔｏｒａｇｅインスタンスのストレージ内で指示された名称の既存のストリームを指示されたアクセスモードで開放する。指示された名称のストリームがストレージ内に存在しないか又は指示されたアクセスモードで開放できない場合には、エラーが返送される。アクセスモードについては以下で詳細に述べる。このメソッドは開放ストリームに対してＩＳｔｒｅａｍインスタンスを例示し、それに対するポインタを返送する。
【００３６】
ＩＳｔｏｒａｇｅ：：ＣｒｅａｔｅＳｔｏｒａｇｅ
ＣｒｅａｔｅＳｔｏｒａｇｅメソッドは、指定されたＩＳｔｏｒａｇｅインスタンス内に指示された名称の新たなストレージを形成し、この新たなストレージを指示されたアクセスモードで開放する。パラメータｄｗＩｆＴｈｅｒｅは、指示された名称のエレメントが既に存在するときにこのメソッドのふるまいを指示する。同じ名称のエレメントが存在する場合には、このメソッドは任意にエラーを返送するか又は既存のエレメントを削除して新たなストレージを形成する。同じ名称のストリームが存在する場合には、そのストリームが、「ＣＯＮＴＥＮＴＳ」という名称の１つのストリームを含む新たなストレージと置き換えられる。このストリームは古いストリーム内にあったデータを含む。このメソッドは、形成されたストレージに対しＩＳｔｏｒａｇｅインスタンス（及びもし必要ならばＩＳｔｒｅａｍ）を例示する。
【００３７】
ＩＳｔｏｒａｇｅ：：ＯｐｅｎＳｔｏｒａｇｅ
ＯｐｅｎＳｔｏｒａｇｅメソッドは、指定されたＩＳｔｏｒａｇｅインスタンス内の指示された名称の既存のストレージを指示されたアクセスモードで開放する。
指示された名称のストレージが存在しないか又は指示されたアクセスモードで開放できない場合には、エラーが返送される。
【００３８】
ＩＳｔｏｒａｇｅ：：ＣｏｐｙＴｏ
ＣｏｐｙＴｏメソッドは、指定されたＩＳｔｏｒａｇｅインスタンスのストレージの全内容を指示されたストレージにコピーする。このメソッドは、指示されたストレージの内容を置き換える。指示されたストレージは、指定されたストレージとは異なる具現であってもよい。従って、ＣｏｐｙＴｏの具現は、指示されたストレージのメソッドしか使用してはならない。
【００３９】
ＩＳｔｏｒａｇｅ：：Ｃｏｍｍｉｔ
Ｃｏｍｍｉｔメソッドは、指定されたストレージに対するトランザクションをコミットする。Ｃｏｍｍｉｔメソッドのふるまいは、指定されたストレージが開放されたアクセスモードによって左右される。指定されたストレージが直接モードで開放された場合には、このメソッドは、１つの例外を除いて何の作用も及ぼさない。指定されたＩＳｔｏｒａｇｅインスタンスがルートストレージである場合、このメソッドは、通常の「フラッシュ」オペレーションのように動作し、これは、内部のメモリバッファがその基礎となる記憶装置へ書き出されるよう確保する。
【００４０】
指定されたストレージがトランザクションモードで開放された場合には、このメソッドは、指定されたストレージが開放されて以来、或いはその指定されたストレージの親に反映されるように最後にコミットされて以来（どちらか遅い方）その指定されたストレージになされたいかなる変化も生じさせる。これらの変化の永久的な更新は、親ストレージのトランザクションモードを受ける。即ち、親ストレージのトランザクションが行われると、その場合に、変化が実際に記憶装置に書き込まれる前に親ストレージにおいてコミットを行う必要がある。このメソッドは指定されたストレージの現在開放されているエレメントのコミットされないトランザクションには何の作用も及ぼさない。特に、このメソッドは、指定されたストレージのエレメント内の変化は自動的にコミットしない。コミットの作用は、本質的に、指定されたストレージに生じる変化を親ストレージに「パブリッシュ」する。
【００４１】
パラメータｇｒｆＣｏｍｍｉｔＦｌａｇｓによって指示されたようにルートストレージをコミットするモードは２つある。第１モードにおいては、コミットされた変化が記憶装置に頑強（ロバスト）なモードで書き込まれる。第２モードにおいては、記憶装置内のデータに、コミットされた変化をオーバーライトすることができる。頑強なモードにおいては、全ての変化がその基礎となる記憶装置の未使用空間に書き込まれる。記憶装置は必要に応じて拡張される。これが完了すると、古いデータに代わって新しいデータを使用すべきであることを指示するために単一の書き込みが記憶装置に行われる。古いデータは、次のコミット中に使用することのできる自由空間となる。
【００４２】
第３のコミットモードは、記憶装置の現在の永続的な内容が、変化のベースとなったときと同じ内容である場合にのみコミットを行うべきであることを指示する。内容が同じでない場合には、エラーコードが返送される。
【００４３】
ＩＳｔｏｒａｇｅ：：Ｒｅｖｅｒｔ
Ｒｅｖｅｒｔメソッドは、指定されたストレージが開放されるか又は最後にコミットされて以来（いずれか遅い方）そのエレメントによってストレージにコミットされた全ての変化を破棄する。このメソッドの完了後に、指定されたストレージに対して開放されたいかなるエレメントも無効とされる（Ｒｅｌｅａｓｅ以外のこれらエレメントの全てのメソッドによってエラーが返送される）。
【００４４】
ＩＳｔｏｒａｇｅ：：ＥｎｕｍＥｌｅｍｅｎｔｓ
ＥｎｕｍＥｌｅｍｅｎｔｓメソッドは、指定されたＩＳｔｏｒａｇｅインスタンスのストレージ内に直ちに含まれたエレメントを列挙する。指定されたストレージは、読み取りモードで開放されねばならない。
【００４５】
ＩＳｔｏｒａｇｅ：：ＤｅｓｔｒｏｙＥｌｅｍｅｎｔ
ＤｅｓｔｒｏｙＥｌｅｍｅｎｔメソッドは、指示された名称のエレメントを指定されたストレージインスタンスから除去する。この破壊されたエレメントを開放すること（指定されたストレージを介して）は無効になる。エレメントが存在しない場合には、エラーが返送される。
【００４６】
ＩＳｔｏｒａｇｅ：：ＲｅｎａｍｅＥｌｅｍｅｎｔ
ＲｅｎａｍｅＥｌｅｍｅｎｔメソッドは、指定されたストレージ内の指示されたエレメントを古い名称から新しい名称に変更する。この新しい名称が既に存在する場合、又は古い名称が存在しない場合には、エラーが返送される。
【００４７】
ＩＳｔｏｒａｇｅ：：Ｓｔａｔ
Ｓｔａｔメソッドは、ストレージ指定されたＩＳｔｏｒａｇｅインスタンスに関する統計学的な情報を返送する。
【００４８】
ＩＳｔｒｅａｍインターフェイス
テーブル３は、ＩＳｔｒｅａｍインターフェイスを定める。ＩＳｔｒｅａｍインターフェイスのメソッドのパラメータはテーブル４に示す。ＩＳｔｒｅａｍインターフェイスは、各読み取り及び書き込みのためのストリーム内の位置として使用されるシークポインタを定める。各メソッドのふるまいは以下に指定する。
テーブル３
Class IStream
｛
仮想  SCODE  Release０=0;
仮想  SCODE  Read(pv,cb,pcbRead)=0;
仮想  SCODE  Write(pv,cb,pcbWritten)=0;
仮想  SCODE  Seek(dlibMove,dwOrigin,plibNewPosition)=0;
仮想  SCODE  SetSize(libNewSize)=0;
仮想  SCODE  Clone(ppstm)=0;
仮想  SCODE  CopyTo(ppstm,cb,pcbRead,pcbWritten)=0;
仮想  SCODE  Commit(grfCommitFlags)=0;
仮想  SCODE  Revert ０=0;
仮想  SCODE  LockRegion(cb,dwLockType)=0;
仮想  SCODE  UnlockRegion(cb,dwLockType)=0;
仮想  SCODE  Stat(pstatstg)=0;
｝
テーブル４
項目                説明                                            
pv                  読み取り又は書き込みするためのバッファのポインタ
cb                  バイト数
ppstm               IStream インスタンスのポインタ
pcbWritten          ストリームに実際に書き込まれるバイト数で、呼び出
し側に関与しない場合にはNULLである
pcbRead             ストリームから実際に読み取られるバイト数で、呼び
出し側に関与しない場合にはNULLである
dlibMove            dwOriginによって指示された位置に追加される変位
dwOrigin            シークモード
plibNewPosition     更新されたシークポインタ
libNewSize          新たなストリームのサイズ
dwLockType          ロックの形式
【００４９】
ＩＳｔｒｅａｍ：：Ｒｅｌｅａｓｅ
Ｒｅｌｅａｓｅメソッドは、指定されたＩＳｔｒｅａｍインスタンスのストリームを閉じる。好ましい実施例では、ＩＳｔｒｅａｍインスタンスは、レファレンスカウンタを増加するメソッドを含む。Ｒｅｌｅａｓｅメソッドは、レファレンスカウンタを減少し、カウントがゼロになったときに指定されたＩＳｔｒｅａｍインスタンスを無効にする。
【００５０】
ＩＳｔｒｅａｍ：：Ｒｅａｄ
Ｒｅａｄメソッドは、現在シークポインタでスタートして、指定されたＩＳｔｒｅａｍインスタンスのストリームから指示されたバッファへ指示された数のバイトを読み込む。このメソッドは、実際に読まれたバイトの数を返送する。このメソッドは、実際に読まれたバイトの数でシークポインタを調整する。ストリームが読み取りモードで開放されていない場合には、エラーが返送される。実際に読まれたバイトの数は、読み取り中にストリームの終わりに達した場合には、要求されたものより少なくなる。
【００５１】
ＩＳｔｒｅａｍ：：Ｗｒｉｔｅ
Ｗｒｉｔｅメソッドは、現在シークポインタでスタートして、指示されたバッファから指定されたＩＳｔｒｅａｍインスタンスのストリームへ指示された数のバイトを書き込む。非ゼロのバイトカウントが指定されそしてシークポインタがストリームの終わりを現在通過したときには、シークポインタに到達するようにストリームのサイズが増加される。加えられたバイトは初期化されない。ストリームが適当なモードで開放していない場合には、エラーが返送される。実際に書き込まれたバイトの数が返送される。シークポインタは、実際に書き込まれたバイトの数で調整される。
【００５２】
ＩＳｔｒｅａｍ：：Ｓｅｅｋ
Ｓｅｅｋメソッドは、指定されたＩＳｔｒｅａｍインスタンスのストリームに対しシークポインタの位置を調整する。ストリームの開始より前ではシークエラーとなる。ストリームの終わりを越えてもシークエラーとならない。パラメータｄｌｉｂＭｏｖｅは、パラメータｄｗＯｒｉｇｉｎによって指示されるように、ストリームの開始、現在シークポインタ、又はストリームの終わりのいずれかからの変位を指示する。新たなシークポインタは、パラメータｐｌｉｂＮｅｗＰｏｓｉｔｉｏｎにおいて返送され、これは発呼者が新たなシークポインタに関心をもたない場合にゼロとなる。
【００５３】
ＩＳｔｒｅａｍ：：ＳｅｔＳｉｚｅ
ＳｅｔＳｉｚｅメソッドは、指定されたＩＳｔｒｅａｍインスタンスのストリームのサイズを、パラメータｌｉｂＮｅｗＳｉｚｅで指示されたものに変更する。シークポインタは、この動作によって影響されない。ストリームは、サイズが増加されるか又はサイズが減少されるかのいずれかである。ストリームのサイズが増加される場合には、新たなバイトの内容が定められない。
【００５４】
ＩＳｔｒｅａｍ：：Ｃｌｏｎｅ
Ｃｌｏｎｅメソッドは、指定されたＩＳｔｒｅａｍインスタンスと同じ基礎的ストリームを指す新たなＩＳｔｒｅａｍインスタンスを形成する。１つのＩＳｔｒｅａｍインスタンスを介してのストリームの変更は、他のストリームインスタンスを介して直ちに見ることができる。ロック状態（以下に述べる）は、２つのＩＳｔｒｅａｍインスタンス間で分担される。しかしながら、クローンされたＩＳｔｒｅａｍインスタンスは、指定されたＩＳｔｒｅａｍインスタンスのシークポインタとは独立したそれ自身のシークポインタを有する。クローンされたＩＳｔｒｅａｍインスタンスにおけるシークポインタの初期設定は、このＣｌｏｎｅメソッドが呼び出されたときには、指定されたＩＳｔｒｅａｍインスタンスにおけるシークポインタの現在設定と同じである。
【００５５】
ＩＳｔｒｅａｍ：：ＣｏｐｙＴｏ
ＣｏｐｙＴｏメソッドは、指定されたＩＳｔｒｅａｍインスタンスのストリームから（その現在シークポインタでスタートして）、指示されたＩＳｔｒｅａｍインスタンスのストリームへ（その現在シークポインタでスタートして）指定された数のバイトをコピーする。実際に読み取られるか又は書き込まれたバイトの数が返送される。各ＩＳｔｒｅａｍインスタンスのシークポインタは、実際に読み取られるか又は書き込まれたバイトの数で調整される。ＩＳｔｒｅａｍインスタンスが適当なアクセスモードで開放していない場合には、エラーが返送される。このメソッドは、語義的には、読み取りに続く書き込みと等価である。
【００５６】
ＩＳｔｒｅａｍ：：Ｃｏｍｍｉｔ
Ｃｏｍｍｉｔメソッドのふるまいは、ＩＳｔｒｅａｍインスタンスが開放されるモードに基づいている。直接モードにおいては、このメソッドは何のふるまいももたない。トランザクションモードにおいては、このメソッドは、ＩＳｔｒｅａｍインスタンスが開放されるか又は親ストレージに反映されるように最後にコミットされて以来（いずれか遅い方）ＩＳｔｒｅａｍインスタンスになされた変化を生じさせる。指示されたコミットモードは、ＩＳｔｏｒａｇｅ：：Ｃｏｍｍｉｔメソッドで述べたのと同様に機能する。
【００５７】
ＩＳｔｒｅａｍ：：Ｒｅｖｅｒｔ
Ｒｅｖｅｒｔメソッドのふるまいは、指定されたＩＳｔｒｅａｍインスタンスのストリームが開放されるモードによって左右される。直接モードにおいては、このメソッドは何の動作も行わない。トランザクションモードにおいては、ＩＳｔｒｅａｍインスタンスが開放されるか或いは最後にコミットされて以来（どちらか遅い方）ＩＳｔｒｅａｍインスタンスになされた全ての変化が破棄される。
【００５８】
ＩＳｔｒｅａｍ：：ＬｏｃｋＲｅｇｉｏｎ
ＬｏｃｋＲｅｇｉｏｎメソッドは、指定されたＩＳｔｒｅａｍインスタンスのストリームの領域をロックするように試みる。領域は現在シークポインタで始まり、ストリームの終わりに向かって指示されたバイト数だけ延びる。ストリームの現在終端を越えて延びる領域を指示することは義務である。ストリームに対する領域ロックをサポートすることは任意である。このメソッドは、２つの形式のロック、即ち、他の書き込み者を排除するためのロック（書き込みロック）と、他の書き込み者及び読み取り者を排除するためのロック（排他的ロック）とをサポートする。書き込みロックが許可された場合には、ストリームの指示された領域を読み取りメソッドによりその基礎となるストリームのＩＳｔｒｅａｍインスタンスからアクセスすることができる。しかしながら、指定されたＩＳｔｒｅａｍインスタンス及びそのクローンを除いて、書き込みメソッドがいずれかのＩＳｔｒｅａｍインスタンスを介して呼び出された場合には、エラーが返送される。排他的ロックが許可された場合には、他のＩＳｔｒｅａｍインスタンスを介して呼び出された読み取り及び書き込みメソッドがエラーを返送する。要求されたモードが具現化によってサポートされない場合には、エラーメッセージが返送される。要求されたロックはサポートされるが、他のロックであるために現在許可できない場合には、エラーが返送される。このメソッドでロックされた領域は、全く同じシークポインタと、同じバイトカウントと、同じロック形式とを有するＵｎＬｏｃｋＲｅｇｉｏｎメソッドを用いて後で特にロック解除しなければならない。従って、２つの隣接領域を別々にロックして１つのアンロックコールでロック解除することはできない。ＩＳｔｒｅａｍインスタンスを通るストリームに対する全てのロックは、ＩＳｔｒｅａｍインスタンスをリリースする前に明確にロック解除されねばならない。
【００５９】
ＩＳｔｒｅａｍ：：ＵｎＬｏｃｋＲｅｇｉｏｎ
ＵｎＬｏｃｋＲｅｇｉｏｎメソッドは、指定されたＩＳｔｒｅａｍインスタンスのストリームの以前にロックされた領域をロック解除する。
【００６０】
ＩＳｔｒｅａｍ：：Ｓｔａｔ
Ｓｔａｔメソッドは、指定されたＩＳｔｒｅａｍインスタンスのストリームの関する情報を返送する。
【００６１】
具現化
図４は、本発明の好ましい具現化の全体を示すブロック図である。この好ましい具現化では、ＩＳｔｏｒａｇｅ／ＩＳｔｒｅａｍ具現部４０１と、Ｄｏｃｆｉｌｅ具現部４０２と、ＩＬｏｃｋＢｙｔｅｓ具現部４０３とを含む階層式解決策を用いている。この好ましい具現化は、オブジェクト指向言語のＣ＋＋言語で行われる。従って、この具現化は、オブジェクト指向の用語で説明する。ＩＳｔｏｒａｇｅ／ＩＳｔｒｅａｍ具現部４０１は、文書ファイルを形成しそして開放する関数と、ＩＳｔｏｒａｇｅ及びＩＳｔｒｅａｍのメソッドとを与える。ＩＳｔｏｒａｇｅ／ＩＳｔｒｅａｍ具現部４０１は、トランザクションを実施し、Ｄｏｃｆｉｌｅ具現部４０２のサービスを呼び出す。Ｄｏｃｆｉｌｅ具現部４０２は、文書ファイル内のストレージ及びストリームの永続的記憶に対するインターフェイスを与える。Ｄｏｃｆｉｌｅ具現部４０２は、文書ファイル内のストレージ及びストリームをマップする。Ｄｏｃｆｉｌｅ具現部４０２は、ＩＬｏｃｋＢｙｔｅｓインターフェイスを用いてストレージ及びストリームをその基礎となる永続的ストレージにマップする。ＩＬｏｃｋＢｙｔｅｓインターフェイスは、永続的ストレージを操作するメソッドを定めるアブストラクトクラスとして定義される。好ましい具現化において、ＩＬｏｃｋＢｙｔｅｓ具現部４０３は、その基礎となるファイルシステムを用いてデータを記憶する。或いは又、ＩＬｏｃｋＢｙｔｅｓインターフェイスの具現化は、他のストレージ４０５で示されたように、他の基礎的な記憶媒体を使用することもできる。
【００６２】
ＩＳｔｏｒａｇｅ／ＩＳｔｒｅａｍ具現部４０１は、階層構成体を使用して、ＩＳｔｏｒａｇｅ及びＩＳｔｒｅａｍインターフェイスをサポートするに必要なデータ及びメソッドを編成する。好ましい具現化では、ＩＳｔｏｒａｇｅ及びＩＳｔｒｅａｍインスタンスが、３つの層、即ちエクスポーズした層と、パブリック層と、ラップした層とに編成される。図５は、ＩＳｔｏｒａｇｅ及びＩＳｔｒｅａｍ層を示すブロック図である。各層は、Ｃ＋＋クラスのインスタンスとして具現化される。ＩＳｔｏｒａｇｅインスタンス５１０のエクスポーズした層５１１はＩＳｔｏｒａｇｅインターフェイスのメソッドを与える。エクスポーズした層５１１のメソッドはパラメータを有効化し、パブリック層５１２のメソッドを呼び出す。パブリック層５１２は、ストレージエレメントのリストを維持し、アクセスモードを強制し、そしてトランザクションモードのときにはラップした層のメソッドを呼び出すと共に直接モードのときには直接層のメソッドを呼び出す。ラップした層５１３は、トランザクションサポートを具現化する。ＩＳｔｒｅａｍインスタンス５２０のエクスポーズした層５２１はＩＳｔｒｅａｍインターフェイスのメソッドを与える。
このエクスポーズした層５２１のメソッドは、パラメータを有効化し、ストリームのシークポインタを維持し、そしてパブリック層５２２のメソッドを呼び出す。パブリック層５２２はアクセスモードを強制し、そしてトランザクションモードのときにはラップした層５２３のメソッドを呼び出すと共に直接モードのときには直接層のメソッドを呼び出す。ラップした層５２３は、トランザクションサポートを具現化する。好ましい実施例では、ＩＳｔｒｅａｍインターフェイスは、トランザクションサポートなしに実施される。即ち、ＩＳｔｒｅａｍ：：Ｗｒｉｔｅメソッドは、トランザクションハイアラーキの次のレベルに直接書き込む。ＩＳｔｒｅａｍ：：Ｃｏｍｍｉｔ及びＩＳｔｒｅａｍ：：Ｒｅｖｅｒｔメソッドは、これがサポートされる間に、何の動作も行わない。ＩＳｔｏｒａｇｅ及びＩＳｔｒｅａｍ具現部の層については、以下で詳細に述べる。
【００６３】
エクスポーズした層
エクスポーズした層は最も外側の層であり、ＩＳｔｒａｇｅ及びＩＳｔｒｅａｍインターフェイスのメソッドを具現化するものである。このエクスポーズした層はＩＳｔｒａｇｅ及びＩＳｔｒｅａｍメソッドのパラメータを有効化する。好ましい実施例においては、ストリームのためのシークポインタのトランザクションは行われない。シークポインタに気付く唯一の層がこのエクスポーズした層である。ＩＳｔｒｅａｍ具現部のこのエクスポーズした層は、シークポインタを維持する。
エクスポーズした層のメソッドが、読み取り及び書き込みを行うパブリック層のメソッドを呼び出すときには、これらメソッドに、読み取り又は書き込みするためのオフセットが通される。従って、全ての内部層は、シークポインタを維持しなければならないことから遮断される。
【００６４】
パブリック層
エクスポーズした層はパブリック層を指す。パブリック層は、インスタンスに対してほとんどのアクセスモードを強制する。パブリック層は、その全てのエレメント及びそのアクセスモードのリストを維持する。このリストを使用して、エレメントへの特定のアクセスを許すか拒絶するかを判断する。インスタンスがトランザクションモードにあるときには、パブリック層は、これが指すラップした層のメソッドを呼び出す。さもなくば、パブリック層は直接層を呼び出す。
【００６５】
ラップした層
ラップした層及び直接層は両方とも同じインターフェイスをサポートし、多様に使用することができる。これは、パブリック層がアブストラクトインターフェイスのメソッドを呼び出せるようにし、そしてそれがラップした層の呼び出しであるか直接層の呼び出しであるかは気にしないようにする。ラップした層は、コミット又は復帰のときまで変化のバッファ作用をサポートする。ラップした層は直接層と通信して、そのダーティ情報（トランザクションに対してバッファされたデータ）を管理すると共に、そのベース情報（永続的ストレージにあるデータ）を管理する。又、ラップした層は、あるアクセスモードを強制する。例えば、ＩＳｔｏｒａｇｅインターフェイスは、親のアクセスモードに係わりなく、インスタンスに対して書き込みアクセスモードを要求できることを指定する。これは、親が読み取りのみのアクセスにある間にそのインスタンスを書き込みモードに入れられることを意味する。しかし、親が読み取りのみのアクセスであるから、書き込みアクセスをするインスタンスのコミットはフェイルとなる。直接層は、ＤｏｃＦｉｌｅ具現部のメソッドを直接呼び出して、永続的なストレージを変更する。
【００６６】
トランザクション
好ましい具現化において、各ＩＳｔｒａｇｅ及びＩＳｔｒｅａｍインスタンスは、直接モード又はトランザクションモードで動作することができる。ＩＳｔｒａｇｅ及びＩＳｔｒｅａｍインスタンスは、トランザクションモードで開放されたときには、ラップした層と共に例示される。ラップした層は、そのエレメントに対してなされた変化を追跡し、そして要求があった際にコミットするか又は復帰する。
【００６７】
各ＩＳｔｒａｇｅ及びＩＳｔｒｅａｍインスタンスはトランザクションモードで開放できるので、これらインスタンスのハイアラーキの各レベルは異なったモードで開放することができる。図６は、典型的なオブジェクトハイアラーキを示している。ルートＩＳｔｏｒａｇｅインスタンス６０１及びグラフオブジェクトのＩＳｔｏｒａｇｅインスタンス６０２がトランザクションモードで開放された場合には、ルートＩＳｔｏｒａｇｅインスタンス６０１及びグラフインスタンス６０２の各々は、ＸＹデータ６０３のストリーム及びタイトルデータ６０４のストリームに対してなされた変化をバッファする。例えば、タイトルデータ６０４に対して変化がなされた場合には、グラフオブジェクトインスタンス６０２がこれらの変化をスクラッチファイルにバッファする。グラフオブジェクトのストレージインスタンスがその変化をコミットするときには、ルートＩＳｔｏｒａｇｅインスタンスがこれらのコミットされた変化をスクラッチファイルにバッファする。最後に、ルートＩＳｔｏｒａｇｅインスタンスがその変化をコミットするときには、永続的なストレージのみが変更される。これとは逆に、グラフオブジェクトのＩＳｔｏｒａｇｅインスタンスが直接モードで開放する場合には、グラフオブジェクトのＩＳｔｏｒａｇｅインスタンスはそのエレメントの変化をバッファしない。むしろ、その変化はルートＩＳｔｏｒａｇｅへ直接送られ、これがその変化をバッファする。
【００６８】
本発明は、各ＩＳｔｏｒａｇｅ及びＩＳｔｒｅａｍインスタンスに対して１組の変化（トランザクションレベルと称する）を維持することによりトランザクションを具現化する。これらのトランザクションレベルは、インスタンスから伝わってくる各エレメントに対してコミットされた変化と、インスタンス自身のコミットされない変化とをバッファする。トランザクションレベルは、トランザクションセットメンバーのインスタンスのリンクされたリストを構成する。トランザクションセットメンバーは、ＩＳｔｏｒａｇｅ又はＩＳｔｒｅａｍインスタンス自身の１つのエレメントに対する変化をバッファする。各トランザクションレベルは、インスタンスに対する変化をバッファするためにＩＳｔｏｒａｇｅ又はＩＳｔｒｅａｍインスタンス自身に対するトランザクションセットメンバーを含んでいる。エレメントが例示されるときには、更に別のトランザクションセットメンバーが形成される。
【００６９】
トランザクションセットメンバーは、直接式であってもよいしラップ式のものであってもよい。直接式のトランザクションセットメンバーは、それに対してなされた変化をバッファしない。むしろ、直接式のトランザクションセットメンバーは、永続的なストレージを直接操作できるようにする。ラップ式のトランザクションセットメンバーは、変化をバッファし、変化のベースとなったデータを指す。各エレメントごとに、ベースデータは、その親が考えているエレメントの現在状態である。ラップ式の各トランザクションメンバーは、２つのポインタを含み、その一方のポインタは、変化情報がバッファされるスクラッチを操作する直接メンバーを指し（ダーティポインタと称する）、そして他方のポインタは、ベースデータを識別する直接式又はラップ式メンバーを指す（ベースポインタと称する）。トランザクションセットメンバーのベースポインタは、ストリーム又はストレージの一連のトランザクションされたバージョンを形成する。ストリーム又はストレージが開放されたときには、その親のＩＳｔｏｒａｇｅインスタンスがそのベースポインタを得るように要求される。親がエレメントに対してトランザクションセットメンバーを有していない場合には、そのエレメントに対するトランザクションセットメンバーを例示する。次いで、親のＩＳｔｏｒａｇｅインスタンスは、その親がエレメントに対するベースポインタを得るように要求し、もし必要であれば、トランザクションセットメンバーを例示する。従って、永続的ファイルに対してアクセス権を得たルートＩＳｔｏｒａｇｅインスタンスまで要求が浸透する。
【００７０】
図７は、好ましい実施例においてトランザクションレベルを示すブロック図である。図６は、オブジェクトハイアラーキを例示する図である。この例では、ルートオブジェクトとグラフオブジェクトがトランザクションモードで開放している。ルートオブジェクトがトランザクションモードで開放しているときは、ＩＳｔｏｒａｇｅインスタンス７１０及びＸＳＭインスタンス７１１が例示される。
ＸＳＭインスタンス７１１は、ルートストレージに対してなされた変化をバッファする。ＸＳＭインスタンス７１１は、ダーティポインタ及びベースポインタを含んでいる。ダーティポインタは、バッファされた変化が記憶されたスクラッチファイルのストリームを指す。ベースポインタは永続的なストレージを指す。グラフオブジェクトストレージがトランザクションモードで開放されたときには、ＩＳｔｏｒａｇｅインスタンス７２０及びＸＳＭインスタンス７２１が例示される。ＸＳＭインスタンス７２１を初期化するときには、このインスタンスがその親ストレージからベースポインタを要求する。この例では、ＩＳｔｏｒａｇｅインスタンス７１０がＸＳＭインスタンス７１２を形成し、そしてスクラッチストリームを指すようにダーティポインタを初期化すると共に、永続的ストレージを指すようにベースポインタを初期化する。ＩＳｔｏｒａｇｅインスタンス７１０はＸＳＭインスタンス７１２に対するポインタをインスタンス７２１に返送し、これはそのポインタをベースポインタとして記憶する。ＸＹデータストリームが直接モードで開放されると、ＸＹデータＩＳｔｒｅａｍインスタンス７３０が例示される。ＩＳｔｒｅａｍインスタンスの初期化メソッドは、そのベースのポインタに対して親のＩＳｔｏｒａｇｅを要求する。グラフオブジェクトのＩＳｔｏｒａｇｅインスタンス７３０は、ＸＹデータストリームに対するトランザクションセットメンバーを形成する。ＸＳＭインスタンス７２２は、次いで、ベースポインタに対し、その親のストレージであるルートＩＳｔｏｒａｇｅインスタンス７１０を要求する。ルートＩＳｔｏｒａｇｅインスタンス７１０は、ＸＹデータストリームに対してＸＳＭインスタンス７１３を例示する。ルートＩＳｔｏｒａｇｅインスタンス７１０は、永続的ストレージを指すようにＸＳＭインスタンス７１３のベースポインタを初期化し、そしてそれ自身のポインタをＸＳＭインスタンス７２２へ返送し、これはそのポインタをそのベースとして記憶する。次いで、ＸＳＭインスタンス７２２は、それ自身のポインタをＸＹデータＩＳｔｒｅａｍインスタンス７３０へ返送する。ＸＹデータＩＳｔｒｅａｍインスタンス７３０はそのポインタをそのベースとして記憶する。
【００７１】
図９は、好ましい実施例におけるトランザクションレベルを示すブロック図である。図８は、オブジェクトハイアラーキを例示する図である。図７及び９は、ストレージが各々トランザクションモード及び直接モードで開放されたときのトランザクションレベルを示している。グラフオブジェクトストレージが直接モードで開放されたときには、ＩＳｔｏｒａｇｅインスタンス９２０がそのベースのポインタに対してルートＩＳｔｏｒａｇｅインスタンス９１０を要求する。それに応答して、ルートＩＳｔｏｒａｇｅインスタンス９１０はＸＳＭインスタンス９１２を例示し、そのベースを永続的ストレージを指すようにセットする。ルートＩＳｔｏｒａｇｅインスタンス９１０は、グラフオブジェクトのＩＳｔｏｒａｇｅインスタンス９２０のポインタを返送し、このインスタンスはそのポインタをそのベースとして記憶する。同様に、ＸＹデータ及びタイトルデータストリームが例示されたときには、ルートＩＳｔｏｒａｇｅ９１０のＸＳＭインスタンスへポインタを返送する。グラフオブジェクトストレージはトランザクションが行われないので、対応するトランザクションレベルはなく、グラフオブジェクトに対してなされた全ての変化は、ルートストレージのトランザクションセットメンバーへ送られる。
【００７２】
図１０は、ＩＳｔｏｒａｇｅインスタンスの種々の層を示したブロック図である。各ブロックは、メンバーＣ＋＋クラスをメンバーメソッドと共に表している。上記したＩＳｔｏｒａｇｅインスタンスは、エクスポーズした層と、パブリック層と、ラップした層とを備えている。これらの層は、クラスインスタンスＣＥｘｐｏｓｅｄＳｔｏｒａｇｅ１０１０と、ＣＰｕｂＳｔｏｒａｇｅ１０２０と、ＣＷｒａｐｐｅｄＳｔｏｒａｇｅ１０３０とで示されている。エクスポーズしたストレージ層は、パブリックストレージ層のに対するポインタと、インスタンスがトランザクションモードでない場合に使用するベース及びダーティポインタとを含んでいる。パブリック層は、ラップした層に対するポインタと、親のパブリック層に対するポインタと、子供のアクセスモード及びＩＳｔｏｒａｇｅインスタンスに対応するアクセスモードを含むリンクリストに対するポインタとを含んでいる。ラップ層は、トランザクションレベルインスタンスに対するポインタと、更新リストに対するポインタと、ダーティ及びベースポインタとを含んでいる。トランザクションレベルインスタンスは、トランザクションセットメンバーのリンクされたリストに対するポインタと、どのトランザクションセットメンバーがこのＩＳｔｏｒａｇｅインスタンスに対応するかを指示するポインタと、トランザクションしたデータをどこに記憶するかを指示する情報とを含んでいる。更新リストは、ＩＳｔｏｒａｇｅインスタンスのエレメントの名称についてのトランザクションを含む。トランザクションセットメンバーは、それに対応するトランザクションされたストリームデータ構造体を指し、これはストリームに対する変化を記憶する。
【００７３】
図１１は、ＩＳｔｒｅａｍインスタンスをサポートするＣ＋＋クラスのブロック図である。好ましい具現化では、ＩＳｔｒｅａｍインスタンスはトランザクションされない。従って、ＩＳｔｒｅａｍインスタンスは、エクスポーズした層１１０１と、パブリック層１１０３のみを有する。エクスポーズした層１１０１はシークポインタ１１０２を指す。ＩＳｔｒｅａｍインスタンスが閉じた場合は、新たなエクスポーズした層１１０５が新たなシークポインタ１１０６と共に形成される。この新たなエクスポーズした層１１０５は、クローンインスタンスのパブリック層１１０３を指すと共に、新たなシークポインタ１１０６を指す。
【００７４】
ＤｏｃＦｉｌｅ具現部
ＤｏｃＦｉｌｅ具現部は、ＩＬｏｃｋＢｙｔｅｓインターフェイスを用いて、ＩＳｔｏｒａｇｅ及びＩＳｔｒｅａｍインターフェイスのオブジェクトハイアラーキを永続的ストレージにマップする。ＩＬｏｃｋＢｙｔｅｓインターフェイスは、以下に説明するように、永続的ストレージをバイトのアレイとして見ることができるようにする。ＤｏｃＦｉｌｅ具現部は、このアレイをヘッダ及び複数の固定長さセクタに論理的に分割する。図１２は、１つの文書ファイルにおけるセクタのレイアウトを示す図である。この具現化のフォーマットをマルチストリームファイルフォーマット（ＭＳＦＦ）と称する。好ましい実施例では、ヘッダが５１２バイトである。セクタのサイズはヘッダに記憶され、典型的に、５１２バイトの倍数である。セクタは、その各々が含む情報の形式に基づいて形式分けされる。これらの形式は、ＦＡＴ、ディレクトリー、ＭｉｎｉＦＡＴ、ＤＩＦ及びデータである。ＭＳＦＦは、ファイル割り当てテーブル（ＦＡＴ）及びダブル間接ファイル割り当てテーブル（ＤＩＦ）を用いて同じ形式のセクタをリンクし、論理的に隣接するストリームを形成する。
【００７５】
図１３は、ＭＳＦＦの割り当て構造を示す図である。この例は、セクタサイズが５１２バイトでありそしてセクタのポインタが４バイトであると仮定する。この例においては、ヘッダ１３０１は、ＤＩＦセクタ１３０２ないし１３０４のリンクリストを指す。ＤＩＦセクタは、リンク１３０２Ａ、１３０３Ａ及び１３０４Ａを用いてリンクされたリストを形成する。各ＤＩＦセクタは、ＦＡＴセクタのポインタのテーブル１３０２Ｂ、１３０３Ｂ及び１３０４Ｂを含んでいる。テーブル内のポインタの数はセクタのサイズによって左右される。図１３に示すように、各ＤＩＦセクタは、ＦＡＴセクタのポインタを１２７個含んでいる。
【００７６】
ＦＡＴセクタは、ＦＡＴエントリーの論理的に隣接するアレイを含んでいる。
永続的ストレージアレイの各セクタごとに１つのＦＡＴエントリーがある。各ＦＡＴセクタは１２８個のＦＡＴエントリーを含む。これらＦＡＴエントリーは、ＭＳＦＦストリームを形成するセクタを一緒にリンクするポインタを含む。ＭＳＦＦストリームは、論理的に隣接する１組の同じ形式のセクタである。ストリーム内の各セクタごとに、そのセクタに対応するＦＡＴエントリーは、そのストリーム内の論理的に次に隣接するセクタに対するポインタを含んでいる。例えば、データストリーム１３０７ないし１３１０は４つのデータセクタを含んでいる。
セクタ１３０７はセクタ３に記憶され、セクタ１３０８はセクタ１２９に記憶され、セクタ１３０９はセクタ１４０に記憶され、そしてセクタ１３１０はセクタ２に記憶される。ＦＡＴエントリーは、このストリームを次のように一緒にリンクする。即ち、セクタ３はストリームの第１セクタを含んでいるので、ＦＡＴエントリー３（ＦＡＴ〔３〕）は１２９を含み、これはデータストリームに第２セクタを含むセクタである。ＦＡＴエントリー１２９（ＦＡＴ〔１２９〕）は１４９を含み、これはデータストリームに第３セクタを含むセクタである。ＦＡＴエントリー１４０（ＦＡＴ〔１４０〕）は２を含み、これはデータストリームに最終セクタを含むセクタである。セクタ２はデータストリームに最終セクタを含むので、ＦＡＴエントリー２（ＦＡＴ〔２〕）は、データストリーム終了インジケータを含む。あるストリームに対するスタートセクタが与えられると、ＦＡＴのリンクされたリストを進むことによってそのストリームの他のセクタを位置決めすることができる。
【００７７】
ＤＩＦセクタのエントリーは、各ＦＡＴセクタが実際にどこに記憶されるかを指示する。第１のＤＩＦセクタは、第１の１２７のＦＡＴセクタのセクタ位置を含んでおり、第２のＤＩＦセクタは、第２の１２７のＦＡＴセクタのセクタ位置を含んでおり、等々となる。従って、ヘッダに記憶される第１のＤＩＦセクタの位置が与えられると、全てのＦＡＴセクタを位置決めすることができる。
【００７８】
ＭＳＦＦヘッダは、ディレクトリーストリームに対するポインタを含む。ディレクトリーストリームは、ＭＳＦＦに対するディレクトリー構造体を含む。図１４は、サンプルのディレクトリーストリームのレイアウトを示すブロック図である。図１５は、図１４によってサンプルのオブジェクトハイアラーキである。ディレクトリーはＩＳｔｏｒａｇｅインスタンスに対応し、そしてデータストリームはＩＳｔｒｅａｍインスタンスに対応する。図１５に示すように、ディレクトリーは、ルートディレクトリーと、サブディレクトリーＢ、Ｃ及びＤと、サブディレクトリーＢ内のデータストリームＢ１及びＢ２とを含んでいる。ＭＳＦＦは各ディレクトリーセクター内に４つのディレクトリーエントリーを記憶するのが好ましい。テンプレート１４０１は、各ディレクトリーエントリーの構造を示している。各エントリーは名称及び状態情報を含む。エントリーは、データストリームに対応する場合には、そのデータストリームのスタートセクタを含む。又、各ディレクトリーエントリーは、その親、その最も左の子供、その前の兄弟及びその次の兄弟のディレクトリーエントリーインデックスを含む。ヘッダ１４０２は第１のディレクトリーセクタ１４０３のセクタ番号を含む。ディレクトリーセクタはＦＡＴによってリンクされる。この例では、ハイアラーキのディレクトリーエントリーは、ディレクトリーセクタ１４０３、１４０４及び１４０５に記憶される。ディレクトリーエントリー１４０６ないし１４１１は各々ハイアラーキ内のストレージストリームに対応している。ディレクトリーエントリー０（ＤＩＲ〔０〕）はルートストレージに対応し、その最も左の子供がそのディレクトリーエントリー２（ＤＩＲ〔２〕）に記憶されることを示している。ディレクトリーエントリー２（ＤＩＲ〔２〕）１４０７は、サブディレクトリーＢのエントリーを含む。ディレクトリーエントリー２は、その親がルートノード（ＤＩＲ〔０〕）であり、ディレクトリーエントリー４（ＤＩＲ〔４〕）に記憶された子供を有しており、手前の兄弟はもたず、そしてその次の兄弟がディレクトリーエントリー５（ＤＩＲ〔５〕）に記憶されることを示している。ディレクトリーエントリー４（ＤＩＲ〔４〕）１４０８は、データストリームＢ１に対応し、データストリームＢ１のスタートセクタ番号（図示せず）を含んでいる。ディレクトリーエントリー４は、その親がディレクトリーエントリー２（ＤＩＲ〔２〕）に記憶され、子供をもたず、手前の兄弟をもたず、そしてその次の兄弟がディレクトリーエントリー６（ＤＩＲ〔６〕）に記憶されることを示している。ディレクトリーエントリー６（ＤＩＲ〔６〕）１４１０はデータストリームＢ２に対応し、このデータストリームＢ２に対するスターとセクタ番号を含んでいる。ディレクトリーエントリー６は、その親がディレクトリーエントリー２に記憶され、子供をもたず、その手前の兄弟がディレクトリーエントリー４に記憶され、そして次の兄弟をもたないことを示している。ディレクトリーエントリー５（ＤＩＲ〔５〕）１４０９は、サブディレクトリーＣのエントリーを含む。ディレクトリーエントリー５は、その親がディレクトリーエントリー０に記憶され、子供をもたず、その手前の兄弟がディレクトリーエントリー２に記憶され、そしてその次の兄弟がディレクトリーエントリー９に記憶されることを示している。ディレクトリーエントリー９（ＤＩＲ〔９〕）１４１１は、サブディレクトリーＤに対するエントリーを含む。このディレクトリーエントリー９は、その親がディレクトリーエントリー０に記憶され、子供をもたず、その手前の兄弟がディレクトリーエントリー５に記憶され、そして次の兄弟をもたないことを示している。
【００７９】
ＭＳＦＦは、永続的ストレージを健全な仕方で容易に更新するように設計されている。この健全な仕方は、永続的なストレージが一貫しない状態で残らないよう確保する助けとなる。永続的なストレージが健全な仕方で更新されるときは、既存のデータがオーバーライトされるのではなく、情報の更新されたセクタが自由ブロックに書き込まれる。更新したセクタを自由ブロックに書き込むプロセスを「シャドーイング」と称する。変更を必要とする全てのセクタがシャドーされると、新たなデータをディレクトリーハイアラーキにリンクするようにヘッダがオーバーライトされる。健全な仕方での永続的ストレージの更新は、システムの欠陥によってファイルが一貫しない状態で残る危険性を最小にする。
【００８０】
図１６は、データストリームを健全な仕方で更新する手順を示すフローチャートである。ステップ１６０１において、このルーチンは、新たなデータをファイル内の自由セクタに書き込む。自由セクタがない場合には、ファイルが拡張される。ステップ１６０２において、このルーチンは、古いデータと新しいデータを含むセクタに対応したＦＡＴエントリーを含んでいるＦＡＴセクタを読み取り、どのセクタがデータストリームの新たな部分かを指示するようにＦＡＴエントリーを変更し、ＦＡＴセクタを自由ブロックに書き込む。ステップ１６０３において、このルーチンは、シャドーされたＦＡＴセクタに対応する各ＤＩＦセクタを読み取り、ＦＡＴセクタの新たなセクタを指すようにＤＩＦセクタを更新し、そしてＤＩＦセクタを自由ブロックに書き込む。又、このルーチンは、丁度シャドーされたものよりも論理的に前にある各ＤＩＦセクタをシャドーする。ＤＩＦセクタのこのシャドーは、ＦＩＤセクタのリンクされたリストにおけるポインタを更新するのに使用される。ステップ１６０４において、このルーチンは、データストリームに対する更新によってディレクトリーへの情報が変更されるかどうか（ディレクトリーのエントリーが最後の変更の時間を含む場合には常に変更される）を決定する。変更が必要な場合には、ルーチンはステップ１６０５へ続き、さもなくばステップ１６０８へ続く。ステップ１６０５ないし１６０７においては、このルーチンは、更新されたデータストリームに対応するディレクトリーエントリーを含むディレクトリーセクタをシャドーし、古い及び新しいディレクトリーセクタに対応するＦＡＴセクタをシャドーし、そして適当なＤＩＦセクタをシャドーする。最後に、ステップ１６０８において、このルーチンは、ＤＩＦのポインタを変更することによりその新たにシャドーされたセクタを指すようにヘッダデータを更新する。
【００８１】
図１７は、本発明のシャドーメソッドを示す図である。構造体１７０１は、更新される前のストレージアレイを示している。このファイルに示されたデータは、図１３のデータ流例に対応している。この例では、セクタ１４０のデータが更新される。ＤＩＦセクタ０（ＤＩＦ〔０〕）はセクタ１３９に記憶される。ＤＩＦエントリー１（ＤＩＦ〔１〕）は、ＦＡＴセクタ１がセクタ１４１に記憶されることを指示する。このＦＡＴセクタ１は、セクタ１４０がデータ流のの次のセクタを含むことを指示するＦＡＴエントリー１２９（ＦＡＴ〔１２９〕）を含むと共に、セクタ２がデータストリームの次のセクタを含むことを指示するＦＡＴエントリー１４０（ＦＡＴ〔１４０〕）を含む。ファイル１７０２は、セクタ１４０のデータが更新されるときのシャドーを示している。シャドーセクタは破線で示されている。新たなデータはセクタ１５２に書き込まれる。セクタ１４１からのＦＡＴセクタ１が検索されそしてＦＡＴエントリー１２９がセクタ１５２を指すように変更され、ＦＡＴエントリー１５２はセクタが２であることを指すように変更され、そしてＦＡＴエントリー１４０は、セクタ１４０がもはやデータストリーム内になく、自由であることを指示するように変更される。次いで、変更されたＦＡＴセクタ１はセクタ１５３に書き込まれる。ＤＩＦセクタ〔０〕が検索され、これは、ＦＡＴセクタ〔１〕が今度はセクタ１５３に記憶されてセクタ１５４に書き込まれることを指示するように変更される。この点において、永続的なストレージは一貫した状態にある。というのは、古いデータがそのまま残されそして新しいデータがファイルの終わりに丁度追加されたところ（又は自由セクタ内に記憶されたところ）だからである。最後に、ブロック１７０３に示されたように新たなヘッダセクタは、ＤＩＦセクタ０が今度はセクタ１５４にあることを指示する。
【００８２】
好ましい実施例では、セクタのサイズが５１２バイトである。しかしながら、多くの状態においては、５１２バイトよりも著しく短いデータ流を記憶することが必要である。セクタは１つのデータ流に対するデータしか含むことができないので、永続的ストレージのほとんどの部分は「未使用」の空間を含む。永続的ストレージ内の未使用空間の量を減少するために、本発明では、ＭｉｎｉＳｔｒｅａｍセクタと称する特殊なセクタに「小さな」データ流が記憶され、ＭｉｎｉＦＡＴセクタに記憶されたデータによって割り当てが追跡されるようにストリームが構成される。ＭｉｎｉＳｔｒｅａｍにおいては、各セクタが６４バイトのミニセクタに論理的に分割される。ＦＡＴに類似したＭｉｎｉＦＡＴは、ＭｉｎｉＳｔｒｅａｍに対するリンク情報を含んでいる。好ましい実施例では、ヘッダがＭｉｎｉＦＡＴの第１セクタを指し、ルートディレクトリーエントリー（Ｄｉｒ〔０〕）がＭｉｎｉＳｔｒｅａｍの第１セクタを指す。ＦＡＴは、ＭｉｎｉＦＡＴ及びＭｉｎｉＳｔｒｅａｍのセクタをリンクするのに用いられる。好ましい実施例では、データ流が２５６バイトより小さいときは、それがＭｉｎｉＳｔｒｅａｍに記憶される。データがＭｉｎｉＳｔｒｅａｍに書き込まれるときには、そのデータ流に対するディレクトリーストリームのディレクトリーエントリーがそのデータ流の第１ミニセクタを指す。その後、データ流のミニセクタはＭｉｎｉＦＡＴを通してリンクされる。図１８は、ＭｉｎｉＳｔｒｅａｍ及びＭｉｎｉＦＡＴのレイアウトを示すブロック図である。
【００８３】
好ましい実施例においては、非常に小さなデータ流はディレクトリーエントリー自体に記憶することができる。非常に小さなデータ流がそのディレクトリーエントリーに対して大き過ぎるように成長した場合には、次いで、データ流がＭｉｎｉＳｔｒｅａｍに記憶される。ＭｉｎｉＳｔｒｅａｍに記憶されたデータ流が指定サイズ以上に大きくなった場合には、次いで、データ流に記憶される。性能を最適化するために、ヘッダ情報は、最初の僅かなＦＡＴセクタの位置を含み、小さな永続性ストレージをアクセスするときの性能を改善することができる。
【００８４】
ＩＬｏｃｋＢｙｔｅｓ具現部
ＩＬｏｃｋＢｙｔｅｓ具現部４０３は、ＩＬｏｃｋＢｙｔｅｓインターフェイスを具現化するものである。以下に述べるように、ＩＬｏｃｋＢｙｔｅｓインターフェイスは、基礎となる記憶媒体のモデルを形成する。好ましい実施例では、ＩＬｏｃｋＢｙｔｅｓ具現部４０３は、基礎となるファイルシステムにおいて動作する。しかしながら、他の媒体で動作するように他の具現部を開発することもできる。ＩＳｔｒａｇｅ／ＩＳｔｒｅａｍ具現部４０３の上記説明では、ＩＬｏｃｋＢｙｔｅｓインターフェイスの多数のインスタンスが使用される。１つのインスタンスはスクラッチファイルを指し、そして別のインスタンスは実際に文書ファイルを指すのに用いられる。又、更に別のパラメータをＳｔｇＣｒｅａｔｅＤｏｃＦｉｌｅ及びＳｔｇＯｐｅｎＤｏｃＦｉｌｅファンクションに追加して、アプリケーションプログラムがＩＬｏｃｋＢｙｔｅｓインスタンスを特定できるようにすることができる。
【００８５】
テーブル５は、ＩＬｏｃｋＢｙｔｅｓインターフェイスを定める。ＩＬｏｃｋＢｙｔｅｓインターフェイスのメソッドのパラメータがテーブル６に示されている。
各メソッドのふるまいは、以下に特定する。
テーブル５
Class  ILockBytes
｛
仮想  SCODE  ReadAt(libOffset,pv,cb,pcbRead)=0;
仮想  SCODE  Write(libOffset,pv,cb,pcbWrite)=0;
仮想  SCODE  Flush０=0;
仮想  SCODE  SetSize(cb)=0;
仮想  SCODE  LockRegion(libOffset,cb,dwLockType)=0;
仮想  SCODE  UnLockRegion(libOffset,cb,dwLockType)=0;
仮想  SCODE  Stat(pstatstg)=0.
｝
テーブル６
項目              説明                                              
libOffset         読み取り又は書き込みを始めるところのストレージアレ
イに対するオフセット
pv                バッファに対するポインタ
cb                ストレージアレイから読み取りを試みるバイト数
pcbRead           実際に読み取られるバイト数
【００８６】
ＩＬｏｃｋＢｙｔｅｓ：：ＲｅａｄＡｔ
ＲｅａｄＡｔメソッドは、指示されたオフセットでスタートして指定されたＩＬｏｃｋＢｙｔｅｓインスタンスのストレージアレイから指示されたバッファへ指示された数のバイトを読み込む。実際に読み取られたバイトの数が返送される。読み取り中にストレージアレイの終わりに達した場合には、実際に読み取られたバイトの数が、要求されたものより少ない。読み取りがストレージアレイの読み取りロック領域にオーバーラップする場合には、エラーが返送される。
【００８７】
ＩＬｏｃｋＢｙｔｅｓ：：ＷｒｉｔｅＡｔ
ＷｒｉｔｅＡｔメソッドは、指示されたバッファから指示されたオフセットでスタートしてＩＬｏｃｋＢｙｔｅｓインスタンスのストレージアレイへ指定された数のバイトを書き込む。オフセットがストレージアレイの現在終了点を越える場合には、ストレージアレイのサイズが初期化されないバイトで増加される。実際に書き込まれたバイトの数はｐｃｂＷｒｉｔｔｅｎにおいて返送される。書き込みがロックされた領域にオーバーラップする場合には、エラーが返送される。
【００８８】
ＩＬｏｃｋＢｙｔｅｓ：：Ｆｌｕｓｈ
Ｆｌｕｓｈメソッドは、指定されたＩＬｏｃｋＢｙｔｅｓインスタンスの具現化によって維持された内部バッファをストレージアレイに書き込む。
【００８９】
ＩＬｏｃｋＢｙｔｅｓ：：ＳｅｔＳｉｚｅ
ＳｅｔＳｉｚｅメソッドは、指定されたＩＬｏｃｋＢｙｔｅｓインスタンスのストレージアレイのサイズを指示されたバイト数に変更する。ストレージアレイのサイズが増加されるか又はサイズが減少される。ストレージアレイのサイズが増加される場合には、新たなバイトの内容が定まらない。
【００９０】
ＩＬｏｃｋＢｙｔｅｓ：：ＬｏｃｋＲｅｇｉｏｎ
ＬｏｃｋＲｅｇｉｏｎメソッドは、指定されたＩＬｏｃｋＢｙｔｅｓインスタンスのストレージアレイの領域をロックするように試みる。領域は指示されたオフセットで始まり、ストレージアレイの終わりに向かって指示されたバイト数だけ延びる。ストレージアレイの現在終了端を越えて延びるバイトの範囲を指示するのは正当である。このメソッドのロック作用のふるまいは、ＩＳｔｒｅａｍ：：ＬｏｃｋＲｅｇｉｏｎメソッドと同様である。
【００９１】
ＩＬｏｃｋＢｙｔｅｓ：：ＵｎＬｏｃｋＲｅｇｉｏｎ
ＵｎＬｏｃｋＲｅｇｉｏｎメソッドは、指定されたＩＬｏｃｋＢｙｔｅｓインスタンスのストレージアレイの既にロックされた領域をロック解除する。
【００９２】
ＩＬｏｃｋＢｙｔｅｓ：：Ｓｔａｔ
Ｓｔａｔメソッドは、指定されたＩＬｏｃｋＢｙｔｅｓインスタンスのストレージアレイに関連した情報を返送する。
【００９３】
以上、好ましい実施例について本発明を詳細に説明したが、本発明はこれらの実施例に限定されるものではない。本発明の範囲内で種々の変更が当業者に明らかであろう。従って、本発明は、特許請求の範囲のみによって限定されるものとする。
【図面の簡単な説明】
【図１】  複合文書サンプルに対するオブジェクトハイアラーキを示す図である。
【図２】  マルチストリームインターフェイスと、ファイルシステムと、アプリケーションプログラムとの関係を示すブロック図である。
【図３】  本発明による複合文書の形成を示すフローチャートである。
【図４】  本発明の好ましい具現化の全体を示すブロック図である。
【図５】  ＩＳｔｒａｇｅ及びＩＳｔｒｅａｍ層を示すブロック図である。
【図６】  典型的なオブジェクトハイアラーキを示す図である。
【図７】  好ましい実施例のトランザクションレベルを示すブロック図である。
【図８】  オブジェクトハイアラーキを例示する図である。
【図９】  好ましい実施例のトランザクションレベルを示すブロック図である。
【図１０】  ＩＳｔｒａｇｅインスタンスの種々の層を示すブロック図である。
【図１１】  ＩＳｔｒｅａｍインスタンスをサポートするＣ＋＋クラスを示すブロック図である。
【図１２】  １つの文書ファイルにおけるセクタのレイアウトを示す図である。
【図１３】  ＭＳＦＦの割り当て構造を示す図である。
【図１４】  ディレクトリーストリームサンプルのレイアウトを示すブロック図である。
【図１５】  図１４に示されたサンプルオブジェクトハイアラーキの図である。
【図１６】  データ流を健全な仕方で更新する手順を示すフローチャートである。
【図１７】  本発明のシャドーメソッドを示す図である。
【図１８】  ＭｉｎｉＳｔｒｅａｍ及びＭｉｎｉＦＡＴのレイアウトを示すブロック図である。
【符号の説明】
１０１  ルートＩＳｔｒａｇｅインスタンス
１０２  ＩＳｔｒｅａｍインスタンス
１０３  ＩＳｔｒａｇｅインスタンス
１０４、１０５  ＩＳｔｒｅａｍインスタンス
２０１  ワードプロセスプログラム
２０２  グラフプログラム
２０３  マルチストリームインターフェイス
２０４  ファイルシステム
２０５  複合文書
【図１】
0003672582.tif 000002
【図２】
0003672582.tif 000003
【図３】
0003672582.tif 000004
【図４】
0003672582.tif 000005
【図５】
0003672582.tif 000006
【図６】
0003672582.tif 000007
【図７】
0003672582.tif 000008
【図８】
0003672582.tif 000009
【図９】
0003672582.tif 000010
【図１０】
0003672582.tif 000011
【図１１】
0003672582.tif 000012
【図１２】
0003672582.tif 000013
【図１３】
0003672582.tif 000014
【図１４】
0003672582.tif 000015
【図１５】
0003672582.tif 000016
【図１６】
0003672582.tif 000017
【図１７】
0003672582.tif 000018
【図１８】
0003672582.tif 000019