以下の説明では、説明する目的として、本技術の完全な理解を提供するために多くの特有の詳細が述べられている。しかしながら、これらの技術は、これらの特定の詳細がなくても実施され得ることは明らかであろう。他の例では、本技術を不必要に分かりにくくしないように、周知の構造及びデバイスがブロック図の形式で示される。
用語解説
以下の定義は、本技術の開示の理解を助けるために、限定ではなく例示を目的として提供されている。
クライアント:「クライアント」は、タスクをライブラリに委任するコンピューターシステムの一部として定義され得る。
コンパイラ:「コンパイラ」は、人間及びマシンの両方の消費に適切な入力を消費し、1つ以上の出力を生成する。各出力は、入力のコンパイラによる変換である。例えば、入力はソースプログラミング言語で書かれたソースコードであり得る。出力は、入力ソースコードの実行可能形式であり得る。また、出力は、ソースプログラミング言語とは異なるターゲットプログラミング言語の入力ソースコードのソースコード形式であり得る。
クロスコンパイラ:「クロスコンパイラ」は、2つ以上の出力を1つの入力から生成するコンパイラである。
割当解除:「割当解除」という用語は、再利用のために不要なオブジェクトによって占有されたメモリ空間を解放する、実行中のコンピュータープログラムのコンテキストにおけるランタイム操作を指す。
ガベージオブジェクト:「ガベージオブジェクト」は、安全に割当解除できるが、まだ割当解除されていないオブジェクトである。
グラフ:「グラフ」は、エンティティ間のペア関係をモデル化するために使用される数学的構造である。このコンテキストにおけるグラフは、通常、エッジ(リンクまたはラインとも呼ばれる)によって接続される頂点(ノードまたはポイントとも呼ばれる)で構成される。コンピュータープログラムは、ノードオブジェクトを参照するエッジオブジェクトを参照するノードオブジェクトを介する等を含む、様々な異なる方法でグラフを表すことができる。他に考えられる方法は、隣接行列、発生行列、または隣接リストを含む。
ライブラリ:「ライブラリ」は、自動化可能形式でのアルゴリズムまたは複数のアルゴリズムの表現として定義され得る。自動化可能形式の例は、プログラミング言語コードまたはそのコンパイルされたバージョン(例えば、バイトコード、バイナリ実行可能コード等)であり得る。通常、ライブラリは、プロセスまたは複数のプロセスとして実行されるとき、その一部として実行されるプロセス(複数可)を「所有」しない。代わりに、ライブラリは、特定の種類のアルゴリズムタスクをライブラリに委任する大規模システムと一緒に、またはその一部として実行される。例えば、コンピューターネットワーク上のマイクロサービスはライブラリとして見なされ得る。多くの場合、特定のアルゴリズムタスクを削除するために、他のネットワークノード用にマイクロサービスが存在する。
オブジェクト:「オブジェクト」は、コンピュータープログラム内のメッセージに応答し得るランタイムエンティティとして定義され得る。通常、エンティティはコンピューターメモリの領域を占有する。オブジェクトはメッセージに応答し、データ型定義に従って占有メモリ領域のビットを編成し得る。オブジェクトの一例は、オブジェクト指向プログラミング言語によるクラス定義のランタイムインスタンスである。
参照:「参照」とは、コンピュータープログラムがコンピューターメモリのある場所に記憶されたオブジェクトにアクセスすることを可能にするランタイム値である。参照を使用してその場所に記憶されたオブジェクトを取得することは、逆参照と呼ばれることもある。「ポインタ」は参照の一例である。
ランタイム:プログラミング言語の「ランタイム」は、その言語で書かれたコンピュータープログラムの実行をサポートする計算メカニズムを含む。例えば、プログラミング言語のランタイムは、その言語のコンピュータープログラムがコンパイルされるバイトコード命令を理解する仮想マシンを含み得る。JAVA(登録商標)仮想マシン(JVM)は、そのようなランタイムの一例にすぎない。ランタイムは、ガベージコレクションまたはサイクルコレクション等の暗黙的な割当解除サービスも提供し得る。しかしながら、全てのランタイムが暗黙的な割当解除サービスを提供するわけではない。さらに、本明細書で使用される「ランタイム」という用語は、コンピュータープログラムが実行されるときの時間を指す。
ターゲット:「ターゲット」は、コンパイラ出力に接続するためにクライアントによって使用されるメカニズムとして定義され得る。プログラミング言語をターゲットにできる。プログラマーは、同じメモリ空間にロードされるライブラリに接続するコードを書く。仮想マシン(VM)をターゲットにできる。プログラマーは、仮想マシンが実行する種類のバイトコードにコンパイルするコードを書き、インターフェースを介してリンクを使用してVMに依存できる。別のプログラムはクライアントになり得る。したがって、プログラム間のメカニズムがターゲットになる。コードは、プロセス間通信(IPC)、リモートプロシージャコール(RPC)、またはRESTfulネットワークプロトコルを使用して、クライアントプログラムのプロセスの外部で実行されているもの(例えば、ネットワークサービスまたはマイクロサービス等)にメッセージを送信し、応答を含むメッセージがいつ来るかを認識し得る。
総括
コンピュータープログラムに未解決の参照サイクルがあると、ガベージオブジェクトのランタイムに蓄積がもたらされる可能性がある。そのような蓄積により、致命的なプログラム障害が生じ得る。例として、PYTHONプログラミング言語を検討する。PYTHONランタイムの古いバージョンでは、参照カウントを使用して、割り当てられたメモリを追跡する。特に、PYTHONのランタイムオブジェクトは、それを参照しているオブジェクトの数を示す参照カウントを有する。参照カウントがゼロに達するとき、オブジェクトはメモリから解放される。参照カウントは、ほとんどのPYTHONプログラムで効果的に機能し、ガベージオブジェクトの蓄積を防止できる。しかしながら、「参照(reference)」サイクルがあるとき、参照カウントは失敗する可能性がある。参照サイクルは、オブジェクトが相互に参照するときに発生する。
以下の単純なPYTHONプログラムを考えてみる。このプログラムは、リストオブジェクトを作成し、リスト自体の要素にリストへの参照を記憶し、その後、リストオブジェクトを削除する。
00: l = []
01: l.append(l)
02: del l
行00のステートメントはリストを作成し、リストの参照カウントを1にインクリメントする。行01のステートメントは、リストへの参照をリスト自体に追加して、参照サイクルを生成し、リストの参照カウントを2にインクリメントする。行02のステートメントは、変数'l'によるリストへの参照を削除し、リストの参照カウントを2から1にデクリメントする。参照サイクルのため、行01のステートメントによって作成された内部に保持される自己参照により、リストには1の参照カウントが残る。したがって、リストは参照カウントだけによって、暗黙的に割当解除されない。そのリストは行02のステートメントの後で使用できず、割当解除する必要があるため、これは望ましくない。
コンピュータープログラムで参照サイクルを意図的に作成することは、概して、良いプログラミング方法とは考えられていないが、時々、参照サイクルの作成を避けることが困難になり、プログラマーは参照サイクルが作成されることに気づかないこともある。サーバープログラム等の長時間実行されるプログラムの場合、これは、参照カウントが使用できないオブジェクトを割当解除できなかったためにサーバープログラムがメモリ不足になった場合に問題になり、場合によって、致命的になる可能性がある。
この参照カウントの欠点に対処するために、PYTHONランタイムのいくつかのバージョンでは、ランタイムに実行中のPYTHONプログラムで参照サイクルを見つけるガベージコレクターを使用する。参照カウントは、依然として、他のオブジェクトを割当解除するために使用される。それにもかかわらず、オブジェクトの「ファイナライザー(finalizer)」には依然として問題が存在する可能性がある。「ファイナライザー」は、オブジェクトが割当解除されるときに行われる必要がある1つ以上のアクションのセットである。多くの場合、ファイナライザーを使用して、数が制限できるオペレーティングシステムのファイル記述子等、システムリソースを解放する。PYTHONのファイナライザーの例は、オブジェクトの「__del__」メソッド(例えば、特別なPYTHON「__del__」メソッドの実施を提供するクラスのインスタンス)である。
参照カウントでは、オブジェクトの参照カウントがゼロになるとき、オブジェクトが割当解除される前にファイナライザーが呼び出される。しかしながら、ガベージコレクションを使用する場合、特に参照サイクルがあるとき、プログラマーがランタイムのファイナライザーの挙動について推理することがより困難になる。例えば、参照サイクルの2つのオブジェクトの両方にファイナライザーがある場合、どちらのファイナライザーを最初に呼び出す必要があるか?ファイナライザーの1つを呼び出した後、他のファイナライザーが依然としてアクセスする必要があり得るため、オブジェクトを解放できない。この状況に直面して、PYTHONランタイムのいくつかのバージョンは、オブジェクトが参照サイクルを作成するファイナライザーを用いて、オブジェクトを割当解除しない。代わりに、オブジェクトは収集不可能なガベージオブジェクトのグローバルリストに追加される。PYTHONプログラムは、グローバルリストにアクセスし、間近で、特定のアプリケーションに有用な方法で参照サイクルを明示的に解放するようにプログラムできる。当然ながら、これはプログラマーが最初に参照サイクルを作成できることを認識していることを前提としている。その場合でも、プログラマーはグローバルリストのオブジェクトを割当解除することを注意する必要がある。
前述のPYTHONの例から明らかなように、ランタイムに暗黙的な割当解除のサポートを追加すると、複雑な問題が発生する可能性がある。PYTHONの場合のようにガベージコレクションを追加すると、PYTHONランタイムがCまたはC++ランタイム内で実行されるという事実が役に立つことがあった。しかしながら、他のランタイムを組み込み得るCまたはC++ランタイムにサポートを追加するのは簡単ではない。例えば、様々なランタイムが互いの参照を参照として認識し、どのランタイムが割当解除を行うのに担当するかについて一貫して合意する必要がある。
概して、プログラマーの観点から見ると、少なくとも2種類の参照サイクル、つまり、(1)意図された参照サイクル、及び(2)意図されない参照サイクルがある。Tree等の再帰的データ型は、意図しない参照サイクルのソースになる可能性がある。例えば、複数のリストのうちのいくつかのリストは、その使用法が注意深くプログラムされている場合、参照サイクルを回避できる。しかしながら、上記のPYTHONの例で分かるように、多くのプログラミング言語では、ランタイムに単純な参照カウントでは解くことができない参照サイクルが意図せず作成される可能性がある。
本明細書に開示される技術は、これらの問題及び他の問題に対処する。
最小ランタイムでガベージオブジェクトの蓄積を防止するために、コンピューター実装技術が提供されている。本技術は、割当解除が起こるときにプログラマーが明示的にプログラムする必要がないソースプログラミング言語で書かれたソースコードが、暗黙的な割当解除をほとんどまたはまったくサポートしないランタイム内で実行できるかどうかをチェックすることを含む。同時に、本技術により、最小のランタイムでオブジェクトがタイミング良く割当解除されることが保証される。
本技術は、参照サイクルの可能性のあるソースコードのデータ型定義を検出すると、ソースプログラミング言語のソースコードのプログラマーにコンパイル時アラート(例えば、エラーメッセージまたはワーニングメッセージ)を生成すること、またはソースコードのコンパイルを停止することを含む。本技術は、プログラマーは、ソースコードで見かけ上循環であるが、実際には非循環データ型を定義することが可能になるように十分に柔軟性がある。また、本技術は、プログラマーがソースコードで再帰的ではあるが自己参照ではないデータ型を定義することが可能になるように十分な柔軟性もある。本技術を用いると、プログラマーは、暗黙的な割当解除をまったく提供しない、または最小だけサポートする(例えば、参照カウントだけを提供する)最小ランタイムと相互運用するプログラムフラグメントを生成しながら、暗黙的な割当解除エクスペリエンスが提供される。
本技術の他の及びこれらの態様は、例として本技術の原理を示す添付の図面と併せて、以下の詳細な説明から明らかになる。
実際のサイクルのない見かけのサイクル
示されるように、プログラマーは、参照サイクルを可能にする目的で、ソースプログラミング言語でソースコードをプログラムし得る。例えば、プログラマーは、再帰的データ型を定義するためにソースコードをプログラムし得る。再帰的データ型は、その独自のデータ型定義を参照するデータ型である。
例えば、考えられるソースプログラミング言語での以下のデータ型定義を検討する。
00: closed type List<E>;
01: closed concrete type Cons<F> extends List<F> {
02: initial: F;
03: rest: List<F>;
04: }
05: closed concrete type Empty<G> extends List<G> {}
上記のデータ型の定義によれば、初期プロパティはジェネリックデータ型として定義され、残りのプロパティはCons<F>型の親型であるList<F>型として定義される。したがって、Cons<F>オブジェクトの初期プロパティ及び残りのプロパティのいずれか一方または両方は、Cons<F>オブジェクト自体を参照できる。したがって、Cons<F>データ型は再帰的データ型である。
上記のデータ型定義では、クローズキーワードは、データ型の追加のサブデータ型を事後的に指定できる拡張可能なデータ型とは対照的に、データ型のサブデータ型の全てがコンパイラに知られていることを指定する。いくつかの実施態様では、クローズデータ型がデフォルトであるため、クローズデータ型を望む場合、クローズキーワードを指定する必要はない。
別の例として、考えられるソースプログラミング言語でのバイナリツリーの以下のデータ型定義を検討する。
00: closed type Tree<B>;
01: closed concrete type BinaryTree<F> extends Tree<F> {
02: element: F;
03: left: Tree<F>;
04: right: Tree<F>;
05: }
06: closed concrete type Empty <G> extends Tree<G> {}
上記のデータ型定義は、ジェネリックデータ型BinaryTree<F>を値のセットとして定義する。上記の型定義によれば、BinaryTree<F>オブジェクトの左プロパティ及び右プロパティのいずれか一方または両方は、BinaryTree<F>型の値を含み得る。したがって、BinaryTree<F>データ型も再帰的データ型である。
既に述べたように、再帰的データ型のインスタンスはランタイムに参照サイクルに発展する可能性がある。図1は、ランタイムのオブジェクトの循環コレクションの例を示す。例えば、オブジェクトのコレクションは、ツリーまたはグラフのデータ構造を表し得る。楕円はコンピューターメモリのランタイムオブジェクトを表し、有向エッジは一方のオブジェクトから別のオブジェクトへの参照を表す。例えば、オブジェクト1は参照記号dによってオブジェクト2を参照する。例示的なコレクションでは、異なる方向の有向エッジによって示されるように、多数の参照サイクルがある。例えば、データオブジェクトのコレクションがツリーデータ構造を表す場合、オブジェクト6からオブジェクト7への参照記号uは、オブジェクト7がオブジェクト6のツリー内の最初の子ノードであることを表し得、その場合、参照記号vは、オブジェクト7がオブジェクト6のツリー内の最後の子ノードであることを表し得、参照記号tは、オブジェクト7がオブジェクト6のツリー内の親ノードであることを表し得る等が挙げられる。
ファサードアプローチ
本技術はファサードアプローチを含む。ファサードアプローチによれば、相互参照するノード及びエッジの分類法によってランタイムにオブジェクト間の関係を表す代わりに、ファサードアプローチを使用して、ランタイムに、オブジェクト間の関係を表すことができる。ファサードアプローチを用いると、オブジェクトのコレクションが、実行中のプログラムには循環(すなわち、見かけ上循環)として見え得るが、そのランタイムの実施態様は実際には非循環である。そのランタイムの実施態様は実際には非循環であるため、自動ガベージコレクターまたは自動サイクルコレクター等の暗黙的なランタイム割当解除サポートは必要ない。代わりに、単純な参照カウントメカニズムを使用して、オブジェクトをタイムリーに割当解除できる。
ソースプログラミング言語のソースコードを、ランタイムに暗黙的なオブジェクト割当解除をサポートしないターゲットプログラミング言語のソースコードに変換するソース・トゥ・ソース・コンパイラは、ファサードアプローチを使用するためにターゲットソースコードを生成できる。そうすることによって、ターゲットプログラミング言語ランタイムは、暗黙的なランタイム割当解除をサポートする必要がなく、オブジェクトをタイムリーに割当解除できる。ファサードアプローチと併せて、ソースプログラミング言語は、プログラマーに暗黙的な割当解除プログラミングエクスペリエンスを提供でき、プログラマーは、オブジェクトを明示的に割り当て及び割当解除するためにソースプログラミング言語でソースコードをプログラミングすることを気にする必要がない。このエクスペリエンスは、ソース・トゥ・ソース・コンパイラの1つ以上のターゲット言語が暗黙的なランタイム割当解除をサポートしない場合でも提供される。プログラマーは、また、ソースプログラミング言語で再帰的データ型を定義することも可能になる。ランタイムには、見かけ上循環しているように見えるが、実際には循環ではないため、参照サイクルはランタイムに作成されない。
ファサードアプローチでは、より大きな分類法が使用される。特に、より大きな分類法は以下のオブジェクトを含む。
・定義されたデータ型のインスタンスである「データ(data)」オブジェクト、
・データオブジェクト間の関係を収集する「関係(relationship)」オブジェクト、
・データオブジェクト及び関係オブジェクトをペアにする「グラフ(graph)」オブジェクト、ならびに
・循環しているかのような外観を提示し、データオブジェクト及びグラフオブジェクトの両方を参照する「ファサード」オブジェクト。
ファサードアプローチによれば、プログラムはランタイムにソースプログラミング言語でプログラムされるデータオブジェクトのコレクションにアクセスして変更し、参照サイクルを可能にする。例えば、データオブジェクトのコレクションは、ソースプログラミング言語で定義された再帰的データ型に基づくデータ構造を表し得る。例えば、データ構造は、データ構造のオブジェクトが再帰的データ型のインスタンスであるリスト、ツリー、またはグラフのデータ構造であり得る。
ファサードアプローチは、ファサードオブジェクトを経由して、データオブジェクトのコレクションが非循環性を維持できるランタイムメカニズムを提供する。ファサードオブジェクトを経由して、明らかに循環データオブジェクトのコレクションは、プログラムからは循環に見えるにもかかわらず、実際の非循環性が維持される。非循環性が維持されるため、データオブジェクトのコレクションをタイムリーに割当解除するためにランタイムのガベージコレクションまたは参照サイクルの検出は必要ない。
ファサードアプローチの分類法では、所与のファサードオブジェクトは、最大1つのグラフオブジェクト及び最大1つのデータオブジェクトに対応する。しかしながら、複数のファサードオブジェクトは同じデータオブジェクトに対応し得る。所与のグラフオブジェクトは、1つ以上の関係オブジェクトに対応し得、所与の関係オブジェクトは、1つ以上のデータオブジェクトに対応できる。したがって、所与のグラフオブジェクトは、所与のグラフオブジェクトが対応する1つ以上の関係オブジェクトを介して1つ以上のデータオブジェクトに対応できる。
図2は、図1に示されるオブジェクトの循環コレクションの例に対するファサードアプローチの適用例を示す。図2に確認できるように、オブジェクトの循環コレクションは、ランタイムにオブジェクトの非循環コレクションとして表される。この例では、データオブジェクト1、4、及び6にはファサードオブジェクトだけがあり、データオブジェクト2、3、5、及び7にはファサードオブジェクトがない。ファサードオブジェクトが1つだけあるセットと、同じ下層のデータオブジェクトの複数のファサードオブジェクトを含むセットとを含む、ファサードオブジェクトの異なるセットが可能になる。さらに、ファサードオブジェクトの異なるセットは、データオブジェクトのコレクションに対するプログラムのアクセスパターン及び変更パターンに応じて、実行中のプログラムの過程の異なる時点で、データオブジェクトのコレクションに対して作成され得る。
ランタイムに、コレクションのデータオブジェクトへの参照は、データオブジェクトのファサードオブジェクトを介して行われる。例えば、図2を参照すると、プログラムがファサードオブジェクト6を使用して、参照fの他端にあるデータオブジェクト1を要求する場合、データオブジェクト1またはデータオブジェクト1への参照を提供する代わりに、ファサードオブジェクト1がプログラムに提供される。例えば、ファサードオブジェクト1は、ファサードオブジェクト6の計算プロパティの抽象化によって提供され得る。
ランタイムにどのデータオブジェクトが参照の他端にあるかを判定するために、ファサードオブジェクトはグラフオブジェクトを使用し得る。グラフオブジェクトはマップオブジェクトを含み得る。マップオブジェクトは、データオブジェクト関係をオブジェクトとペアにする。例えば、図2のマップオブジェクトは、データオブジェクト6及びデータオブジェクト1を関係オブジェクトXにマッピングし得る。特に、プログラムがデータオブジェクト6のファサードオブジェクト6を使用して、参照fの他端にあるデータオブジェクトを参照するとき、ファサードオブジェクト6はグラフオブジェクト及びマップオブジェクトを使用して、グラフオブジェクトによって参照される関係オブジェクトのどれが、参照fを介してデータオブジェクト6とデータオブジェクト1との間の関係を収集しているかを判定する。次に、ファサードオブジェクト6は、ファサードオブジェクト1を作成し得る。その際に、ファサードオブジェクト1は、ファサードオブジェクト6が関係オブジェクトXを介して取得するデータオブジェクト1を参照するように作成または構成される。ファサードオブジェクト1は、グラフオブジェクトを参照するように作成または構成される。これは図2に示される。次に、データオブジェクト1の代わりにファサードオブジェクト1は、ファサードオブジェクト6によって呼び出しプログラムに返され、データオブジェクトのコレクションの見かけの循環性ではあるが、実際の非循環性が維持される。
マップオブジェクトは様々な方法で構築され得る。例えば、マップオブジェクトは、アレイの各要素がデータオブジェクトのペアに対応し、データオブジェクトのペア間の全ての関係をグループ化する関係オブジェクトを示す2次元アレイを含み得る。例えば、Mが2次元アレイの場合、M[x][y]は、データオブジェクトxとデータオブジェクトyとの間の全ての関係をグループ化する関係オブジェクトを参照する。2次元アレイの代替として、M[x][y]は、データオブジェクトxからデータオブジェクトy(またはデータオブジェクトyからデータオブジェクトx)までの全ての関係をグループ化する関係オブジェクトを参照し得る。代替として、マップオブジェクトは、各アレイ要素がデータオブジェクトと、そのデータオブジェクトから他のデータオブジェクトへの全ての関係をグループ化する関係オブジェクトとに対応する1次元アレイを含み得る。例えば、M[x]は、データオブジェクトxから他のデータオブジェクトへの全ての関係をグループ化する関係オブジェクトを参照し得る。
データオブジェクトがランタイムにコレクションに追加されるとき、それはグラフオブジェクトに接続され得る。例えば、図3は、図1のデータオブジェクトの循環コレクションを示すが、データオブジェクト4の参照w及びxを有するデータオブジェクト8が追加されている。参照w及びxは、図3のオブジェクトの循環コレクションに参照サイクルを作成する。図4は、データオブジェクト8を追加したオブジェクトのコレクションの見かけ上循環コレクションであるが、実際には非循環コレクションの表現を示す。特に、グラフオブジェクトのマップオブジェクトは、データオブジェクト8及びデータオブジェクト4を関係オブジェクトYにマッピングするように更新され得る。関係オブジェクトYは、データオブジェクト8とデータオブジェクト4との間のw及びxの関係を収集する。
ファサードアプローチでは、データオブジェクトはグラフオブジェクトを介して別のデータオブジェクトと関係を築くことができる。これは、データオブジェクトを既存のデータ構造に追加する方法に影響をもたらす。例えば、考えられるソースプログラミング言語で以下のソースコードを検討する。
00: let root = BinaryTree("root", Empty, Empty);
01: let left = BinaryTree("left", Empty, Empty);
02: root.left = left;
行00は、上記に説明したBinaryTree<F>再帰的データ型のインスタンスとして「root」データオブジェクトを作成する。図5Aは、ファサードアプローチによる、上記の行00で作成された「root」データオブジェクトの非循環ランタイム表現を示す。変数「root」は、「root」データオブジェクトを直接参照する代わりに、「root」データオブジェクト及び「root」グラフオブジェクトを参照するファサードオブジェクトである。実行のこの時点において、行01の「left」オブジェクトインスタンスは作成されていない。したがって、「root」関係オブジェクトは、「root」データオブジェクトと「left」オブジェクトとの間の関係をグループ化しない。
行01は、上記に説明したBinaryTree<F>再帰的データ型のインスタンスとして「left」データオブジェクトを作成する。図5Bは、ファサードアプローチによる、上記の行01で作成された「left」データオブジェクトの非循環ランタイム表現を示す。変数「left」は、「left」データオブジェクトを直接参照する代わりに、「left」データオブジェクト及び「left」グラフオブジェクトを参照するファサードオブジェクトであり、「left」グラフオブジェクトは、図5Aに示されるように「root」データオブジェクトの「root」ファサードオブジェクトが参照する「root」グラフオブジェクトとは異なるグラフオブジェクトであり得る。実行のこの時点において、「root」データオブジェクトと「left」データオブジェクトとの間には依然として関係がない。したがって、「left」データオブジェクトを参照する「left」関係オブジェクトも、「root」オブジェクトと「left」オブジェクトとの間の関係をグループ化しない。「左の関係オブジェクト」は、図5Aに示されるように、「root」データオブジェクトを参照する「root」関係オブジェクトとは異なる関係オブジェクトであり得る。
行02は、「root」オブジェクトの左プロパティを「left」データオブジェクトを参照するように設定する。ファサードアプローチがない場合、「root」データオブジェクトの左プロパティは、ランタイムに「left」データオブジェクトを直接参照し得る。しかしながら、ファサードアプローチを用いると、ソースプログラミング言語のソースコードが、暗黙的なランタイム割当解除をサポートしないターゲットプログラミング言語のソースコードにコンパイルされるとき、そのような直接参照が防止される。具体的には、ターゲット言語ソースコードはランタイムにファサードアプローチを実施するようにコンパイルされ、その結果、ターゲット言語ソースコードが実行可能にコンパイルされ実行されるとき、直接参照が防止される。
図5Cは、ファサードアプローチによる、「root」データオブジェクトの左プロパティが「left」データオブジェクトを参照するように割り当てられた後の「root」データオブジェクト及び「left」データオブジェクトの非循環ランタイム表現を示す。このとき、ルート及び左側のファサードオブジェクトが同じグラフオブジェクトを共有するようになる。具体的には、「left」ファサードオブジェクトによって参照される「left」グラフオブジェクト(図5B)は、「root」ファサードオブジェクトによって参照される「root」グラフオブジェクト(図5A)にインポートされる。その際に、「left」ファサードオブジェクトが更新され、「root」グラフオブジェクトを参照し、「left」グラフオブジェクトを参照しなくなる。「root」グラフオブジェクトによって参照される「root」関係オブジェクトは、「left」データオブジェクトを参照するように更新され、左グラフの「left」関係オブジェクトは「left」データオブジェクトから切断される。ここで、左側のグラフの「left」グラフオブジェクトは、その参照カウントがゼロであるとき割当解除され得る。「left」グラフオブジェクトが割当解除されると、「left」グラフオブジェクトの「left」マップオブジェクト及び「left」関係オブジェクトが割当解除され得る。これは、「left」グラフオブジェクトが割当解除された後、それらの参照カウントをゼロにする必要があるためである。「root」グラフオブジェクトの「root」マップオブジェクトは、「root」データオブジェクトが左側の「データオブジェクト」と関係を築き、その関係が「root」関係オブジェクトによってグループ化されることを指定するために更新される。
図5Cの非循環表現は、ランタイムに、図5Dに示されるように、「root」データオブジェクトの左プロパティが「left」データオブジェクトを直接参照するという概念を表す。
ここで、上記のソースコードに加えて、考えられるソースプログラミング言語で以下のソースコードを検討する。
03: left.right = root;
04: let extra = root;
ファサードアプローチがない場合、上記の行03の追加のソースコードにより、ランタイムに「root」データオブジェクトと「left」データオブジェクトとの間に参照サイクルが作成される。しかしながら、ファサードアプローチを用いると、参照サイクルを回避できる。これは図5Eに示され、図5Eは、ファサードアプローチによる、上記の行03のように、「left」データオブジェクトの右プロパティがファサードオブジェクトを経由して「root」データオブジェクトを参照するように割り当てられた後の「root」データオブジェクト及び「left」データオブジェクトの非循環ランタイム表現を示す。「root」データオブジェクト及び「left」データオブジェクトは、依然として、(1)「root」データオブジェクトの左プロパティを介した「root」データオブジェクトと「left」データオブジェクトとの間の関係、(2)「left」データオブジェクトの右プロパティを介して作成された「root」データオブジェクトと「left」データオブジェクトとの間の関係、の両方をグループ化する「root」関係オブジェクトを共有する。「extra」という名前の変数は、「root」グラフオブジェクト及び「root」データオブジェクトを参照するファサードオブジェクトである。
ここで、上記のソースコードに加えて、考えられるソースプログラミング言語で以下のソースコードを検討する。
05: let super = BinaryTree("root", Empty, Empty);
06: super.left = root;
行05は、上記に説明したBinaryTree<F>再帰的データ型のインスタンスとして「super」データオブジェクトを作成する。行06は、上記の行00で作成された「root」データオブジェクトを参照するように「super」データオブジェクトの左プロパティを設定する。ファサードアプローチでは、行06は、結果として、ランタイムの暗黙的な割当解除をサポートしないターゲット言語の場合、ランタイムに「root」グラフオブジェクトが「super」グラフオブジェクトにインポートされ得る。このインポートは図5Fに示される。図5Fは、ファサードアプローチによる、インポート後の「super」、「root」、及び「left」データオブジェクトの非循環表現を示す。「root」及び「left」ファサードオブジェクトは、「super」グラフオブジェクトを参照するように更新されている。「super」グラフオブジェクト及び「super」マップオブジェクトが更新され、「root」関係オブジェクトへの「root」データオブジェクトの左プロパティ(上記の行02)を介して、「root」データオブジェクトと「left」データオブジェクトとの間の関係がマッピングされる。また、「super」グラフオブジェクト及び「super」マップオブジェクトも更新され、「super」関係オブジェクトへの「super」データオブジェクトの左プロパティ(上記の行06)を介して、「super」オブジェクトと「root」データオブジェクトとの間の関係がマッピングされる。ファサードアプローチがない場合でも、行03が参照サイクルを作成するようにプログラムされている場合でも、非循環性が維持されることに留意されたい。
上記の行04で「root」データオブジェクトを参照するように割り当てられた「extra」ファサードオブジェクトは、依然として、上記の行06によってグラフのインポートが生じた後、「root」グラフオブジェクトを参照し得ることに留意されたい。しかしながら、グラフのインポートにより、「root」グラフオブジェクトは「root」関係オブジェクトを参照しなくなる。言い換えれば、「extra」ファサードオブジェクトは、上記の行06によって生じたグラフのインポートによって「放棄(abandoned)」されている。この放棄は図5Fに示されている。確認できるように、「root」マップオブジェクトは「root」関係オブジェクトに接続されていない。したがって、上記の行06以降、ソースプログラミング言語のソースコードプログラマーは、「root」データオブジェクトが別のオブジェクトと築く関係を逆参照するために「extra」ファサードオブジェクトを使用することを試みないことを注意する必要があり得る。例えば、以下の追加のソースコードを検討する。
07: A = root.left;
08: B = extra.left;
ランタイム、図5Fに示されるインポート後、結果として、上記の行02の割り当てにより、変数Aは「left」データオブジェクトを参照するファサードオブジェクトになるであろう。しかしながら、行08のステートメントは、「extra」ファサードオブジェクトが図5Fに示されるグラフのインポートによって破棄されたため、ランタイムエラーまたはフォールトを生成するであろう。ソースプログラミング言語で慎重にプログラミングすると、グラフのインポートによってファサードオブジェクトが放棄されるのを回避できる。例えば、行04の余分な変数の作成は省略され、既に作成されている「root」ファサードオブジェクトが代わりに使用され得る。
同じ下層のデータオブジェクト及び同じ下層のグラフオブジェクトを参照する異なるファサードオブジェクトについて、ファサードオブジェクトのメモリアドレスの比較に基づいて同等かどうか適切に比較できない。これは、ファサードオブジェクトが異なるメモリアドレスに記憶されているためである。しかしながら、両方のファサードオブジェクトが同じ下層のデータオブジェクト及び同じ下層のグラフオブジェクトを参照する場合、ファサードオブジェクトは別のファサードオブジェクトと意味的に同じである。ファサードアプローチによれば、ターゲットプログラミング言語(例えば、CまたはC++)の等価演算子をオーバーライドでき、その結果、2つのファサードオブジェクトが等しいかどうかを比較するとき、それらのファサードオブジェクトが同じ下層のデータオブジェクト及び同じ下層のグラフオブジェクトを参照している場合に演算子が2つのファサードオブジェクトが等しいことを示し、そして、それらのファサードオブジェクトが異なるデータオブジェクトまたは異なるグラフオブジェクトを参照している場合は等しくないことを示す。
データ型定義の可能なサイクルの確認
既に述べたように、データオブジェクトのコレクションにランタイムに参照サイクルが含まれない場合、参照カウントはデータオブジェクトのタイムリーな割当解除に十分である。ガベージコレクションまたはサイクル検出等のより高度な割当解除メカニズムは必要ない。
ランタイムに、データオブジェクトがどのように生成され、どのように変化するかは、ソースプログラミング言語のソースコードのデータ型の定義によって決まる。ソースプログラミング言語は、ランタイムに参照サイクルが発生するのを防止するのに十分な制限をソース内のデータ型定義に課すことができる。
例えば、考えられるソースプログラミング言語での「Cons」リストの以下のデータ型定義を検討する。Cons<F>データ型は、空であるか、または先頭要素、及び残りの要素を含む別のリストであるテールを有するか、のいずれか一方の再帰的データ型である。
00: closed type List<E>;
01: closed concrete type Cons<F> extends List<F> {
02: head: F;
03: tail: List<F>;
04: }
05: closed concrete type Empty<G> extends List<G> {}
上記のデータ型定義は、ランタイムの参照サイクルの影響を受けやすくなる。例えば、以下の例のように、それ自体でテールを指すように構成されるCons<F>データオブジェクトを作成することによって、「ウロボロス(ouroboros)」リストを作成できる。
06: let list = Cons(0, Empty);
07: list.tail = list;
本技術の一部によれば、ランタイムの参照サイクルの影響を受けやすいソースプログラミング言語のソースコードのデータ型定義は、ソースコードのコンパイル時に検出される。次に、コンパイラはプログラマーにアラートを発することができる、またはソースコードのコンパイルを停止できる。アラートは、例えば、ユーザーインターフェースに提示されるワーニングメッセージもしくはエラーメッセージ、またはファイルへの出力等であり得る。代わりに、ソースコードの潜在的な参照サイクルを検出してアラートを生成するコンパイラ、専用の型チェックツール、または他のソースコード管理ツールは検出及びアラーティングを行い得る。
概して、データ型定義の潜在的な参照サイクルの検出は、ソースプログラミング言語コンパイラが、関係する各データ型のノードを伴うデータ型定義グラフを作成し、その後、そのデータ型を表すノードに各プロパティのエッジを追加することを含む。上記のCons<F>型等のジェネリックデータ型の場合、コンパイラはデータ型パラメーターをコンテキスト化する。コンテキスト化は、抽象的データ型定義ではなく、具象データ型定義ごとにグラフを作成することによって達成される。具象データ型定義はランタイムにそのデータ型のデータオブジェクトをインスタンス化するために使用できるが、抽象データ型定義はそこから導出した具象データ型をサポートするためだけに存在する。具象データ型定義ごとのグラフを用いると、コンパイラはデータ型パラメーターを具象データ型定義で定義されたもののコンテキストに変換できるため、ソースプログラミング言語のソースコードのプログラマーが、例えば、複数のリストのうちの1つのリスト等のネストされたデータ構造を定義し、安全に使用することを可能にする。さらに、コンパイラは、データ型パラメーターごとに、データ型パラメーターがバインドし得るデータ型に関する最悪のケースを表す「リミットノード」を作成する。
図6Aは、上記に定義した具象データ型及びジェネリックデータ型Cons<F>のデータ型定義グラフの例である。グラフの実線のエッジは、ランタイムの参照サイクルに関係し得るエッジを表す。そのグラフは、ランタイムに参照サイクルが発生し得る2つの方法を示す。
第1の方法では、エッジ602は、Cons<F>型のデータオブジェクトが、そのテールプロパティを介してList<F>型のデータオブジェクトを指すことができることを表す。エッジ604は、List<F>型のデータオブジェクトがCons<F>型のデータオブジェクトでもあり得ることを表す。
第2の方法では、ジェネリックデータ型FがTopのような非常にジェネリックデータ型(全てのデータオブジェクトを含む仮想のスーパーデータ型を表す)でインスタンス化された場合、Cons<F>型のデータオブジェクトはそのヘッドプロパティを介して、型Fのデータオブジェクトを指し得、型Fは、Cons<F>型のデータオブジェクトへの独自のプロパティ参照を有するいくつかの未知のデータ型であり得る。第2の方法は、図6Aのエッジ606、608、及び610によって表される。
第1のデータ型の参照サイクルは、データ型定義に2つの余分な情報を含めることを可能にすることによって解決できる。この情報は、ソースプログラミング言語のソースコードのプログラマーが手動で入力できる、ソースコードの静的分析に基づいて推論できる、または、例えば、自動もしくは半自動のデータ型チェックツール等、その情報が自動もしくは半自動ツール等で必要とされるためソースコードに自動的に追加できる。
データオブジェクトのプロパティがランタイムに、そのプロパティを含むデータオブジェクトよりも古いデータオブジェクトだけを指すことができる場合、そのプロパティは参照サイクルには不十分である。したがって、プロパティの初期値がそのプロパティを含むデータオブジェクトよりも古く、プロパティがその初期値から変更できない(例えば、読み取り専用である)とコンパイラによって判定できる場合、そのプロパティは参照サイクルとしては不十分である。
本技術によれば、データオブジェクトのデータ型定義のデータオブジェクトのプロパティに対して、2つのメタプロパティを暗黙的に(例えばデフォルトで)または明示的に(例えばプログラマーによって)定義し得る。
・読み取り専用-「読み取り専用(read only)」プロパティは、最初に割り当てられた値から変更できないデータオブジェクトのプロパティである。
・初期-「初期(early)」プロパティは、単にデータオブジェクトのプロパティを初期化する手段として使用される代わりに、そのプロパティを含むデータオブジェクトへの任意の参照が値として使用される前に、最初に割り当てられる値が判定されるデータオブジェクトのプロパティである。この後者の制限は、コンストラクターでの例外的なケースが回避される。
上記の2つのメタプロパティを用いると、以下の例のように、以下の読み取り専用の初期ヒントを用いて、上記のデータ型定義の例を変更できる。
00: closed type List<E>;
01: closed concrete type Cons<F> extends List<F> {
02: head: F;
03: readonly early tail: List<F>;
04: }
05: closed concrete type Empty<G> extends List<G> {}
コンパイラがコンパイル時にデータ型定義のプロパティが読み取り専用であるかどうかを判定するのに、様々な方法がある。特別な方法は必要ない。1つの方法は、プロパティ定義でプログラマーによって明示的にプログラムされたキーワードヒントに基づいている。キーワードのヒントは、「const」、「final」、「readonly」等である。別の方法は、例えば、プロパティ定義に「変更可能(mutable)」または「書き込み可能(writeable)」キーワードヒントが存在しない等、逆の意味があるキーワードヒントが存在しないことに基づき得る。さらに別の方法は、コンパイラがソースコードの静的分析を実行して、初期値が割り当てられた後にプロパティに値を設定できたソースコードのいずれかが実際に設定されているかどうかを判定することである。そうでない場合、コンパイラはプロパティが読み取り専用であると推論できる。静的分析は、プロパティ定義の明示的なキーワードヒント(例えば「読み取り専用(read-only)」)によってトリガーできる。
また、コンパイラは、プロパティが初期化された後のランタイムにプロパティに値が割り当てられないようにする追加命令をコンパイル時に挿入することによって、プロパティを強制的に読み取り専用にすることもできる。さらに、またはその代わりに、追加命令は、プロパティが初期化された後にプロパティに値を割り当てようとするランタイムにおける任意の試行をログに記録し得る(例えば、ランタイム診断ログまたはランタイムプロファイラログに記録する)。
同様に、コンパイラがコンパイル時にプロパティが初期であるかどうかを判定できる様々な方法がある。特別な方法は必要ない。1つの方法は、プロパティ定義のキーワードヒントの有無に基づいている。別の方法は、コンパイラがソースコードを静的に分析して、含まれているデータオブジェクトを値として任意の参照が行われる前にプロパティが初期化されているかを判定することである。静的分析は、プロパティ定義の明示的なキーワードヒント(例えば「初期」)によってトリガーできる。
コンパイラは、また、プロパティを含むデータオブジェクトへの参照が値として使用された後、ランタイムにプロパティが初期化されないようにコンパイル時に追加命令を挿入することによって、プロパティを強制的に初期にすることもできる。さらに、またはその代わりに、追加命令は、プロパティを含むデータオブジェクトへの参照が値として使用された後、ランタイムにプロパティを初期化する任意の試行をログに記録し得る(例えば、ランタイム診断ログまたはランタイムプロファイラログに記録する)。
また、コンパイラがコンパイル時にデータ型がクローズしているかどうかを判定できる様々な方法もある。クローズデータ型は、コンパイル時にあらゆる全てのサブデータ型がコンパイラに知られるデータ型である。コンパイラは、「ファイナル(final)」、「クローズド(closed)」、「シールド(sealed)」等のデータ型定義の明示的なキーワードヒントに基づいて、または「オープン(open)」等の反対の意味があるデータ型定義の明示的なキーワードヒントに基づいて、データ型がクローズされているかどうかを判定できる。クローズ性は、コンテキストに基づいたソースコードの静的分析の一部としてコンパイラによって推論され得る。例えば、データ型定義へのアクセスが情報隠蔽メカニズムによっていくつかのモジュールまたはパッケージに制限されており、それらのモジュールまたはパッケージにデータ型のサブデータ型の定義が存在しない場合、コンパイラはそのデータ型がクローズしていると推論できる。
また、コンパイラがコンパイル時にデータ型が具体的であるかどうかを判定できる様々な方法もある。具象データ型は、そのデータ型のサブデータ型のインスタンスではない、その型のデータオブジェクトとして存在する可能性があるデータ型である。具象データ型は、データオブジェクトを定義するには不十分であるが具象サブデータ型を導出し得る抽象データ型とは対照的である。コンパイラは、「具象的(concrete)」等のデータ型定義の明示的なキーワードヒントの存在に基づいて、または「抽象的(abstract)」等の逆の意味があるデータ型定義の明示的なキーワードヒントの存在に基づいて、データ型が具体的であると判定できる。コンパイラは、データ型のデータオブジェクトを構築するためにソースコードでデータ型を使用する等、ソースコードの静的分析によって、またはデータ型のデータオブジェクトの構築を妨げるようなソースコードのデータ型のデータ型定義に定義要素が存在しないことによって、データ型の具体性を推論し得る。全てのデータオブジェクトは具象データ型である必要があるため、参照サイクルが作成される可能性について具象データ型だけを型チェックするだけで十分である。
図6Bは、読み取り専用ヒント及び初期ヒントを使用する上記のデータ型定義のデータ型定義グラフの例である。確認できるように、エッジ602及びエッジ604は、ここで、対応する参照がランタイムの参照サイクルの作成に関与できないことを反映するために断線している。さらに、テールプロパティのエッジ602は、厳密に未満の関係(「<」)、以下の関係(「<=」)を有するようになった。意味的には、データ型定義グラフのサイクルのエッジが以下の関係(「<=」)がある場合、エッジによって表されたデータ型定義の一部がランタイムの参照サイクルに対して不十分になる既知の順序付けが存在する。既知の順序付けの1つのタイプは、読み取り専用の初期関係である。例えば、テールプロパティに対する読み取り専用で早期の制限のため、図6Aのエッジ602及びエッジ604の潜在的な参照サイクルは、図6Bに表されるような潜在的な参照サイクルではなくなっている。データ型がそれ自体の値以下であると主張することに矛盾はないことが認識される。
しかしながら、図6Bのエッジ606、608、及び610によって表された潜在的な参照サイクルが依然として存在する。特に、テールプロパティに読み取り専用の初期ヒントが設定されている場合でも、Cons<F>データオブジェクトのヘッドプロパティが未知の型Fのデータオブジェクトを参照でき、次に、そのデータオブジェクトがCons<F>データオブジェクトを逆に指すことができたことによって、参照サイクルが作成される。これは、ヘッドプロパティが読み取り専用で早期であっても同様である。この理由として、ヘッドプロパティは、Cons<F>データオブジェクトを参照する未知の型Fのデータオブジェクトに初期化できたためである。
図6Bのエッジ606、608、及び610によって表されたタイプの参照サイクルを防止するには、参照がそれ自体に対するものでない限り、特定のデータ型のデータオブジェクトが同じ特定のデータ型の別のデータオブジェクトを参照できるようにすることが望ましい。例えば、それ自体を参照しない複数のリストのうちの1つのリストを可能にすべきである。さらに、プリミティブデータ型を含むデータオブジェクトも可能にすべきである。例えば、文字列または数値のリストを可能にすべきである。
データオブジェクトのプロパティが任意のデータ型であり得るジェネリックデータ型である等の問題に対処するには、ソースプログラミング言語のソースコードで表現された追加の制限を使用し得る。例えば、以下の「Cons」リストのデータ型定義を検討する。
00: closed type List<E ┤ Cons<E>>;
01: closed concrete type Cons<F ┤ Cons<F>> extends List<F> {
02: head: F;
03: readonly early tail: List<F>;
04: }
05: closed concrete type Empty<G ┤ Cons<G>> extends List<G> {}
上記の例では、A ┤ Bという表記は、AタイプのデータオブジェクトがランタイムにBタイプのデータオブジェクトを直接参照してはいけないこと、またはBタイプのデータオブジェクトを直接参照する任意のデータオブジェクトを直接参照してはいけないことを意味する。本技術は、例えばList<Number>が有効であるかどうかを判断するとき、この表記に従っている。ソースコードエディタで使用されるフォント合字に応じて、表記はダッシュバーとして書かれ得、シンボルはソースプログラミング言語のソース内で('┤')または('-|')として見え得る。他のテキストベースの表記を使用して、「AはBを指してはいけない」という制限を表現し得、本発明はダッシュバー表記に限定されない。
本技術によれば、上記のデータ型定義の結果、Cons<F>のデータ型定義はジェネリックで再帰的であり、重要なことに参照サイクルがない。
図6Cは、読み取り専用ヒント及び初期ヒントならびに追加情報を使用する上記のデータ型定義のデータ型定義グラフの例である。確認できるように、データ型定義は、Cons<F>からの参照で開始し、Cons<F>からCons<F>に戻る'<'エッジを伴う潜在的な参照サイクルがない。図6Bのデータ型定義グラフと図6Cのデータ型定義グラフとの違いは、Fデータオブジェクトが「Top ┤ ()」の代わりに「Top ┤ (Cons<F>)」であり得ることである。この制限により、Top(すなわち、全てのスーパーデータ型)、またはList<F>もしくはCons<F>への「可能性のある(may-be)」接続は存在しない。しかしながら、何も参照しないEmpty<F>が可能になる。
データ型チェックプロセスの例
図7A、図7B、図7C、図7D、図7E、図7F、図7G、図7Hは、データ型チェックプロセスの例のフローチャートを含む。データ型チェックプロセスは、ソースコードが具象データ型定義を含む、ソースプログラミング言語のソースコードのコンパイラによって行われ得る。コンパイラは、データ型チェックプロセスを行って、具象データ型定義がランタイムに参照サイクルを可能にしているかどうかを判定し得る。ランタイムに参照サイクルを可能にする具象データ型定義を検出すると、コンパイラはコンパイルプロセスを停止できる、またはアラートを出力できる。アラートは、ユーザーインターフェース(例えば、グラフィカルまたはコマンドライン)、ファイルに、データベースに、またはアラートに適した別のデータコンテナに出力できる。アラートは、型チェックプロセスによって識別された具体的型定義に問題があったことを示すエラーメッセージまたはワーニングメッセージであり得る。例えば、メッセージは、ランタイムの参照サイクルを可能にする具象データ型定義を識別し得る。例えば、識別は、ソースコードファイルの名前及びソースコードファイルの行番号、または、具象データ型定義が定義されているソースコードファイルの行番号のセットもしくはスパンを、エラーまたはワーニングの説明と一緒に含み得る。例えば、説明は「mysource.srcの52行目で定義された具体的型Cons<F>は参照サイクルを可能にする。」のような内容が記載され得る。
型チェックプロセスを行うコンパイラは、ソースプログラミング言語のソースコードを1つ以上のターゲットプログラミング言語にコンパイルするソース・トゥ・ソース・コンパイラであり得、1つ以上のターゲットプログラミング言語は、割当解除の最小のランタイムサポート(例えば、非暗黙的な割当解除サービス)を用いた、少なくとも1つのターゲットプログラミング言語を含む。例えば、ターゲットプログラミング言語は、C、C++、OBJECTIVE-C、またはRUSTのいずれかであり得る。代替として、ソースコードのコンパイラは、ソースコードの中間表現をターゲットプログラミング言語にさらに翻訳することなく、品質管理の目的でソースコードを処理し得る。さらに別の代替として、コンパイラは、ソースプログラミング言語のソースコードを、全てのターゲット言語が暗黙的な割当解除をサポートする1つ以上のターゲットプログラミング言語にコンパイルするソース・トゥ・ソース・コンパイラであり得る。この場合、型チェックは、例えばランタイムのガベージコレクションまたはサイクル検出の必要性を軽減または排除する等の品質管理のために行われ得る。
図7Aから開始するように、データ型チェックプロセスは、ソースコードで定義された具象データ型Cのデータ型チェックグラフ用の未構築ノードの空リストから開始する(712)。空リストは、コンピューターストレージ媒体で初期化された適切なリストデータ構造であり得る。実施例として、データ型チェックプロセスの説明では、考えられるソースプログラミング言語で表現された以下のデータ型定義を使用する。
00: closed type List<E ┤ Cons<E>>;
01: closed concrete type Cons<F ┤ Cons<F>> extends List<F> {
02: head: F;
03: readonly early tail: List<F>;
04: }
05: closed concrete type Empty<G ┤ Cons<G>> extends List<G> {}
実施例では、Cは具象データ型Cons<F>である。
動作714において、グラフの具象データ型Cのノードを表す要素は未構築ノードリストに追加される。実施例では、具象データ型Cons<F>のノードを表す要素は未構築ノードリストに追加され得る。
動作716において、未構築ノードリストが空である(すなわち、任意の要素を含まない)であるかどうかを判定する。未構築ノードリストが空でない場合、動作718、720、722、及び724は、未構築ノードリスト上の現在のノードに対して行われる。
動作718において、未構築ノードリスト上の現在のノードNが識別される。例えば、現在のノードNは、未構築ノードリストに最近追加された要素に対応するノードであり得る。実施例では、現在のノードNは、具象データ型Cons<F>に対して追加されたノードであり得る。
動作720において、現在のノードNを表す要素が未構築ノードリストから除去される。実施例では、具象データ型Cons<F>の現在のノードNを表す要素は、未構築ノードリストから除去され得る。
動作722は、現在のノードNによって表されたデータ型を拡張するソースコードで定義されたダイレクトサブデータ型Sごとに行われる。サブデータ型は、トレイトベースの継承をサポートするオブジェクト指向プログラミング言語で通常可能になるように、サブクラスまたは子クラスの意味で現在のノードNによって表されたデータ型を直接拡張し得る。ソースプログラミング言語は、そのようなトレイトベースの継承をサポートし得る。トレイトは、細粒度コード再利用のためのメカニズムを提供する。トレイトは、クラス階層から独立した方法のセットとして定義され得、一連の合成操作によって他のトレイトまたはクラスを構築するために柔軟に使用できる。
動作722は、図7Bに関してより詳細に示される。実施例では、現在のノードNがCons<F>データ型であるとき、動作722は、Cons<F>データ型を拡張するように定義されたダイレクトサブデータ型が存在しないため、具象データ型Cons<F>の任意のダイレクトサブデータ型Sに対して行わない場合がある。
動作724は、現在のノードNによって表されたデータ型のプロパティPごとに行われる。データ型のプロパティ[AS12]は、現在のノードNによって表されたデータ型の定義のソースコードのメンバー変数定義に対応し得る。メンバー変数は、データ型の静的変数またはインスタンス変数であり得る。動作724は、図7Cに関してより詳細に示される。実施例では、動作724は、Cons<F>データ型に対して定義されたヘッドプロパティ及びテールプロパティのそれぞれに対して行われ得る。
現在のノードNに対して動作718、720、722、及び724が行われた後、プロセスは動作716に戻り、他のノードに対応する未構築ノードリスト上の任意の残りの要素を検討する。動作716で未構築ノードリストに要素が残っていない場合、動作726において、動作720で除去された全てのノードの要素は、図7Dに関して下記に説明されるようなさらなる処理のために未構築ノードリストに再び追加される。
既に述べたように、図7Aの動作722は、現在のノードNによって表されたデータ型を直接拡張するソースコードのサブデータ型Sごとに行われる。図7Bは動作722のフローチャートである。
動作728において、現在のダイレクトサブデータ型Sがジェネリック型である場合、現在のダイレクトサブデータ型Sは、現在のノードNによって表されたデータ型の型パラメーターを使用して変換される。例えば、「class Sub<X>はSuper<Bar<X>>を拡張する」等の型関係及び「Super<Bar<Baz>>」等のスーパー型を所与とすると、変換は、Subの型パラメーターのそれぞれに対する適切なバインディングを見つけることを含み得る。この例では、XはBazにバインドされ、Sub<Baz>がSuper<Bar<Baz>>を拡張するため、変換されたサブデータ型はSub<Baz>になるであろう。これは、Sub<X>がSuper<Bar<X>>を拡張することが、XがBazに置換されたとき、それを反映するため知られており、そして、Xにバインドされなくなり、XがBazにバインドすることが防止されるであろう。
動作730において、現在のダイレクトサブデータ型Sのノードを表す要素が未構築ノードリスト上にあるかどうかを判定する。ない場合、動作732において、現在のダイレクトサブデータ型Sを表すノードに対して要素が作成され、動作734において、その要素が未構築ノードリストに追加される。いずれの場合も、具象データ型Cのデータ型定義グラフにエッジが追加され(736)、エッジは現在のノードNから現在のダイレクトサブデータ型Sのノードまでである。エッジは、現在のノードNによって表されたデータ型のインスタンスであるデータオブジェクトが、現在のダイレクトサブデータ型Sのインスタンスでもあり得るという点で「可能性のある」要件で限定される。
既に述べたように、図7Aの動作724は、ソースコードで定義された現在のノードNによって表されたデータ型のプロパティPごとに行われる。図7Cは、動作724のフローチャートである。実施例では、現在のノードNがCons<F>データ型を表す場合、動作724がヘッドプロパティ及びテールプロパティのそれぞれに対して行われる。
動作738において、現在のプロパティPのデータ型は、現在のノードNによって表されたデータ型の型パラメーターを使用して変換される。この実施例では、現在のプロパティPがCons<F>データ型のヘッドプロパティであるとき、現在のプロパティPのデータ型はジェネリック型Fである。現在のプロパティがCons<F>データ型のテールプロパティであるとき、現在のプロパティPのデータ型はList<F>である。
動作740において、現在のダイレクトサブデータ型Sのノードを表す要素が未構築ノードリスト上にあるかどうかを判定する。ない場合、動作742において、現在のプロパティPのデータ型を表すノードに対して要素が作成される。動作744において、その要素が未構築ノードリストに追加される。この実施例では、現在のプロパティPがCons<F>データ型のヘッドプロパティであるとき、ジェネリックデータ型Fを表すグラフのノードの要素は未構築ノードリストに追加される。現在のプロパティPがCons<F>データ型のテールプロパティであるとき、List<F>データ型を表すグラフのノードの要素が未構築ノードリストに追加される。
動作746において、現在のプロパティPが読み取り専用で初期として定義されている場合がある。実施例では、現在のプロパティPがCons<F>データ型のヘッドプロパティであるとき、Cons<F>データ型のデータ型定義のプロパティ定義にそのようなキーワードヒントがないため、現在のプロパティPが読み取り専用でなく初期でないと判定され得る。他方では、現在のプロパティPがCons<F>データ型のテールプロパティであるとき、現在のプロパティPが、Cons<F>データ型のテールプロパティに関するプロパティ定義のそのようなキーワードヒントの存在によって読み取り専用で早期であることを判定し得る。
動作748において、現在のプロパティPが読み取り専用で初期である場合、具象データ型Cのデータ型定義グラフにエッジが追加され、エッジは、現在のノードNから現在のプロパティPのデータ型を表すノードまでである。エッジは「<=」要件で限定される。実施例では、現在のプロパティPがCons<F>データ型のテールプロパティであるとき、テールプロパティが読み取り専用で初期であるため、「<=」要件があるエッジがCons<F>データ型を表すノードからList<F>データ型を表すノードに追加されるであろう。
動作750において、現在のプロパティPが読み取り専用でなく初期でない場合、具象データ型Cのデータ型定義グラフにエッジが追加され、エッジは、現在のノードNから現在のプロパティPのデータ型を表すノードまでである。この場合、エッジは「<」要件で限定される。実施例では、現在のプロパティPがCons<F>データ型のヘッドプロパティであるとき、ヘッドプロパティが読み取り専用でなく初期でないため、「<」要件があるエッジがCons<F>データ型を表すノードからFデータ型を表すノードに追加されるであろう。
実施例では、Cons<F>データ型のヘッドプロパティ及びテールプロパティに対して動作724が行われた後、プロセスは動作716に戻り、未構築ノードリストが空であるかを判定する。ジェネリックデータ型F及びList<F>データ型の要素が未構築ノードリストに追加されたため、リストは空ではない。これらのノードは動作720でリストから除去される。動作722は、List<F>データ型を拡張するダイレクトサブデータ型Empty<F>を有するため、List<F>データ型によって行われる。ジェネリックデータ型Fを拡張するダイレクトサブデータ型がないため、ジェネリックデータ型Fに対して動作722は行われない。これらのデータ型には定義されたプロパティがないため、ジェネリックデータ型FまたはList<F>データ型に対して動作724は行われない。List<F>データ型に対して動作722を行った結果として、Empty<F>データ型のノードがグラフに追加され(動作734)、「可能性のある」要件があるエッジがList<F>データ型のノードからEmpty<F>データ型の新しいノードに追加される(動作736)。プロセスが再び動作716に戻るとき、Empty<F>データ型を表すノードの要素だけが未構築ノードリストにある。その要素は動作720で除去され、Empty<F>データ型に、それを拡張する任意のダイレクトサブデータ型または任意の定義されたプロパティがないため、動作722及び動作724はノードに対して行われない。
ここで図7Dを参照すると、具象データ型Cのデータ型チェックプロセスは、図7A、図7B、及び図7Cのサブプロセスに従って構築された全てのノードの要素が未構築ノードリストに再び追加された後の、図7Aの動作726から得られる未構築ノードのリストを継続する。実施例では、プロセスのこの時点における、Empty<F>、List<F>、F、及びCons<F>のデータ型のノードがある。これらのノードの要素は、未構築ノードリストに再び追加される。
動作752において、未構築ノードリストが空である(すなわち、任意の要素を含まない)であるかどうかを判定する。未構築ノードリストが空でない場合、ノードを構築するために、動作754、756、及び758は、未構築ノードリスト上の現在のノードに対して行われる。
動作754において、未構築ノードリスト上の現在のノードNが識別される。例えば、現在のノードNは、未構築ノードリストに最近追加された要素に対応するノードであり得る。
動作756において、現在のノードNを表す要素が未構築ノードリストから除去される。
動作760、762、764、766、及び768は、ソースコードで定義されているように、現在のノードNによって表されたデータ型が直接拡張する各スーパーデータ型に対して行われ得る。現在のノードNによって表されたデータ型は、トレイトベースの継承をサポートするオブジェクト指向プログラミング言語で通常可能になるように、スーパークラスまたは親クラスの意味でスーパーデータ型を直接拡張し得る。ソースプログラミング言語は、そのようなトレイトベースの継承をサポートし得る。
動作760、762、764、766、及び768の目的のために、現在のノードNを表したデータ型がソースコードで定義されているスーパーデータ型を直接拡張しない場合、そのデータ型は他の全てのデータ型の仮想のスーパーデータ型を表す仮想の「トップ」スーパーデータ型を直接拡張すると考えられる。したがって、少なくとも動作768は、トップスーパーデータ型を直接拡張すると考えられる現在のノードNごとに行われ、動作746及び動作766は、それぞれ、トップスーパーデータ型に対して一度行われる。
動作760において、現在のダイレクトスーパー型Tがジェネリックタイプである場合、現在のダイレクトスーパーデータ型Tは、現在のノードNによって表されたデータ型の型パラメーターを使用して変換される。
動作762において、現在のダイレクトサブデータ型Tのノードを表す要素が未構築ノードリスト上にあるかどうかを判定する。ない場合、動作764において、現在のダイレクトスーパーデータ型Tを表すノードに対して要素が作成され、動作766において、その要素が未構築ノードリストに追加される。いずれの場合も、動作768において、具象データ型Cのデータ型定義グラフにエッジが追加され、エッジは現在のダイレクトスーパーデータ型Tのノードから現在のノードNまでである。エッジは、現在のダイレクトスーパーデータ型Tのインスタンスであるデータオブジェクトが、現在のノードNによって表されたデータ型のインスタンスでもあり得るという点で「可能性のある」要件で限定される。
現在のノードNに対して動作754、756、及び758が行われた後、プロセスは動作752に戻り、他のノードに対応する未構築ノードリスト上の任意の残りの要素を検討する。動作752で未構築ノードリストに要素が残っていない場合、図7Dのフローチャートによって示されるサブプロセスが終了する。
実施例では、Cons<F>データ型のスーパーデータ型であるList<F>のノードが、具象データ型Cons<F>のグラフに既にある。動作768において、「可能性のある」要件がある、List<F>のノードからCons<F>データ型のノードまでグラフにエッジが追加される。また、List<F>データ型は、Empty<F>データ型のスーパーデータ型でもある。しかしながら、「可能性のある」要件があるエッジは、List<F>データ型を拡張するダイレクトサブデータ型を考慮するとき、図7Bの動作736において、List<F>のノードからEmpty<F>データ型のノードに既に追加されている。したがって、動作768において、エッジは再度追加する必要はない。また、動作768において、「可能性のある」要件があるエッジは、全てのノードのトップスーパーデータ型からジェネリックデータ型Fを表すノードに追加される。同様に、動作768において、「可能性のある」要件があるエッジは、トップスーパーデータ型ノードから、List<F>ジェネリックデータ型を表すノードに追加される。
ここで図7Eを参照すると、具象データ型Cのデータ型チェックプロセスは、図7A、図7B、図7C、及び図7Dのフローチャートによって示されるサブプロセスの実行が具象データ型Cに対して行われた後にそれらが存在するときの、具象データ型Cのデータ型定義グラフのノード及びエッジが継続する。
具象データ型Cのグラフを構築するこの時点において、グラフはデータ型ノードで構成されているが、リミットノードは構成されていない。グラフのデータ型ノードは、図7A、図7B、図7C、及び図7Dに関して上記に説明したように、具象データ型Cのダイレクトサブデータ型、具象データCのプロパティのデータ型、及びそれらのダイレクトサブデータ型のスーパーデータ型、それらのプロパティデータ型、ならびに具象データ型Cに基づいて作成される。
リミットノードは、非制限データ型ノードをグループ化するために、コンパイラによって具象データ型Cのデータ型定義グラフに追加され得る。このコンテキストにおける非制限データ型ノードは、(a)コンパイル時に全てのサブデータ型がコンパイラに知られているわけではないという意味での非クローズデータ型、または(b)ジェネリックデータ型、のいずれか一方のデータ型を表すノードである。
動作770は、データ型ノードであるグラフの各ノードに対して行われ得る。動作772において、現在のデータ型ノードNによって表されたデータ型が非制限であるかどうかを判定する。「NO」の場合、動作774、776、778、及び780は現在のデータ型ノードNに対して行われない。「YES」の場合、動作774、776、778、及び780は現在のデータ型ノードNに対して行われる。実施例では、Top、Empty<F>、List<F>、F、及びCons<F>データ型のノードは、グラフのデータ型ノードである。このうち、Empty<F>、List<F>、F、及びCons<F>データ型のノードは、ジェネリックデータ型であるため制限がない。
動作774において、現在のデータ型ノードNによって表されたデータ型の変換されたスーパーデータ型であるデータ型の「YES」セットが判定される。
動作776において、現在のデータ型ノードNによって表されたデータ型に対する制限を参照しない場合がある「NO」セットが判定される。
動作778において、現在のYESセット及び現在のNOセットの組み合わせに関する具象データ型CのグラフにリミットノードLNが追加されていない場合、リミットノードLNが組み合わせ用に作成され、グラフに追加される。
動作780において、「可能性のある」要件があるエッジが、現在のデータ型を表すノードNから現在のYES及びNOの組み合わせに対するリミットノードLNまでグラフに追加される。
ここで図7Fを参照すると、具象データ型Cのデータ型チェックプロセスは、図7A、図7B、図7C、図7D、及び図7Eのフローチャートによって示されるサブプロセスの実行が具象データ型Cに対して行われた後にそれらが存在するときの、具象データ型Cのデータ型定義グラフのノード及びエッジが継続する。
動作782は、グラフの各リミットノードに対して行われる。そして、グラフの各リミットノードに対して、動作784は、グラフのデータ型ノードのそれぞれに対して行われる。
動作786において、現在のノードNのデータ型が、現在のリミットノードLNに対するYESセット(図7Eの動作774)の各データ型のサブデータ型であるかどうかを判定する。そうである場合、プロセスは動作788に進む。そうでない場合、図7Fのサブプロセスが終了する。
動作788において、現在のリミットノードLNのNOセット(図7Eの動作776)の任意のデータ型が、現在のノードNのデータ型のサブデータ型であるかどうかを判定する。そうである場合、図7Fのサブプロセスは終了する。そうでない場合、動作790において、「<」未満の要件がある現在のリミットノードLNから現在のデータ型ノードNまでのエッジがグラフに作成される。
ここで図7Gを参照すると、具象データ型Cのデータ型チェックプロセスは、図7A、図7B、図7C、図7D、図7E、及び図7Fのフローチャートによって示されるサブプロセスの実行が具象データ型Cに対して行われた後にそれらが存在するときの、具象データ型Cのデータ型定義グラフのノード及びエッジが継続する。
動作792において、セットCHAINはエッジの空のセットになるように初期化される。
動作794において、セットVISITEDはノードの空のセットになるように初期化される。
動作796において、図7A、図7B、図7C、図7D、図7E、及び図7Fのサブプロセスに従ってデータ型定義グラフが生成された具象データ型Cから開始するサブプロセスが呼び出される。サブプロセスはグラフの矛盾を探すが、図7Hを参照して下記により詳細に説明される。
動作798において、タイプチェックプロセス中に検出された任意の問題が報告される。例えば、ソースプログラミング言語で書かれたソースコードで識別された潜在的な参照サイクルごとに、コマンドラインインターフェースもしくはグラフィカルユーザーインターフェース等のコンピューターユーザーインターフェースへの出力、または潜在的な参照サイクルの人間可読な記述を提供するファイルもしくはデータベースへの出力を提供できる。出力は、例えば、「'Thing'型の値は、そのプロパティ'otherThing'を用いてそれ自体を参照し得る。'aThing.otherThing=aThing;'は、参照サイクルを生じさせるであろう。」のようなテキストになり得る。出力は、潜在的な参照サイクルが検出された具象データ型Cのデータ型定義グラフのノードまたはエッジに関連付けられたメタデータから導出され得る。また、出力は、潜在的な参照サイクルを回避する等の問題を修正する方法も提案し得る。出力は統合開発環境(IDE)プログラムに入力され、自動的に、または人間のプログラマーによって選択もしくは承認された提案に基づいてソースコードを変更し得る。
ここで図7Hを参照すると、図7Gのサブプロセスの動作796で呼び出された矛盾のサブプロセス探索のフローチャートである。サブプロセスは、現在のノードNで呼び出される。また、サブプロセスは、再帰的であり得る、または非再帰的であるが同等の方法で実施され得る。矛盾のサブプロセス探索の最初の呼び出しでは、現在のノードNは、データ型定義グラフが生成された具象データ型Cを表すグラフのノードである。
動作800において、現在のノードNがVISITEDセットにあるかどうかを判定する。現在のノードNがVISITEDセットにある場合、矛盾のサブプロセス探索は動作802に進む。
動作802において、CHAINセットが「<」要件があるエッジを含むかどうかを判定する。そうである場合、サブプロセスは動作804に進む。
動作804において、具象データ型Cに関する潜在的な参照サイクル問題が報告される。例えば、CHAINセットのエッジのセットを使用して問題を報告し、人間可読な問題の説明を導出し得る。
動作802において、「<」要件があるCHAINセットにエッジがない場合、動作806において、現在のノードNがVISITEDセットから除去され、矛盾のサブプロセス探索の現在の呼び出しが戻る/終了する。
動作800において、現在のノードNがVISITEDセットにない場合、動作808において、現在のノードNがVISITEDセットに追加される。
動作810は、現在のノードNからのグラフの各エッジに対して行われる。
動作812において、CHAINセットが空である場合、または現在のエッジEが「<」もしくは「<=」の要件がある場合、動作814において、現在のエッジEがCHAINセットに追加され、矛盾のサブプロセスの探索が再帰的に呼び出され(816)、現在のエッジEのグラフのターゲットノードを再帰呼び出しへの入力ノードとして提供し、再帰呼び出しが戻る/終了するとき、現在のエッジEは、動作806に進む前にCHAINセットの最後から除去される(818)。動作812において、CHAINが空でない場合、または現在のエッジEに「<」もしくは「<=」の要件がない場合、サブプロセスは動作806に進む。
利点
証明可能な非循環オブジェクトには多くの利点がある。1つは、ランタイムにオブジェクトをタイムリーに割当解除するには、参照カウントで十分である。別のものは、特定のランタイムメタ操作が簡素化され、信頼性が向上している。そのランタイムメタ操作は、
・ランタイムに2つのオブジェクトを比較して、それらが構造的に等しいかどうかを確認すること(すなわち、2つのオブジェクトが、対応するプロパティ自体が構造的に同等である同じタイプのオブジェクトであると判定すること)と、
・オブジェクトのパーツがメモリでどのように配置されているかに関係なく、ランタイムにオブジェクトのフィンガープリントを取得することと、
・別のコンピューティングプロセスまたはコンピューターに伝送するためにオブジェクトをシリアル化することと、
・オブジェクトを、問題をデバッグしている人間のプログラマーに示すことができる診断フォームに変換することと、を含む。
また、参照サイクルフリーのデータ型定義は、分散コンピューティングシステムにも利点がある。例えば、分散ガベージコレクションは、多くのプロパティ値が、そのプロパティ値を含むオブジェクトとは異なるシステムのコンピューティングノード上にあるとき、分散コンピューティングプロセス間で往復する実質的なプロセス間通信(例えば、データネットワーク)メッセージングを必要とし得る。一方、全てのデータ型が非循環である場合、分散ガベージコレクションを分散参照カウントに置換でき、参照カウントの更新をより少ない数の小さなメッセージにバッチ処理して、そのメッセージはシステムのノードで作動でき、ノードにおけるコンピューティングプロセスによって待機時間が少なくなる。
基本コンピューティングデバイス
本技術は、少なくとも1つのコンピューティングデバイスによって実装され得る。2つ以上のコンピューティングデバイスによる場合、本技術は、パケットデータネットワーク等のネットワークを使用して一緒に結合されたコンピューティングデバイスの組み合わせを使用して全体または部分的に実装され得る。本技術の実施態様で使用されるコンピューティングデバイスは、本技術の一部もしくは全てを行うようにハードワイヤードされ得る、または、本技術の一部もしくは全てを行うように永続的にプログラムされる、少なくとも1つの特定用途向け集積回路(ASIC)もしくはフィールドプログラマブルゲートアレイ(FPGA)等のデジタル電子デバイスを含み得る、または、ファームウェア、メモリ、他のストレージ、もしくはそれらの組み合わせにおけるプログラム命令に従って本技術の一部もしくは全てを行うようにプログラムされた少なくとも1つの汎用ハードウェアプロセッサを含み得る。本技術の実施態様に使用されるコンピューティングデバイスは、また、カスタムのハードワイヤードロジック、ASIC、またはFPGAとカスタムプログラミングを組み合わせて、本技術の一部または全ても達成し得る。本技術の実施態様で使用されるコンピューティングデバイスは、サーバーコンピューティングデバイス、ワークステーションコンピューティングデバイス、パーソナルコンピューティングデバイス、ポータブルコンピューティングデバイス、ハンドヘルドコンピューティングデバイス、モバイルコンピューティングデバイス、または本技術の一部もしくは全てを実装するためのハードワイヤードロジックもしくはプログラムロジックを組み込む任意の他のコンピューティングデバイスであり得る。
図8は、本技術の実施態様で使用され得る例示的な基本的なコンピューティングデバイスのブロック図である。図8の例では、コンピューティングデバイス800、ならびにハードウェア、ソフトウェア、またはハードウェア及びソフトウェアの組み合わせにおける本技術の一部または全てを実施するための命令は、本開示でコンピューターアーキテクチャ及びコンピューティングデバイスの実施態様について通信することに関して関係する当業者によって一般的に使用するのと同じ詳細レベルで、例えばボックス及び円として概略的に表される。
コンピューティングデバイス800は、電子信号経路を通じてコンピューティングデバイス800のコンポーネント間で情報または命令を通信するためのバスまたは他の通信機構を含み得る入出力(I/O)サブシステム802を含む。I/Oサブシステム802は、I/Oコントローラ、メモリコントローラ、及び少なくとも1つのI/Oポートを含み得る。電子信号経路は、図面では、例えば、線、一方向の矢印、または双方向の矢印として概略的に表される。
少なくとも1つのハードウェアプロセッサ804は、情報及び命令を処理するためにI/Oサブシステム802に結合される。ハードウェアプロセッサ804は、例えば、汎用マイクロプロセッサもしくはマイクロコントローラ、または組み込みシステムもしくはグラフィックス処理ユニット(GPU)もしくはデジタル信号プロセッサもしくはARMプロセッサ等の専用マイクロプロセッサを含み得る。プロセッサ804は、統合算術論理演算ユニット(ALU)を備え得る、または別個のALUに結合され得る。
コンピューティングデバイス800は、プロセッサ804によって実行されるデータ及び命令を電子的にデジタル的に記憶するためにI/Oサブシステム802に結合される、メインメモリ等の1つ以上のメモリ806のユニットを含む。メモリ806は、様々な形態のランダムアクセスメモリ(RAM)または他の動的ストレージ等の揮発性メモリを含み得る。メモリ806は、また、プロセッサ804によって実行される命令の実行中、テンポラリ変数または他の中間情報を記憶するために使用され得る。そのような命令は、プロセッサ804にアクセス可能な非一時的ストレージ媒体に記憶されるとき、コンピューティングデバイス800を、命令で指定された動作を行うようにカスタマイズされる専用マシンにレンダリングさせることができる。
コンピューティングデバイス800は、さらに、プロセッサ804のための情報及び命令を記憶するために、I/Oサブシステム802に結合された読み取り専用メモリ(ROM)808または他の静的ストレージ等の不揮発性メモリを含む。ROM808は、消去可能PROM(EPROM)または電気的消去可能PROM(EEPROM)等の様々な形式のプログラマブルROM(PROM)を含み得る。永続ストレージ810のユニットは、フラッシュメモリ、またはソリッドステートストレージ、磁気ディスク、またはCD-ROMもしくはDVD-ROM等の光ディスク等の様々な形式の不揮発性RAM(NVRAM)を含み得、情報及び命令を記憶するためのI/Oサブシステム802に結合され得る。ストレージ810は、プロセッサ804によって実行されるとき、コンピューター実施方法に本技術の一部または全てを実行させる命令及びデータを記憶するために使用され得る非一時的コンピューター可読媒体の例である。
メモリ806、ROM808、またはストレージ810にある命令は、モジュール、方法、オブジェクト、関数、ルーチン、または呼び出しとして編成される1つ以上の命令セットを含み得る。命令は、1つ以上のコンピュータープログラム、オペレーティングシステムサービス、またはモバイルアプリを含むアプリケーションプログラムとして編成され得る。命令は、オペレーティングシステムまたはシステムソフトウェア;マルチメディア、プログラミング、または他の機能をサポートする1つ以上のライブラリ;TCP/IP、HTTP、または他の通信プロトコルを実装するためのデータプロトコル命令またはスタック;HTML、XML、JPEG、MPEG、またはPNGを使用してコード化されたファイルを解釈及びレンダリングするためのファイル処理命令;グラフィカルユーザーインターフェース(GUI)、コマンドラインインターフェース、またはテキストユーザーインターフェースのコマンドをレンダリングまたは解釈するためのユーザーインターフェース命令;オフィススイート、インターネットアクセスアプリケーション、設計及び製造アプリケーション、グラフィックスアプリケーション、オーディオアプリケーション、ソフトウェアエンジニアリングアプリケーション、教育アプリケーション、ゲームまたは他のアプリケーション等のアプリケーションソフトウェアを含み得る。その命令は、ウェブサーバー、ウェブアプリケーションサーバー、またはウェブクライアントを実施し得る。命令は、プレゼンテーション層、アプリケーション層、及び構造化照会言語(SQL)またはNoSQLを使用するリレーショナルデータベースシステム、オブジェクトストア、グラフデータベース、フラットファイルシステム、または他のデータストレージ等のデータストレージ層として編成され得る。
コンピューティングデバイス800は、I/Oサブシステム802を介して、少なくとも1つの出力デバイス812に結合され得る。出力デバイス812は、デジタルコンピューターディスプレイであり得る。使用され得るディスプレイの例は、タッチスクリーンディスプレイまたは発光ダイオード(LED)ディスプレイまたは液晶ディスプレイ(LCD)、または電子ペーパーディスプレイを含む。コンピューティングデバイス800は、表示デバイスの代わりに、またはそれに加えて、他のタイプの出力デバイス812を含み得る。他の出力デバイス812の例は、プリンタ、チケットプリンタ、プロッタ、プロジェクタ、サウンドカードまたはビデオカード、スピーカー、ブザーまたは圧電デバイスまたは他の可聴デバイス、ランプまたはLEDまたはLCDインジケータ、触覚デバイス、アクチュエーターまたはサーボを含む。
入力デバイス814は、信号、データ、コマンド選択、またはジェスチャをプロセッサ804に通信するために、I/Oサブシステム802に結合され得る。入力デバイス814の例は、タッチスクリーン、マイクロフォン、静止画及びビデオデジタルカメラ、英数字及び他のキー、キーパッド、キーボード、グラフィックタブレット、イメージスキャナ、ジョイスティック、時計、スイッチ、ボタン、ダイヤル、スライド、あるいは力センサー、運動センサー、熱センサー、加速度計、ジャイロスコープ、慣性測定ユニット(IMU)センサー等の様々なタイプのセンサー、または、携帯電話もしくはWi-Fi(登録商標)等の無線、無線周波数(RF)トランシーバーもしくは赤外線(IR)トランシーバー及び全地球測位システム(GPS)トランシーバー等の様々なタイプのトランシーバーを含む。
別のタイプの入力デバイスは制御デバイス816であり、入力機能の代わりに、または入力機能に加えて、カーソル制御、または表示画面上のグラフィカルインターフェースにおけるナビゲーション等の他の自動制御機能を行い得る。制御デバイス816は、方向情報及びコマンド選択をプロセッサ804に伝達し、ディスプレイ812上のカーソルの動きを制御するための、タッチパッド、マウス、トラックボール、またはカーソル方向キーであり得る。入力デバイスは、デバイスが平面内の位置を指定することを可能にする2つの軸、すなわち、第1の軸(例えばx)及び第2の軸(例えばy)の少なくとも2つの自由度を有し得る。別のタイプの入力デバイスは、ジョイスティック、ワンド、コンソール、ステアリングホイール、ペダル、ギアシフト機構、または他のタイプの制御デバイス等、有線、無線、または光学式の制御デバイスである。入力デバイス814は、ビデオカメラ及び深度センサー等の複数の異なる入力デバイスの組み合わせを含み得る。
コンピューティングデバイス800は、出力デバイス812、入力デバイス814、及び制御デバイス816のうちの1つ以上が省略されたモノのインターネット(IoT)デバイスまたは他のコンピューティング機器を備え得る。入力デバイス814は、1つ以上のカメラ、動作検出器、温度計、マイクロフォン、地震検出器、他のセンサーまたは検出器、測定デバイスまたはエンコーダーを備え得、出力デバイス812は、単線LEDディスプレイまたは単線LCDディスプレイ等の専用ディスプレイ、1つ以上のインジケータ、ディスプレイパネル、メーター、バルブ、ソレノイド、アクチュエーター、またはサーボを備え得る。
コンピューティングデバイス800がモバイルまたはポータブルコンピューティングデバイスであるとき、入力デバイス814は、複数のGPS衛星を三角測量し、コンピューティングデバイス800の地球物理的場所の緯度経度値等の地理位置情報または位置データを判定及び生成することが可能であるGPSモジュールに結合された全地球測位システム(GPS)受信機を備え得る。出力デバイス812は、位置報告パケット、通知、パルス信号もしくはハートビート信号、またはコンピューティングデバイス800の位置を指定する他の反復データ伝送を、単独で、またはホスト824もしくはサーバー830に向けられた他のアプリケーション特有のデータと組み合わせて生成するためのハードウェア、ソフトウェア、ファームウェア、及びインターフェースを含み得る。
コンピューティングデバイス800は、カスタマイズされたハードワイヤードロジック、少なくとも1つのASICもしくはFPGA、ファームウェア、またはプログラム命令もしくはロジックを使用して、本技術の一部または全てを実装し得、プログラム命令またはロジックは、コンピューティングデバイス800と組み合わせてロード及び使用されるとき、または実行されるとき、コンピューティングデバイス800を専用マシンとして動作させるように、起動させるまたはプログラムする。
コンピューティングデバイス800によって行われた技術は、メインメモリ806に含まれる少なくとも1つの命令の少なくとも1つのシーケンスを実行するプロセッサ804に応答して行われ得る。そのような命令は、ストレージ810等の別のストレージ媒体からメインメモリ806に読み取られ得る。メインメモリ806に含まれる一連の命令を行うと、プロセッサ804は本技術の一部または全てを行う。ハードワイヤード回路は、ソフトウェア命令の代わりに、またはソフトウェア命令と組み合わせて使用され得る。
本明細書で使用される「ストレージ媒体」という用語は、機械を特定の方式で動作させるデータまたは命令を記憶する任意の非一時的コンピューター可読媒体を指す。そのようなストレージ媒体は、不揮発性媒体または揮発性媒体を含み得る。不揮発性媒体は、例えば、ストレージ810等の光ディスクまたは磁気ディスクを含む。揮発性メディアは、メモリ806等のダイナミックメモリを含む。ストレージ媒体の一般的な形式は、例えば、ハードディスク、ソリッドステートドライブ、フラッシュドライブ、磁気データストレージ媒体、任意の光学的または物理的データストレージ媒体、メモリチップ等を含む。
ストレージメディアは伝送メディアとは異なるが、伝送メディアと組み合わせて使用され得る。伝送メディアは、記憶メディア間の情報の転送に関与する。例えば、伝送媒体は、同軸ケーブル、銅線、及び光ファイバーを含み、I/Oサブシステム802のバスを構成するワイヤを含む。伝送媒体は、また、電波及び赤外線データの通信中に生成されたもの等の音響波または光波の形態をとることもできる。
様々な形態の媒体は、実行のために少なくとも1つの命令の少なくとも1つのシーケンスをプロセッサ804に搬送することに関与し得る。例えば、命令は最初にリモートコンピューターの磁気ディスクまたはソリッドステートドライブに保存され得る。リモートコンピューターは、その命令を動的メモリにロードし、モデムを使用する光ファイバーまたは同軸ケーブルまたは電話回線等の通信リンクを通じて命令を送信できる。コンピューティングデバイス800に対してローカルにあるモデムまたはルータは、通信リンク上でデータを受信し、そのデータをコンピューティングデバイス800によって読み取られるように変換できる。例えば、無線周波数アンテナまたは赤外線検出器等の受信機は、無線または光信号で搬送されるデータを受信でき、適切な回路は、データをバス上に配置する等、データをI/Oサブシステム802に提供できる。I/Oサブシステム802はデータをメモリ806に搬送し、プロセッサ804はメモリ806から命令を取り出して実行する。メモリ806によって受信された命令は、オプションで、プロセッサ804による実行の前または後のいずれか一方で、ストレージ810に記憶され得る。
コンピューティングデバイス800は、また、バス802に結合された通信インターフェース818も含む。通信インターフェース818は、ネットワーク822またはインターネット上のパブリックまたはプライベートクラウド等の少なくとも1つの通信ネットワークに直接的または間接的に接続されるネットワークリンク820に結合する双方向データ通信を提供する。例えば、通信インターフェース818は、イーサネット(登録商標)ネットワーキングインターフェース、総合サービスデジタルネットワーク(ISDN(登録商標))カード、ケーブルモデム、衛星モデム、または対応する通信回線のタイプ(例えばイーサネットケーブルもしくは任意の種類のメタルケーブル、または光ファイバー回線もしくは電話回線)へのデータ通信接続を提供するモデム等であり得る。ネットワーク822は、ローカルエリアネットワーク(LAN)、ワイドエリアネットワーク(WAN)、キャンパスネットワーク、インターネットワーク、またはそれらの任意の組み合わせを広く表す。通信インターフェース818は、互換性のあるLANへのデータ通信接続を提供するLANカード、またはセルラー無線電話無線ネットワーキング規格に従ってセルラーデータを送信もしくは受信するために有線で接続されるセルラー無線電話インターフェース、または衛星無線ネットワーキング規格に従ってデジタルデータを送信もしくは受信するために有線で接続される衛星無線インターフェースを備え得る。任意のそのような実施態様では、通信インターフェース618は、様々なタイプの情報を表すデジタルデータストリームを搬送する信号経路を通じて、電気信号、電磁信号、または光信号を送信及び受信する。
ネットワークリンク820は、通常、例えば衛星、セルラー、Wi-Fi(登録商標)、またはBLUETOOTH(登録商標)技術を使用して、電気通信、電磁通信、または光データ通信を直接、または少なくとも1つのネットワークを経由して他のデータデバイスに提供する。例えば、ネットワークリンク820は、ネットワーク822を経由して、ホストコンピューター824への接続を提供し得る。
さらに、ネットワークリンク820は、ネットワーク822を経由した接続、またはインターネットサービスプロバイダ(ISP)826が運用するインターネットワーキングデバイス及び/もしくはコンピューターを介した他のコンピューティングデバイスへの接続を提供し得る。ISP826は、インターネット828として表された世界規模のパケットデータ通信ネットワークを経由してデータ通信サービスを提供する。サーバーコンピューター830はインターネット828に接続され得る。サーバー830は、ハイパーバイザーの有無にかかわらず任意のコンピューター、データセンター、仮想マシンもしくは仮想コンピューティングインスタンス、またはDOCKERもしくはKUBERNETES等のコンテナ化されたプログラムシステムを実行するコンピューターを広く表す。サーバー830はデジタル電子サービスを表し得、これは、2つ以上のコンピューターまたはインスタンスを使用して実装され、ウェブサービスリクエスト、HTTPペイロードのパラメーターを伴うユニフォームリソースロケータ(URL)文字列、APIコール、アプリサービスコール、または他のサービスコールを伝送することによってアクセス及び使用される。
コンピューティングデバイス800及びサーバー830は、他のコンピューター、処理クラスター、サーバーファーム、あるいはタスクを協働して行う、またはアプリケーションもしくはサービスを協働して実行するコンピューターの他の組織を含む分散コンピューティングシステムの要素を形成し得る。サーバー830は、モジュール、方法、オブジェクト、関数、ルーチン、または呼び出しとして編成される1つ以上の命令のセットを含み得る。命令は、1つ以上のコンピュータープログラム、オペレーティングシステムサービス、またはモバイルアプリを含むアプリケーションプログラムとして編成され得る。命令は、オペレーティングシステム及び/またはシステムソフトウェア;マルチメディア、プログラミング、または他の機能をサポートする1つ以上のライブラリ;TCP/IP、HTTP、または他の通信プロトコルを実装するためのデータプロトコル命令またはスタック;HTML、XML、JPEG、MPEG、またはPNGを使用してコード化されたファイルを解釈またはレンダリングするためのファイル形式処理命令;グラフィカルユーザーインターフェース(GUI)、コマンドラインインターフェース、またはテキストユーザーインターフェースのコマンドをレンダリングまたは解釈するためのユーザーインターフェース命令;オフィススイート、インターネットアクセスアプリケーション、設計及び製造アプリケーション、グラフィックスアプリケーション、オーディオアプリケーション、ソフトウェアエンジニアリングアプリケーション、教育アプリケーション、ゲームまたは他のアプリケーション等のアプリケーションソフトウェアを含み得る。サーバー830は、プレゼンテーション層、アプリケーション層、及び構造化照会言語(SQL)またはNoSQLを使用するリレーショナルデータベースシステム、オブジェクトストア、グラフデータベース、フラットファイルシステム、または他のデータストレージ等のデータストレージ層をホストするウェブアプリケーションサーバーを含み得る。
コンピューティングデバイス800は、ネットワーク、ネットワークリンク820、及び通信インターフェース818を経由して、メッセージを送信し、プログラムコードを含むデータ及び命令を受信できる。インターネットの例では、サーバー830は、インターネット828、ISP826、ローカルネットワーク822、及び通信インターフェース818を経由して、アプリケーションプログラムに対して要求されたコードを伝送し得る。受信されたコードは、受信されたときにプロセッサ804によって実行され得る、または後で実行するためにストレージ810または他の不揮発性ストレージに記憶され得る。
基本的なソフトウェアシステム
図9は、図8のコンピューティングデバイス800の動作を制御するために採用され得る例示的な基本ソフトウェアシステム900のブロック図である。ソフトウェアシステム900、ならびにその接続、関係、及び機能を含むそのコンポーネントは、単なる例であることを意図しており、本技術の実装を限定することを意図するものではない。本技術を実装するのに適した他のソフトウェアシステムは、異なる接続、関係、機能を備えたコンポーネントを含む、異なるコンポーネントを有し得る。
ソフトウェアシステム900は、コンピューターシステム800の動作を指示するために提供される。システムメモリ(RAM)806及び固定ストレージ(例えば、ハードディスクまたはフラッシュメモリ)810に記憶され得るソフトウェアシステム900は、カーネルまたはオペレーティングシステム(OS)910を含む。
OS910は、902-1、902-2、902-3...902-Nとして表されたプロセスの実行の管理、メモリ割り当て、ファイル入出力(I/O)、デバイスI/Oを含むコンピューター操作の低レベルの態様を管理する。1つ以上のアプリケーションプログラムは、システム900による1つ以上のプロセスとして実行するために「ロード」され得る(例えば、固定ストレージ810からメモリ806に転送され得る)。また、コンピューティングデバイス800での使用を意図としたアプリケーションまたは他のソフトウェアは、例えば、インターネットの場所(例えば、ウェブサーバー、アプリストア、または他のオンラインサービス)からダウンロード及びインストールするために、ダウンロード可能なコンピューター実行可能命令のセットとしても記憶され得る。
アプリケーションプログラム命令の実行は、実行中であり、プログラムコード及びその現在のアクティビティから成るコンピュータープログラムのインスタンスの形式でプロセス(例えば、902-2)を実施し得る。オペレーティングシステム(OS)によって、プロセス(例えば、902-3)は、命令を同時に実行する複数の実行スレッドで構成され得る。このコンテキストでは、コンピュータープログラムは命令のパッシブなコレクションである一方、プロセス(例えば、902-1)はそれらの命令の実際の実行であり得る。いくつかのプロセス(例えば、902-1及び902-2)は同じプログラムに関連付けられ得る。例えば、同じプログラムのいくつかのインスタンスを開くということは、多くの場合、2つ以上のプロセスが実行されていることを意味する、または、最初は、単一のプロセスとして起動するプログラムは、その後、追加のプロセスをスポーン(例えば、フォーク)し得る。
OS910は、プロセス902-1、902-2、902-3...902-Nがプロセッサ804を共有することを可能にするようにマルチタスクを実施し得る。プロセッサ804のそれぞれまたはプロセッサのコアは一度に単一タスクを実行するが、コンピューティングデバイス800は、各プロセッサが、各タスクが終了することを待機する必要がなく、実行中であるタスク間を切り替えることを可能にするマルチタスクを実施するようにプログラムされ得る。タスクが入出力操作を行うとき、タスクが切り替え可能であることを示すとき、またはハードウェア割り込み時に、切り替えは行われ得る。タイムシェアリングは、コンテキストの切り替えを急速に行って、複数のプロセスが同時に起こるかのように見せることを提供することによって、対話型ユーザーアプリケーションの高速応答が可能になるように実施され得る。セキュリティ及び信頼性のために、OS910は独立したプロセス間の直接通信を防止し得、厳密に仲介及び制御されたプロセス間通信機能を提供する。
いくつかの例では、プロセス902-1、902-2、902-3...902-N、及びそれらのプロセスが実施するアプリケーションプログラムは、アプリケーションコンテナ940内で実行され得る。アプリケーションコンテナは、概して、OS910の動作モードであり、OS910では、複数の分離されたユーザー空間インスタンスの存在をOS910で実行することを可能にする。アプリケーションコンテナ940は、そのようなインスタンスの一例である。インスタンス自体は、代替として、ゾーン、仮想プライベートサーバー、パーティション、仮想環境、仮想カーネル、またはジェイルと呼ばれることもある。アプリケーションコンテナは、CPU時間及びストレージメディア空間等の有限のハードウェアコンピューティングリソースをインスタンス間で割り当てることができるメカニズムを提供する。
ソフトウェアシステム900は、グラフィカル(例えば、「ポイントアンドクリック」または「タッチジェスチャ」)方式でユーザーコマンド及びデータを受信するためのグラフィカルユーザーインターフェース(GUI)915を含む。次に、これらの入力は、オペレーティングシステム910またはプロセス902-1、902-2、902-3...902-Nからの命令に従ってシステム900によって処理され得る。次に、GUI915は、OS910及びプロセス902-1、902-2、902-3...902-N、902から操作の結果を表示する役割も果たし、その後、ユーザーは追加の入力を供給し得る、またはセッションを終了し得る(例えば、ログオフする)。
OS910は、コンピューティングデバイス800のベアハードウェア920(例えば、プロセッサ804)で直接実行できる。代替として、ハイパーバイザーまたは仮想マシンモニター(VMM)930は、ベアハードウェア920とOS910との間に挿入され得る。この構成では、VMM930は、OS910とコンピューティングデバイス800のベアハードウェア920との間のソフトウェア「クッション」または仮想化層として機能する。
VMM930は、1つ以上の仮想マシンインスタンス(「ゲストマシン」)をインスタンス化して実行する。各ゲストマシンは、OS910等の「ゲスト」オペレーティングシステムと、ゲストオペレーティングシステムで実行するように設計されたアプリケーション902等の1つ以上のアプリケーションとを備える。VMM930は、ゲストオペレーティングシステムを仮想オペレーティングプラットフォームに提示し、ゲストオペレーティングシステムの実行を管理する。
いくつかの例では、VMM930は、ゲストオペレーティングシステムがコンピューティングデバイス800のベアハードウェア920で直接起動しているかのように起動することが可能になり得る。これらの例では、ベアハードウェア920で直接実行するように構成された同じバージョンのゲストオペレーティングシステムは、また、変更または再構成なしで、VMM930で実行され得る。言い換えれば、VMM930は、いくつかの例では、完全なハードウェア及びCPUの仮想化をゲストオペレーティングシステムに提供し得る。
他の例では、ゲストオペレーティングシステムは、VMM930で実行するように特別に設計または構成され得る。これらの例では、ゲストオペレーティングシステムは、仮想マシンモニターで実行されていることを「認識」する。言い換えれば、VMM930は、いくつかの例では、パラ仮想化をゲストオペレーティングシステムに提供し得る。
クラウドコンピューティング
本技術は、「クラウドコンピューティング」環境で実装され得る。「クラウドコンピューティング」という用語は、概して、本明細書では、コンピューターネットワーク、サーバー、ソフトウェアアプリケーション、及びサービス等のコンピューティングリソースの共有プールへのオンデマンドアクセスを可能にし、最小の管理労力または最小のサービスプロバイダーとのインタラクションで、リソースの急速なプロビジョニング及びリリースを可能にする、コンピューティングモデルを表すために使用される。
クラウドコンピューティング環境(クラウド環境またはクラウドと呼ばれることもある)は、異なる要件に最適になるように様々な異なる方法で実装できる。例えば、パブリッククラウド環境では、下層のコンピューティングインフラストラクチャは、そのクラウドサービスを他の組織または一般の人々が利用可能になる組織によって所有される。対照的に、プライベートクラウド環境は、概して、単一の組織による、または単一の組織内での使用だけを意図としている。コミュニティクラウドは、コミュニティ内のいくつかの組織によって共有されることを意図とする一方、ハイブリッドクラウドは、データ及びアプリケーションのポータビリティによって一緒にバインドされた2つ以上のタイプのクラウド(例えば、プライベート、コミュニティ、パブリック)を含む。
概して、クラウドコンピューティングモデルは、以前は組織独自の情報技術部門によって提供されていた場合があるその責任の一部を、代わりに、コンシューマー(クラウドのパブリック/プライベートの性質に応じて、組織内または組織外のいずれか一方にいるコンシューマー)による使用のために、クラウド環境内のサービス層として提供することを可能にする。特定の実施態様に応じて、各クラウドサービス層によって、または各クラウドサービス層内で提供されたコンポーネントまたは機能の正確な定義は異なる可能性があるが、一般的な例は、コンシューマーがクラウドインフラストラクチャ上で実行されているソフトウェアアプリケーションを使用するサービス型ソフトウェア(SaaS)を含む一方、SaaSプロバイダーは下層のクラウドインフラストラクチャ及びアプリケーションを管理または制御する。サービス型プラットフォーム(PaaS)では、コンシューマーが、PaaSプロバイダーによってサポートされたソフトウェアプログラミング言語及び開発ツールを使用して、その独自のアプリケーションを開発、展開し、そうでなければ制御することができる一方、PaaSプロバイダーはクラウド環境の他の態様(例えば、ランタイム実行環境の下の全てのもの)を管理または制御する。サービス型インフラストラクチャ(IaaS)では、コンシューマーが、任意のソフトウェアアプリケーション、及び/または準備処理、ストレージ、ネットワーク、及び他の基本コンピューティングリソースを展開及び起動できる一方、IaaSプロバイダーは、下層の物理クラウドインフラストラクチャ(例えば、オペレーティングシステム層の下の全てのもの)を管理または制御する。サービス型データベース(DBaaS)では、コンシューマーはクラウドインフラストラクチャ上で実行されているデータベースサーバーまたはデータベース管理システムを使用する一方、DbaaSプロバイダーは、1つ以上のデータベースサーバーを含む、下層のクラウドインフラストラクチャ、アプリケーション、サーバーを管理または制御する。
本開示の他の態様
文脈上明確に別段の指示がない限り、「または(or)」という用語は、(排他的な意味ではなく)包括的な意味で、前述の明細書及び添付の特許請求の範囲で使用され、したがって、例えば、要素のリストを接続するために使用されるとき、「または(or)」という用語は、そのリストにある要素の1つ、一部、または全部を意味する。
文脈上明確に別段の指示がない限り、「備える(comprising)」、「含む(including)」、「有する(having)」、「に基づく(based on)」、「含む(encompassing)」等の用語は、前述の明細書及び添付の特許請求の範囲で無制限に使用され、追加の要素、機能、行為、または動作を除外するものではない。
文脈上明確に別段の指示がない限り、語句「X、Y、及びZのうちの少なくとも1つ」等の接続的言語は、項目、用語等がX、Y、もしくはZ、またはそれらの組み合わせであり得ると伝えることを理解されたい。したがって、そのような接続的言語は、初期設定で、Xの少なくとも1つ、Yの少なくとも1つ、及びZの少なくとも1つがそれぞれ存在するという含意が必要であることを意図していない。
文脈上明確に別段の指示がない限り、前述の発明を実施するための形態及び添付の特許請求の範囲で使用されるように、単数形「a」、「an」、及び「the」は、同様に複数形も含むことが意図される。
文脈上明確に別段の指示がない限り、前述の詳細な説明及び添付の特許請求の範囲において、「第1の」、第2の」等の用語は、いくつかの例では、本明細書では様々な要素を説明するために使用されているが、これらの要素は、これらの用語によって限定すべきではない。これらの用語は、一方の要素を別の要素と区別するためだけに使用される。例えば、第1のコンピューティングデバイスを第2のコンピューティングデバイスと呼ぶことができ、同様に、第2のコンピューティングデバイスを第1のコンピューティングデバイスと呼ぶことができる。第1のコンピューティングデバイス及び第2のコンピューティングデバイスは両方ともコンピューティングデバイスであるが、それらは同じコンピューティングデバイスではない。
前述の明細書では、実施態様ごとに異なり得る多くの特定の詳細を参照して技術を説明している。したがって、明細書及び図面は、限定的な意味ではなく例示的な意味で考えるべきである。