(57)【特許請求の範囲】
【請求項１】
文字の入力ブロックをスキャンしてトークンのストリームを生成する第１のハードウェア・エンジンであって、前記トークンのストリームは、前記入力ブロックの文字の一致した文字列への置換バック・ポインタと前記入力ブロックの置換されていない文字とを含む、第１のハードウェア・エンジンと、
前記トークンのストリームを受信し、前記トークンに関連付けられたシンボルのソートされたリストを維持する第２のハードウェア・エンジンと、
各シンボルについてのエントリを含む頻度テーブルであって、該頻度テーブルはシンボル値によってインデックスを指され、前記頻度テーブルの各エントリがシンボルの出現の頻度を保持する、頻度テーブルと、
を備え、
前記ソートされたリストの各エントリがシンボルの値を保持し、
前記頻度テーブルの各エントリが、前記ソートされたリストのエントリへのインデックスをさらに保持し、前記ソートされたリストのエントリは、前記頻度テーブルのインデックスを指すシンボル値を保持し、
前記第２のハードウェア・エンジンは、前記第１のハードウェア・エンジンが前記ストリームの前記トークンを生成する間、出現の頻度によってシンボルの前記ソートされたリストを同時に更新すること及び再ソートすることによりシンボルの前記ソートされたリストを維持する、
ハードウェア・データ圧縮器。
【請求項２】
前記ソートされたリストを維持するために、前記第２のハードウェア・エンジンは、
（ａ）前記第１のハードウェア・エンジンから受信された前記ストリームのトークンに関連付けられた第１のシンボルの第１の頻度をインクリメントし、
（ｂ）前記第１の頻度が前記第１のシンボルのすぐ上の第２のシンボルの第２の頻度より大きい間、前記ソートされたリスト内の前記第１のシンボルの位置と前記第２のシンボルの位置とを繰り返し交換する、
請求項１に記載のハードウェア・データ圧縮器。
【請求項３】
前記第２のハードウェア・エンジンは、
前記第１のハードウェア・エンジンが前記文字の入力ブロックをスキャンして前記ストリームの次のトークンを生成する間、（ａ）及び（ｂ）を実行する、
請求項２に記載のハードウェア・データ圧縮器。
【請求項４】
前記ソートされたリストを維持するために、前記第２のハードウェア・エンジンは、さらに、
（ｃ）前記第１の頻度が前記第２の頻度に等しく、且つ前記第１のシンボルのシンボル値が前記第２のシンボルのシンボル値より小さい間、前記ソートされたリスト内の前記第１のシンボルの位置と前記第２のシンボルの位置とを繰り返し交換する、
請求項３に記載のハードウェア・データ圧縮器。
【請求項５】
前記ソートされたリストを維持するために、前記第２のハードウェア・エンジンは、さらに、
（ｄ）前記トークンに関連付けられた各シンボルについて（ａ）乃至（ｃ）を繰り返す、
請求項４に記載のハードウェア・データ圧縮器。
【請求項６】
前記ソートされたリストを維持するために、前記第２のハードウェア・エンジンは、さらに、
前記ストリームの各トークンについて（ａ）乃至（ｄ）を繰り返す、
請求項５に記載のハードウェア・データ圧縮器。
【請求項７】
前記ソートされたリストを維持するために、前記第２のハードウェア・エンジンは、さらに、
前記の生成されたトークンのストリーム内の前記第１のシンボルの最初の出現に応答して、前記第１のシンボルを前記ソートされたリストの末尾に挿入する、
請求項６に記載のハードウェア・データ圧縮器。
【請求項８】
前記ソートされたリスト内の前記第１のシンボルの位置と前記第２のシンボルの位置とを交換するために、前記第２のハードウェア・エンジンは、
前記第１のシンボルと前記第２のシンボルとの、前記ソートされたリストの２つのエントリに保持されたシンボルの値を交換する、
請求項２に記載のハードウェア・データ圧縮器。
【請求項９】
前記ソートされたリスト内の前記第１のシンボルの位置と前記第２のシンボルの位置とを交換するために、前記第２のハードウェア・エンジンは、さらに、
前記第１のシンボルについての前記頻度テーブル内のエントリのインデックスをデクリメントし、
前記第２のシンボルについての前記頻度テーブル内のエントリのインデックスをインクリメントする、
請求項８に記載のハードウェア・データ圧縮器。
【請求項１０】
シンボルの前記ソートされたリストを使用してハフマン・コード・テーブルを構築する第３のハードウェア・エンジン、
をさらに備える請求項１に記載のハードウェア・データ圧縮器。
【請求項１１】
さらに、前記第３のハードウェア・エンジンが、前記第２のハードウェア・エンジンによる前記ソートされたリストの変更に応答して、前記第１のハードウェア・エンジンによる前記入力ブロックのスキャンの完了の前に、シンボルの前記ソートされたリストを使用して前記ハフマン・コード・テーブルの構築を開始する、
請求項１０に記載のハードウェア・データ圧縮器。
【請求項１２】
前記ソートされたリストの最後の変更に応答して前記第３のハードウェア・エンジンによって実行された前記ハフマン・コード・テーブルの最後の構築を使用して、前記トークンのストリームをハフマン・エンコードする第４のハードウェア・エンジン、
をさらに備え、
前記第３のハードウェア・エンジンが、前記ソートされたリストに対する最後の変更の後に前記ハフマン・コード・テーブルの最後の構築を開始し、前記入力ブロックのスキャンの完了の前に前記最後の構築を完了した場合、前記第４のハードウェア・エンジンは、前記入力ブロックのスキャンの完了において前記トークンのストリームのハフマン・エンコードを開始し、
そうでない場合、前記第４のハードウェア・エンジンは、前記ハフマン・コード・テーブルの最後の構築の完了において前記トークンのストリームのハフマン・エンコードを開始する、
請求項１１に記載のハードウェア・データ圧縮器。
【請求項１３】
ハードウェア・データ圧縮器を使用して文字の入力ブロックを圧縮する方法であって、
第１のハードウェア・エンジンによって、文字の入力ブロックをスキャンし、応答的に、トークンのストリームを生成するステップであって、前記トークンのストリームは、前記入力ブロックの文字の一致した文字列への置換バック・ポインタと前記入力ブロックの置換されない文字とを含む、ステップと、
第２のハードウェア・エンジンによって、前記第１のハードウェア・エンジンから前記トークンのストリームを受信するステップと、
前記第２のハードウェア・エンジンによって、前記第１のハードウェア・エンジンによる前記トークンのストリームを生成するステップと同時に、出現の頻度によってソートされたリストを更新すること及び再ソートすることにより前記ソートされたリストを維持するステップと、
各シンボルについてのエントリを含む頻度テーブルを維持するステップであって、前記頻度テーブルはシンボル値によってインデックスを指され、前記頻度テーブルの各エントリがシンボルの出現の頻度を保持する、ステップと、
を備え、
前記ソートされたリストの各エントリがシンボルの値を保持し、
前記頻度テーブルの各エントリが、前記ソートされたリストのエントリへのインデックスをさらに保持し、前記ソートされたリストのエントリは、前記頻度テーブルのインデックスを指すシンボル値を保持する、
方法。
【請求項１４】
前記ソートされたリストを維持するステップは、
（ａ）前記第１のハードウェア・エンジンから受信された前記ストリームのトークンに関連付けられた第１のシンボルの第１の頻度をインクリメントするステップと、
（ｂ）前記第１の頻度が前記第１のシンボルのすぐ上の第２のシンボルの第２の頻度より大きい間、前記ソートされたリスト内の前記第１のシンボルの位置と前記第２のシンボルの位置とを繰り返し交換するステップと、
を備える、請求項１３に記載の方法。
【請求項１５】
前記第１のハードウェア・エンジンが前記文字の入力ブロックをスキャンして前記ストリーム内の次のトークンを生成する間、前記第２のハードウェア・エンジンが前記（ａ）及び（ｂ）を実行するステップ、
をさらに備える請求項１４に記載の方法。
【請求項１６】
前記ソートされたリストを維持するステップは、
（ｃ）前記第１の頻度が前記第２の頻度に等しく、且つ前記第１のシンボルのシンボル値が前記第２のシンボルのシンボル値より小さい間、前記ソートされたリスト内の前記第１のシンボルの位置と前記第２のシンボルの位置とを繰り返し交換するステップ
をさらに備える、請求項１５に記載の方法。
【請求項１７】
前記ソートされたリストを維持するステップは、
（ｄ）前記トークンに関連付けられた各シンボルについて前記（ａ）乃至（ｃ）を繰り返すステップ、
をさらに備える、請求項１６に記載の方法。
【請求項１８】
前記ソートされたリストを維持するステップは、
前記ストリームの各トークンについて前記（ａ）乃至（ｄ）を繰り返すステップ、
をさらに備える、請求項１７に記載の方法。
【請求項１９】
前記ソートされたリスト内の前記第１のシンボルの位置と前記第２のシンボルの位置とを交換するステップは、
前記第１のシンボルと前記第２のシンボルとの、前記ソートされたリストの２つのエントリに保持されたシンボルの値を交換するステップ、
を備える、請求項１４に記載の方法。
【請求項２０】
前記ソートされたリスト内の前記第１のシンボルの位置と前記第２のシンボルの位置とを交換するステップは、
前記第１のシンボルについての前記頻度テーブル内のエントリのインデックスをデクリメントするステップと、
前記第２のシンボルについての前記頻度テーブル内のエントリのインデックスをインクリメントするステップと、
をさらに備える、請求項１９に記載の方法。
【請求項２１】
第３のハードウェア・エンジンによって、シンボルの前記ソートされたリストを使用してハフマン・コード・テーブルを構築するステップ、
をさらに備える請求項１３に記載の方法。
【請求項２２】
さらに、前記第３のハードウェア・エンジンが、前記第２のハードウェア・エンジンによる前記ソートされたリストの変更に応答して、前記第１のハードウェア・エンジンによる前記入力ブロックのスキャンの完了の前に、シンボルの前記ソートされたリストを使用して前記ハフマン・コード・テーブルの構築を開始する、
請求項２１に記載の方法。
【請求項２３】
第４のハードウェア・エンジンによって、前記ソートされたリストの最後の変更に応答して前記第３のハードウェア・エンジンによって実行された前記ハフマン・コード・テーブルの最後の構築を使用して、前記トークンのストリームをハフマン・エンコードするステップ、
をさらに備え、
前記第３のハードウェア・エンジンが、前記ソートされたリストに対する最後の変更の後に前記ハフマン・コード・テーブルの最後の構築を開始し、前記入力ブロックのスキャンの完了の前に前記最後の構築を完了した場合、前記第４のハードウェア・エンジンは、前記入力ブロックのスキャンの完了において前記トークンのストリームのハフマン・エンコードを開始し、
そうでない場合、前記第４のハードウェア・エンジンは、前記ハフマン・コード・テーブルの最後の構築の完了において前記トークンのストリームのハフマン・エンコードを開始する、
請求項２２に記載の方法。
【請求項２４】
コンピューティング・デバイスに、ハードウェア・データ圧縮器を規定するためのコンピュータ使用可能プログラム・コードを実行させるコンピュータ・プログラムであって、
前記コンピュータ使用可能プログラム・コードは、
文字の入力ブロックをスキャンしてトークンのストリームを生成する第１のハードウェア・エンジンを規定するための第１のプログラム・コードであって、前記トークンのストリームは、前記入力ブロックの文字の一致した文字列への置換バック・ポインタと前記入力ブロックの置換されていない文字とを含む、第１のプログラム・コードと、
前記トークンのストリームを受信し、前記トークンのストリームにおける出現の頻度によってソートされたシンボルのリストを維持する第２のハードウェア・エンジンを規定するための第２のプログラム・コードと、
を備え、
前記第１のハードウェア・エンジンは、前記トークンのストリームを生成し、前記第２のハードウェア・エンジンは同時に、シンボルの前記のソートされたリストを更新すること及び再ソートすることによりシンボルの前記ソートされたリストを維持し、頻度テーブルが各シンボルについてのエントリを含み、前記頻度テーブルはシンボル値によってインデックスを指され、前記頻度テーブルの各エントリがシンボルの出現の頻度を保持し、前記ソートされたリストの各エントリがシンボルの値を保持し、前記頻度テーブルの各エントリが、前記ソートされたリストのエントリへのインデックスをさらに保持し、前記ソートされたリストのエントリは、前記頻度テーブルのインデックスを指すシンボル値を保持する、
コンピュータ・プログラム。
【発明の詳細な説明】
【背景技術】
【０００１】
コンピュータの世界では、効率的なデータ圧縮が重要な要件になっている。これは主に、インターネットを経由して送信される多くのファイルが、送信される前に圧縮され、受信された後に解凍されるからである。このことは、ファイルのサイズが小さいほど送信時間が短くなり、ネットワーク上で使用される帯域幅が少なくなるため、有利であり得る。
【０００２】
関連出願の相互参照
本出願は、２０１５年５月１１日に申請された米国仮出願第６２／１５９，３５２号に基づく優先権を主張するものであり、その全体を参照により援用する。
【図面の簡単な説明】
【０００３】
【図１】ハードウェア・データ圧縮器を示すブロック図である。
【図２Ａ】図１のハードウェア・データ圧縮器の一部を示すブロック図である。
【図２Ｂ】図２ＡのＬＺ７７エンジン及びソート・エンジンの動作を示すタイミング図である。
【図３】図２ＡのＬＺ７７エンジン及びソート・エンジンの動作を示すフローチャートである。
【図４】図１のソート・エンジンによって使用するための頻度テーブル、ソート済みリスト、及びテール・ポインタを示すブロック図である。
【図５】図３のブロックの実施形態に従う図１のソート・エンジンの動作を示すフローチャートである。
【図６】ソート・エンジンによって更新された、図４の頻度テーブル、ソート済みリスト、及びテール・ポインタを示すブロック図である。
【図７】ソート・エンジンによって更新された、図６の頻度テーブル、ソート済みリスト、及びテール・ポインタを示すブロック図である。
【図８】ソート・エンジンによって更新された、図７の頻度テーブル、ソート済みリスト、及びテール・ポインタを示すブロック図である。
【図９】従来方法において、ＤＥＦＬＡＴＥ方式入力ブロック圧縮に関連付けられた圧縮時間の構成要素をグラフィカルに示すタイミング図である。
【図１０】同時シンボル・リスト・ソートの実施形態に従う、ＤＥＦＬＡＴＥ方式入力ブロック圧縮に関連付けられた圧縮時間の構成要素をグラフィカルに示すタイミング図である。
【図１１Ａ】代替の実施形態に従うソート済みリストを示すブロック図である。
【図１１Ｂ】代替の実施形態に従う頻度テーブルを示すブロック図である。
【図１２】代替の実施形態に従う、図１のハードウェア・データ圧縮器に関連付けられたハードウェアを示すブロック図である。
【図１３】代替の実施形態に従う圧縮時間の構成要素をグラフィカルに示すタイミング図である。
【図１４Ａ】ダイナミック−プライム・ハフマン・エンコーディングと連動してデータ圧縮を実行するための図１のＬＺ７７エンジンの動作を示すフローチャートである。
【図１４Ｂ】ダイナミック−プライム・ハフマン・エンコーディングと連動してデータ圧縮を実行するための図１のハフマン・コード・テーブル構築エンジンの動作を示すフローチャートである。
【図１４Ｃ】ダイナミック−プライム・ハフマン・エンコーディングと連動してデータ圧縮を実行するための図１のハフマン・エンコーディング・エンジンの動作を示すフローチャートである。
【図１５】従来方法において、ＤＥＦＬＡＴＥ方式入力ブロック圧縮に関連付けられた圧縮時間の構成要素をグラフィカルに示すタイミング図である。
【図１６】ダイナミック−プライム・ハフマン・コード・テーブルの実施形態に従う、ＤＥＦＬＡＴＥ方式入力ブロック圧縮に関連付けられた圧縮時間の構成要素をグラフィカルに示すタイミング図である。
【図１７Ａ】一実施形態に従う、ダイナミック−プライム・ハフマン・コード・テーブルを構築するためのハードウェア・データ圧縮器の動作を示すフローチャートである。
【図１７Ｂ】一実施形態に従う、ダイナミック−プライム・ハフマン・コード・テーブルを構築するためのハードウェア・データ圧縮器の動作を示すフローチャートである。
【図１７Ｃ】一実施形態に従う、ダイナミック−プライム・ハフマン・コード・テーブルを構築するためのハードウェア・データ圧縮器の動作を示すフローチャートである。
【図１８】一実施形態に従う、図１のハードウェア・データ圧縮器に関連付けられたハードウェアを示すブロック図である。
【図１９】ハフマン・コード・テーブルの構築を信号で伝えるためのソート・エンジンの動作を示すフローチャートである。
【図２０】代替の実施形態に従う、ＤＥＦＬＡＴＥ方式入力ブロック圧縮に関連付けられた圧縮時間の構成要素をグラフィカルに示すタイミング図である。
【図２１】図１のハードウェア・データ圧縮器の一部を示すブロック図である。
【図２２】データを圧縮するためのハードウェア・データ圧縮器の動作を示すフローチャートである。
【図２３Ａ】一実施形態に従う、図２２のブロックの動作を示すフローチャートである。
【図２３Ｂ】代替の実施形態に従う、図２２のブロックの動作を示すフローチャートである。
【図２４】図１のＬＺ７７エンジンの一部を示すブロック図である。
【図２５】図２４のＬＺ７７エンジンの動作を示すフローチャートである。
【図２６】ハードウェア・データ圧縮器の一部を示すブロック図である。
【図２７】図２６のハッシュ・チェーンのノードを示すブロック図である。
【図２８】動的ノード確率の実施形態に従う、新しいノードをハッシュ・チェーンに挿入するための図２６のハードウェア・データ圧縮器の動作を示すフローチャートである。
【図２９】図２８に従う図２６のハードウェア・データ圧縮器の動作を例で示すタイミング図である。
【図３０】動的ノード確率の実施形態に従う、ハッシュ・チェーンをソートするための図２６のハードウェア・データ圧縮器の動作を示すフローチャートである。
【図３１】図３０に従う図２６のハードウェア・データ圧縮器の動作を例で示すタイミング図である。
【図３２】静的なハッシュ・チェーン・ノード確率の実施形態で使用するためのルックアップ・テーブルの作成方法を示すフローチャートである。
【図３３】静的なハッシュ・チェーン・ノード確率の実施形態で使用するためのルックアップ・テーブルである。
【図３４】静的なノード確率の実施形態に従う、ハッシュ・チェーンをソートするための図２６のハードウェア・データ圧縮器の動作を示すフローチャートである。
【図３５】図３４に従う、図２６のハードウェア・データ圧縮器の動作を例で示すタイミング図である。
【図３６】代替の実施形態に従うハードウェア・データ圧縮器を示すブロック図である。
【図３７】図３６のハードウェア・データ圧縮器の動作を示すフローチャートである。
【図３８】図３７の方法に従う、図３６のハードウェア・データ圧縮器の動作を示すタイミング図である。
【図３９】図１のＬＺ７７エンジンの一部を示すブロック図である。
【図４０】図３９のＬＺ７７エンジンの動作を示すフローチャートである。
【図４１】図３９のハッシュ・インデックス・ジェネレータのうちの１つをより詳細に示すブロック図である。
【図４２】図１などのハードウェア・データ圧縮器１００を含むシステムを示すブロック図である。
【図４３】代替の実施形態に従う、ハードウェア・データ圧縮器を含むシステムを示すブロック図である。
【発明を実施するための形態】
【０００４】
ｇｚｉｐやｚｌｉｂなどの一般的なファイル圧縮プログラムは、入力ファイルを取り込んで圧縮し、可能な場合、より小さい出力ファイルを作り出す。出力ファイルは定義済みのフォーマットを持っており、これにより、ファイル解凍プログラム（ｇｚｉｐやｚｌｉｂなど）は、圧縮された出力ファイルを入力として取り込んで解凍し、元の入力ファイルと同一の解凍されたファイルを作り出すことができる。圧縮されたファイルは、入力ファイルのデータの連続するブロックに対応する一連のブロックを含んでいる。圧縮されたファイルの各ブロックは、ＤＥＦＬＡＴＥ圧縮データ・フォーマット仕様バージョン１．３、ＲＦＣ  １９５１で定義されている可逆圧縮データ・フォーマットに従う。ＤＥＦＬＡＴＥ仕様によれば、入力ファイルの各ブロックは、ＬＺ方式アルゴリズム（例えば、ＬＺ７７）とハフマン・コーディングの組み合わせを使用して圧縮される。例えば、「Ａ  Ｕｎｉｖｅｒｓａｌ  Ａｌｇｏｒｉｔｈｍ  ｆｏｒ  Ｓｅｑｕｅｎｔｉａｌ  Ｄａｔａ  Ｃｏｍｐｒｅｓｓｉｏｎ」Ｚｉｖ  Ｊ．、Ｌｅｍｐｅｌ  Ａ．、情報理論に関するＩＥＥＥトランザクション、第２３巻３号、３３７〜３４３ページ、「Ａ  Ｍｅｔｈｏｄ  ｆｏｒ  ｔｈｅ  Ｃｏｎｓｔｒｕｃｔｉｏｎ  ｏｆ  Ｍｉｎｉｍｕｍ  Ｒｅｄｕｎｄａｎｃｙ  Ｃｏｄｅｓ」Ｈｕｆｆｍａｎ、Ｄ．  Ａ．、無線技術学会の会報、１９５２年  ９月、第４０巻９号、１０９８〜１１０１ページを参照されたい。
【０００５】
ＬＺ７７圧縮アルゴリズム（及びその多くの変形）は、入力データ・ストリーム内の繰り返し出現するデータ又は文字列を、入力データ・ストリーム内の以前に出現した文字列へのバック・ポインタで置換することによって、可逆方式で入力データ・ストリームを圧縮する。文字列は、１つ又は複数の連続する文字である。各バック・ポインタは、順序付けられた対（長さ、距離）である。長さは、入力データ・ストリーム内の現在のスキャン位置での文字列の文字数を示し、この文字列は、現在のスキャン位置から後方の距離によって指定された、入力ストリーム内の以前の位置から始まる同じ文字列と一致する。バック・ポインタは、次の記述、すなわち「次の長さの各文字は、圧縮されていないストリーム内のそれらの文字の後方の、距離の文字数だけ正確に離れた各文字に等しい」と同等なものとして説明されている。アルゴリズムは、繰り返される文字列の文字をバック・ポインタで置換することによって圧縮を実現する。さらに具体的には、ＬＺ７７アルゴリズムは、入力データ・ストリーム内を、現在のスキャン位置から後方に検索し、１つのバック・ポインタで置換するための文字列の一致（例えば、もしあれば、最長の一致する文字列）を検出する。適切な一致が検出された場合、アルゴリズムは一致する文字列へのバック・ポインタを生成し、検出されない場合、アルゴリズムはリテラル入力文字、例えば、現在のスキャン位置の３文字を効率的に生成し、現在のスキャン位置を更新する。ＤＥＦＬＡＴＥ仕様は、アルゴリズムが入力文字を置換するためのバック・ポインタを生成するのではなく入力文字を生成する場合を指して、「リテラル」という用語を使用する。したがって、ＬＺ７７圧縮の実際の出力は、リテラルとバック・ポインタのストリーム（及び、必要に応じて、下でより詳細に説明されるように、各リテラル及びバック・ポインタの頻度のヒストグラム）である。現在の仕様では、リテラルとバック・ポインタは「トークン」と呼ばれる。したがって、ＬＺ７７圧縮の出力はトークンのストリームである。達成される圧縮量は、主に、入力データ・ストリーム内で文字列が繰り返される度合いと繰り返される文字列の長さとに依存している。
【０００６】
ＤＥＦＬＡＴＥ仕様は、一般にプレフィックス・コーディングとも呼ばれるハフマン・コーディングについて、次のように説明している。すなわち「プレフィックス・コーディングは、ビット列（コード）によって既知のアルファベットからシンボルを表現し、シンボルごとに１つのコードである。この方法では、さまざまな長さのビット列によって、さまざまなシンボルが表現されることが可能であるが、パーサは、エンコードされた文字列をシンボルごとに常に一義的に構文解析することができる。アルファベットのシンボルの頻度がわかっていると仮定した場合、ハフマン・アルゴリズムは最適なプレフィックス・コード（そのアルファベットに対して使用できる最小のビット数のプレフィックス・コードを使用して、上記のシンボルの頻度で文字列を表現する）を構築することができる。このようなコードをハフマン・コードと呼ぶ」。ＤＥＦＬＡＴＥ仕様によれば、２つの区別可能なアルファベットが識別される。一方のアルファベットでは、シンボルは、リテラルの値（エントリ０〜２５６）、及びバック・ポインタの長さに関連付けられた値又はインデックス（エントリ２５７〜２８５）である。他方のアルファベットでは、シンボルは、バック・ポインタの距離に関連付けられた値又はインデックスである（エントリ０〜２９）。下でより詳細に説明されているように、２つのアルファベットの各々についてハフマン・コード・テーブルが作成される。
【０００７】
ＤＥＦＬＡＴＥ仕様によれば、出力ファイルの各圧縮ブロックは、そのブロックの圧縮に使用されたハフマン・コード・テーブルが出力ブロックに含まれているか、或いは出力ブロックに含まれていないかを示すビットをヘッダーに含んでいる。ハフマン・コード・テーブルが含まれていない場合、ハフマン・コード・テーブルは暗示され、ＤＥＦＬＡＴＥ仕様のセクション３．２．６で規定される。ＤＥＦＬＡＴＥ仕様では、前者（ハフマン・コード・テーブルが含まれる）は動的ハフマン・コードでの圧縮と呼ばれ、後者（ハフマン・コード・テーブルが暗示される）は固定ハフマン・コードでの圧縮と呼ばれる。動的なアプローチには、圧縮ファイルがハフマン・コード・テーブルの表現を含まなければならないという欠点があり、ハフマン・コード・テーブルが出力ブロック内の空間を占め、このことは出力ファイルを小さくするという目的に反する働きをする。したがって、固定されたアプローチは、小さい入力ファイルに対しては、場合によっては動的なアプローチが生成するよりも小さい出力ファイルを生成することができる。
【０００８】
しかし、動的なアプローチには、ＤＥＦＬＡＴＥ仕様の固定ハフマン・コード・テーブルを使用して得られるよりも優れたハフマン・コーディングが得られる可能性が高くなるように、ハフマン・コードをアルファベットのシンボルに割り当てることができるという利点がある。この場合、優れたハフマン・コーディングとは、動的ハフマン・コード・テーブルが、固定ハフマン・コード・テーブルが生成する場合よりも高い圧縮率でＬＺ７７出力ストリームを生成するということである。これは、固定ハフマン・コード・テーブルが汎用的であるゆえに、その確率の推定又は相対的な頻度があまり適切でない可能性があるからであり、固定ハフマン・コード・テーブルが特定の特徴に合わせて調整されないため、２つのアルファベットのさまざまなシンボルがハフマン圧縮されたＬＺ７７出力ストリームに出現することになる。前述したように、動的ハフマン・コード・テーブルは、ＬＺ７７出力ストリーム内により頻繁に出現するアルファベットのシンボルにより短いコードを割り当て、あまり頻繁に出現しないシンボルにより長いコードを割り当てて、入力ブロックの高い圧縮率を実現することができる。従来（例えば、ｇｚｉｐ又はｚｌｉｂによって実行されているように）、入力ブロックを圧縮して、動的ハフマン・コード・テーブルを使用してＤＥＦＬＡＴＥ仕様に従う（可能であれば）より小さい出力ブロックを作り出すための処理は、以下のように３つのステップの処理を備える。
【０００９】
第１ステップで、処理は、入力ブロックに対してＬＺ７７圧縮を実行して、ＬＺ７７出力ストリームと呼ばれるトークン（リテラルとバック・ポインタ）のストリームを作り出す。このステップは、入力ブロックのスキャンとも呼ばれ、文字列の一致について入力ブロックを後方に検索することを含む。入力ブロックをスキャンする間、プログラムは、トークンのストリームに基づいて２つのヒストグラムをさらに作り出す。一方のヒストグラムは、リテラル／長さのアルファベットにおける各シンボルについてのエントリを含み、他方のヒストグラムは、距離のアルファベットにおける各シンボルについてのエントリを含む。ヒストグラム内の各エントリは、シンボルがＬＺ７７トークン出力ストリームに現れた回数に関連付けられた頻度を明示する。バック・ポインタのトークンには、リテラル／長さのアルファベットの長さシンボルと距離のアルファベットの距離シンボルとの、２つのシンボルが関係付けられていることに注意する。
【００１０】
第２ステップで、処理は、処理の第１ステップで作り出された対応するヒストグラムを使用して、リテラル／長さハフマン・コード・テーブルと距離ハフマン・コード・テーブルを構築する。
【００１１】
第３ステップで、処理は、処理の第２ステップの間に構築されたハフマン・コード・テーブルを使用してＬＺ７７トークン出力ストリームをハフマン・エンコードして、圧縮された出力ブロックを作り出す。この出力ブロックは、可変長ハフマン・コードを含むビット列である。バック・ポインタの長さを指定する出力ブロック内のハフマン・コードの場合、バック・ポインタの距離を指定するハフマン・コードがその後に続く。
【００１２】
動的ハフマン・コード・テーブルを使用してＤＥＦＬＡＴＥ方式入力ブロックを圧縮するための、前述の３つのステップの処理における従来の欠点は、ステップが逐次的に実行されることである。つまり、ハフマン・コード・テーブルが構築される（第２ステップ）まで、ハフマン・エンコーディング（第３ステップ）は実行されることが不可能であり、ヒストグラムが（第１ステップの間に）完全に作り出されるまで、ハフマン・コード・テーブルは構築されない（第２ステップ）。
【００１３】
しかし、第１ステップと第３ステップは、例えば、固定ハフマン・コード・テーブルが使用されているときに実行されることが可能であるため、並行して実行されることが可能である。本発明者らは、ある観察を行うことにより、動的ハフマン・コード・テーブルを使用することによって得られる所望の圧縮率の改善を提供しながら、動的ハフマン・コード・テーブルを使用することに伴う速度の低下を防ぐハードウェア・データ圧縮器（compressor）を発明することができた。本発明者らは、入力ブロックの初期部分のみがスキャンされた後のヒストグラムを調べ、該ヒストグラムを、入力ブロック全体がスキャンされた後のヒストグラムと比較した。多くの場合、この比較によって、アルファベットのさまざまなシンボルの間の相対的な頻度に関して、時間におけるこれら２つの事例での頻度に、大きな差がないことが明らかであるのが観察された。つまり、多くの場合、入力ブロックの残りの部分がスキャンされた後のヒストグラムにおける相対的頻度は、最初の部分のみがスキャンされた後の相対的頻度とほとんど変わらない。例えば、入力ブロックの１０％のみがスキャンされた後、「Ａ」の頻度が６、「Ｂ」の頻度が３、「Ｃ」の頻度が４であり得、一方、入力ブロック全体がスキャンされた後に、「Ａ」の頻度が６２、「Ｂ」の頻度が３１、「Ｃ」の頻度が４４であり得る。相対的な観点からは、入力ブロックの１０％のみがスキャンされた後の頻度と入力ブロック全体がスキャンされた後の頻度との間に差異はない。
【００１４】
このことは、ハフマン・コード・テーブルがアルファベットのシンボルの絶対的頻度値ではなく相対的頻度に基づいて作成されることが可能であるため、有益な観察である。つまり、前述したように、より頻度の高いシンボルに、より短いコードを使用することによって入力ブロックの圧縮を最適化するために、アルファベットのシンボルの相対的頻度が高いほど、それに割り当てられるハフマン・コードは短くなる（すなわち、ビット数が少なくなる）。
【００１５】
この観察に基づき、ハードウェア・データ圧縮器の実施形態は、入力ブロックの最初の部分のみがスキャンされた後に、ヒストグラムの更新を停止し、この「不完全な」ヒストグラムを使用してハフマン・コード・テーブル（本明細書では、「ダイナミック−プライム」ハフマン・コード・テーブルと呼ばれる）を構築し、その後、入力ブロックの残りの部分のスキャンと並行して、ダイナミック−プライム・ハフマン・コード・テーブルの使用を開始し、ＬＺ７７出力トークン・ストリームをエンコードすると説明される。これによって、ハードウェア・データ圧縮器のハフマン・コーディング・エンジンは、そのハフマン・コーディングを、ＬＺ７７圧縮エンジンによる入力ブロックの残りの部分のスキャンと重複させることができ、そのため、ハフマン・コーディング時間の、全部ではないにしても少なくともいくらかが、ＬＺ７７圧縮時間の背後に隠れる。ハフマン・コーディングにかかる時間が、通常は、ＬＺ７７圧縮に関連する入力ブロックのスキャンにかかる時間よりも少ないことを考えると、入力スキャンの間にハフマン・コード・テーブルが構築される時点に依存して、ハフマン・コーディング時間が入力ブロック圧縮処理に対して加算する時間は、無視できる量である場合がある。
【００１６】
さらに、本発明者らは、各シンボルの出現頻度に基づくヒストグラムのソート（効率的なハフマン・コード・テーブルの構築に必要とされる）が時間のかかる処理であり、図９に示すように、圧縮処理のクリティカル・パスにあり、したがって合計圧縮時間を加算する要因になっていることを観察した。有利なことに、本実施形態は、頻度によるシンボル・リストのソートが入力ブロックのスキャンと同時にインクリメンタルに、好ましくは各シンボルがＬＺ７７エンジンによって作り出されるときに別個のハードウェア・エンジンによって（例えば、図２Ａ及び２Ｂを参照）実行されて、ソート時間を入力ブロックのスキャン時間の背後に隠して、合計圧縮時間を減少させると説明される。本発明者らの観察によれば、各シンボルがＬＺ７７によって生成されるとき、シンボルの頻度値は１ずつだけ変更され、ソート済みリスト内のシンボルの場所を変更する必要はない可能性が高く、変更する必要がある場合でも、シンボルの場所を短い距離ずつ変更するだけで済み、このことは極めて高速に実行することができる可能性が高く、ソート・エンジンは、上記観察からの恩恵を有利に受ける。特に、ソート済みリスト内のシンボルの場所を変更するために必要な時間は、ＬＺ７７エンジンがターゲット文字列の一致を検索し及び検出するために必要な時間よりも少なくなる可能性が非常に高い。さらに有利なことに、インクリメンタル且つ同時に行われるシンボル・リストのソート・メカニズムは、ダイナミック−プライム・ハフマン・テーブルの実施形態と組み合わせて採用されることが可能である。
【００１７】
ハードウェア・データ圧縮器
ここで図１を参照すると、ハードウェア・データ圧縮器１００を表すブロック図が示されている。ハードウェア・データ圧縮器１００は、入力ブロック・メモリ１０１と、圧縮エンジン１０２（例えば、ＬＺ７７エンジン）と、ハッシュ・メモリ１０３と、ソート・エンジン１０４と、バック・ポインタ及びフラグ・メモリ１０５と、ハフマン・コード・テーブル構築エンジン１０６と、頻度テーブル、シンボルのソート済みリスト、及びハフマン・コード・テーブルを格納するテーブル・メモリ１０７と、ハフマン・エンコーディング・エンジン１０８と、出力メモリ１０９とを含む。圧縮エンジン１０２、ソート・エンジン１０４、ハフマン・コード・テーブル構築エンジン１０６、及びハフマン・エンコーディング・エンジン１０８は、ハードウェア・エンジンである。ハードウェア・エンジンはハードウェアであり、ハードウェア・ステート・マシンを含めて、ハードウェアの組み合わせ論理及び順序論理を含むことができる。ハードウェア・エンジンは、メモリに格納された命令を取得して該命令を実行するプログラム可能なプロセッサとは区別可能である。しかし、ハードウェア・エンジンは、１つ又は複数のメモリから入力としてデータを読み出し、１つ又は複数のメモリに出力としてデータを書き込むことができる。
【００１８】
入力ブロック・メモリ１０１は、圧縮されるべき複数の文字から成る入力ブロックを保持する。一実施形態では、入力ブロック・メモリ１０１は３２ＫＢであり、別の実施形態では、入力ブロック・メモリ１０１は１６ＫＢであるが、他の実施形態が企図される。通常、複数の文字から成る入力ブロックは、画像ファイル（例えば、ＪＰＧ、ＴＩＦＦ）、オーディオ・ファイル（例えば、ＡＩＦＦ、ＷＡＶ）、テキスト・ファイル、スプレッドシート、ワード・プロセッサやプレゼンテーション・アプリケーションによって生成されたファイル、又はその他の種類のファイル（例えば、ＰＤＦ）などの、圧縮されるべき入力ファイルの複数の文字の一部である。入力ブロックの各文字は、１バイト・データであることが好ましい。入力ブロック・メモリ１０１は、入力ブロックを圧縮エンジン１０２及びハフマン・エンコーディング・エンジン１０８に提供する。一実施形態では、入力ブロック・メモリ１０１は、実施形態における競合を減らすようにデュアルポート・メモリであり、圧縮エンジン１０２は、入力ブロック・メモリ１０１にアクセスして入力ブロックをスキャンして（例えば、現在の検索位置で文字列を取得し、入力ブロック内の以前の部分との一致を検索して）圧縮を実行し（例えば、一致する文字列を置換するためのバック・ポインタを作り出す）、同時に、ハフマン・エンコーディング・エンジン１０８は、入力ブロック・メモリ１０１にアクセスして出力トークン・ストリームのリテラル・シンボル（バック・ポインタによって置換されない入力ブロックの文字）をハフマン・エンコードする。一実施形態では、入力ブロックは、システム・メモリから入力ブロック・メモリ１０１にロードされる。
【００１９】
圧縮エンジン１０２は、入力ブロックの文字の文字列を、入力ブロック内の以前の文字列へのバック・ポインタで置換することによって、入力ブロックを圧縮する。以前の文字列は、バック・ポインタによって置換される文字列に一致する。圧縮エンジン１０２は、好ましくは、ＬＺ７７エンジン１０２である。ＬＺ７７エンジン１０２は、論文「Ａ  Ｕｎｉｖｅｒｓａｌ  Ａｌｇｏｒｉｔｈｍ  ｆｏｒ  Ｓｅｑｕｅｎｔｉａｌ  Ｄａｔａ  Ｃｏｍｐｒｅｓｓｉｏｎ」（Ｚｉｖ  Ｊ．、Ｌｅｍｐｅｌ  Ａ．著、情報理論に関するＩＥＥＥトランザクション、第２３巻３号、ｐｐ．３３７−３４３）に記載されたアルゴリズム又はその変形を使用する。ただし、圧縮エンジン１０２が他の文字列置換可逆圧縮アルゴリズムを使用してバック・ポインタを生成する他の実施形態が企図される。
【００２０】
好ましくは、ＬＺ７７エンジン１０２は、バック・ポインタを生成し、バック・ポインタ・メモリ１０５に格納する。一実施形態では、ＬＺ７７エンジン１０２は、バック・ポインタ・メモリ１０５内にフラグの配列を維持する。一実施形態では、各フラグは、入力ブロック内の１文字に対応する単一ビットである（例えば、１６Ｋ文字の入力ブロックに対して１６Ｋビットのフラグが存在する）。フラグがｔｒｕｅ値である場合、このことは、バック・ポインタ・メモリ１０５に格納されたバック・ポインタが、フラグ配列内のそのフラグの位置に対応する入力ブロック内の位置で始まる文字列を置換したことを示す。例えば、フラグ配列のインデックス３７４２のフラグがｔｒｕｅである場合、ＬＺ７７エンジン１０２は、入力ブロック内の位置３７４２で始まる文字列を置換するバック・ポインタを生成している。そうでない場合（フラグがｆａｌｓｅの場合）、そのフラグのインデックスに対応する入力ブロック内の位置の文字は、ＬＺ７７エンジン１０２の出力トークンのストリームの一部である「リテラル」文字と見なされる。リテラルは、その後にハフマン・エンコーディング・エンジン１０８によってハフマン・エンコードされ、出力メモリ１０９に格納されることになるシンボルである。
【００２１】
下でより詳細に説明されているように、好ましくは、ＬＺ７７エンジン１０２は、一致する文字列の検索時間を減らすために、ハッシュ・テーブル及びハッシュ技術を採用する。ハッシュ・テーブルは、ハッシュ・メモリ１０３に格納される。有利なことに、一実施形態では、下でより詳細に説明されているように、ＬＺ７７エンジン１０２は、圧縮速度を上げるために２つのハッシュ・テーブルを採用する。
【００２２】
テーブル・メモリ１０７は、ＬＺ７７エンジン１０２、ソート・エンジン１０４、ハフマン・コード・テーブル構築エンジン１０６、及びハフマン・エンコーディング・エンジン１０８によってアクセス可能である。テーブル・メモリ１０７内の頻度テーブル（その一例が、図４の要素４０１として示される）は、頻度（図４の要素４０２）、又は、ＬＺ７７エンジン１０２の出力トークンのストリーム内で各シンボルが出現した回数を保持する。一実施形態では、ＬＺ７７エンジン１０２が、頻度テーブル４０１の頻度値４０２を維持する。代替の実施形態では、ソート・エンジン１０４が、ＬＺ７７エンジン１０２によって生成されたトークン２１２に応答して、頻度テーブル４０１の頻度値４０２を維持する。別の代替の実施形態では、ハフマン・コード・テーブル構築エンジン１０６が、ＬＺ７７エンジン１０２によって生成されたトークン２１２に応答して、頻度テーブル４０１の頻度値４０２を維持する。下でより詳細に説明されているように、ソート・エンジン１０４は、シンボルのソート済みリスト（その一例が、図４のソート済みリスト４０３として示される）を、シンボルの頻度に従って（例えば、図４の頻度テーブル４０１のエントリのソート済みインデックス・フィールド４０４を使用して）維持する。さらに、ハフマン・コード・テーブル構築エンジン１０６は、頻度でソートされたシンボルのソート済みリストを使用して、ハフマン・コード・テーブルを構築する。このハフマン・コード・テーブルは、ハフマン・エンコーディング・エンジン１０８によって、ＬＺ７７エンジン１０２の出力ストリームのトークンに関連付けられたシンボルをハフマン・エンコードして出力メモリ１０９に格納するために使用される。
【００２３】
下でより詳細に説明されているように、好ましくは、ハフマン・エンコーディング・エンジン１０８は２つのハフマン・コード・テーブル、リテラル及び長さシンボルについて１つと距離シンボルについて１つとを採用し、したがって、２つの対応する頻度テーブル及びソート済みリストが維持され、これらから２つのハフマン・コード・テーブルが構築される。一実施形態では、ハフマン・コード・テーブル構築エンジン１０６は、ＤＥＦＬＡＴＥ仕様などで使用される、良く知られた標準的なハフマン・エンコーディング処理に従って、ハフマン・コード・テーブルを構築する。好ましくは、リテラル・シンボルをハフマン・エンコードすることは、リテラル・シンボル値（例えば、図１１Ａのシンボル値４０６、又は図１１Ｂの頻度テーブル４０１へのインデックス）に関連付けられたハフマン・コード（例えば、図１１Ａ及び１１Ｂのハフマン・コード１１０８）を出力することを意味し、バック・ポインタの長さをハフマン・エンコードすることは、長さシンボルの値に関連付けられたハフマン・コードを出力し、その長さシンボルの長さの範囲が、バック・ポインタの長さに加えて、バック・ポインタの長さの指定に使用される任意の追加ビット（extra  bits）（例えば、ＤＥＦＬＡＴＥ仕様のセクション３．２．５に記載された、下の表１で規定される）を包含することを意味し、バック・ポインタの距離をハフマン・エンコードすることは、距離シンボルの値に関連付けられたハフマン・コードを出力し、その距離シンボルの距離の範囲が、バック・ポインタの距離に加えて、バック・ポインタの距離の指定に使用される任意の追加ビット（例えば、ＤＥＦＬＡＴＥ仕様のセクション３．２．５に記載された、下の表２で規定される）を包含することを意味する。「コード」という用語が下の表１に含まれているのは、「コード」という用語がＤＥＦＬＡＴＥ仕様の表で使用されているからであるということが理解されるべきである。ただし、表１の「コード」列の値は、例えば図１１Ａ及び１１Ｂのハフマン・コード１１０８などの、ハフマン・コードではない。むしろ、「コード」列の値は、例えば、図４の実施形態のシンボル値４０６に対応し、この値は、図４の頻度テーブル４０１へのインデックスの値でもある。このことは、距離シンボルに関する表２に対しても当てはまる。
【００２４】
【表１】
0006363581.tif 000002
【００２５】
【表２】
0006363581.tif 000003
【００２６】
ソート・エンジン１０４を含まず、代わりに、ＬＺ７７エンジン１０２が頻度テーブルの更新を完了した後に、ハフマン・コード・テーブル構築エンジン１０６が頻度テーブルのシンボルのソートを実行する実施形態が企図される。通常、ＬＺ７７エンジン１０２は、入力ブロック全体をスキャンした後に、頻度テーブルの更新を停止する。しかし、下で説明される実施形態では、ＬＺ７７エンジン１０２が、入力ブロックの初期部分をスキャンした後に、頻度テーブルの更新を有利に停止し、その時点でハフマン・コード・テーブル構築エンジン１０６がハフマン・コード・テーブルを構築する。このハフマン・コード・テーブルは、本明細書では、「ダイナミック−プライム」ハフマン・コード・テーブルと呼ばれる。
【００２７】
入力ブロックのスキャンと同時のソート済みシンボル・リストの維持
ここで図２Ａを参照すると、図１のハードウェア圧縮器１００の一部を表すブロック図が示されている。図１のＬＺ７７エンジン１０２は、ソート・エンジン１０４に対してトークン２１２を生成する。トークン２１２は、バック・ポインタ又はリテラルの文字列（単一のリテラル文字になる場合もある）のいずれかの表現になる。一実施形態では、トークン２１２は、リテラルの文字列の位置についての入力ブロック・メモリ１０１へのポインタ又はインデックスである。このような実施形態では、入力ブロック・メモリ１０１は、ソート・エンジン１０４によってアクセス可能である。代替の実施形態では、トークン２１２は、リテラル自体の文字列、例えば、文字列の文字の値である。一実施形態では、トークン２１２は、バック・ポインタの位置についてのポインタ・メモリ１０５へのポインタ又はインデックスである。このような実施形態では、ポインタ・メモリ１０５は、ソート・エンジン１０４によってアクセス可能である。代替の実施形態では、トークン２１２は、バック・ポインタ自体、例えば、バック・ポインタの長さ及び距離の値である。特に図３に関して下でより詳細に説明されているように、ソート・エンジン１０４は、テーブル・メモリ１０７内の頻度テーブル４０１及びソート済みリスト４０３の更新の進行状況に基づいて、ＬＺ７７エンジン１０２へのレディ信号２１４を発生させる。
【００２８】
図３〜８の検討から推測できるように、あるシンボルの頻度がソート済みリスト内で該シンボルの上にある他の複数のシンボルの頻度と同じであり、したがって、上記シンボルの頻度がインクリメントされたときにソート・エンジン１０４がシンボルをリスト４０３内の正しくソートされた位置へ到達させるように複数回の交換を実行する必要がある、異常な状態が生じる可能性がある。さらに、インクリメントされたシンボルの頻度は、その上にある、より後の辞書式順序の値を持つ複数のシンボルの頻度に等しくなる可能性があり、したがって、シンボルの頻度がインクリメントされたとき、ソート・エンジン１０４は、シンボルをリスト４０３内の正しくソートされた位置へ到達させるように複数回の交換を実行する必要がある。ソート・エンジン１０４がビジーになり、トークン２１２をＬＺ７７エンジン１０２から受信できない場合、入力ブロックの圧縮を実行するために必要な時間が増加する可能性がある。
【００２９】
一般的に言えば、シンボルの頻度の分布が相対的に均一な場合に、このような異常な状態が生じやすくなる。この状態は、すべての頻度がゼロに初期化されているときに、入力バッファのスキャンの初期に発生しやすい。頻度が等しくない値に初期化される、図１４Ａ〜１４Ｃ及び図１６に関して下で説明されているような実施形態は、異常な状態が発生する見込みを減らす長所を有し得ることに、注目するべきである。
【００３０】
一実施形態では、ハードウェア・データ圧縮器１００は、ＬＺ７７圧縮エンジン１０２とソート・エンジン１０４との間に短期の先入先出（ｆｉｒｓｔ−ｉｎ  ｆｉｒｓｔ−ｏｕｔ：ＦＩＦＯ）メモリを含み、このＦＩＦＯメモリは、ＬＺ７７圧縮エンジン１０２からソート・エンジン１０４に提供されるトークン２１２をバッファリングして、必要な場合に異常な状態の影響を減らすか、場合によっては除去する。ＦＩＦＯによるフル・フラグの出力は、ＬＺ７７圧縮エンジン１０２に対するレディ信号２１４としての役割を果たす。
【００３１】
ここで図２Ｂを参照すると、図２ＡのＬＺ７７エンジン１０２及びソート・エンジン１０４の動作を表すタイミング図が示されている。上側部分はＬＺ７７エンジン１０２の動作を示し、下側部分はソート・エンジン１０４の動作を示している。時間は、左から右に進んでいる。図に示されている時間は単位を持たず、相対的な時間を表すために使用されている。しかし、上記時間は、クロック・サイクル、ナノ秒、又はその他の関連する時間単位の代表であり得る。
【００３２】
図に示されているように、時間０で、ＬＺ７７エンジン１０２が、（例えば、図３のブロック３０２でのように）現在の検索位置での入力ブロックのスキャンを開始して文字列の一致を検索し、時間６で、トークンＮで示されるトークン２１２をソート・エンジン１０４に出力する。それに応答して、ソート・エンジン１０４は、（例えば、図３のブロック３１６でのように）トークンＮに関連付けられた各シンボルの頻度をインクリメントし、シンボルのソート済みリスト（例えば、図４のソート済みリスト４０３）を再ソートして、シンボル間における頻度（及び辞書式順序）でソートされた順序を維持し、時間１２で終了する。その後、ＬＺ７７エンジン１０２は、次の検索を終了し、時間１８でトークンＮ＋１を出力する。それに応答して、ソート・エンジン１０４は、トークンＮ＋１に関連付けられた各シンボルの頻度をインクリメントし、シンボルのソート済みリストを再ソートして、頻度でソートされた順序を維持し、時間２５で終了する。その後、ＬＺ７７エンジン１０２は、次の検索を終了し、時間３８でトークンＮ＋２を出力する。それに応答して、ソート・エンジン１０４は、トークンＮ＋２に関連付けられた各シンボルの頻度をインクリメントし、シンボルのソート済みリストを再ソートして、ソートされた順序を維持し、時間４７で終了する。その前に、ＬＺ７７エンジン１０２は、次の検索を終了し、トークンＮ＋３を出力する。この場合、レディ信号２１４がＬＺ７７エンジン１０２をストールさせ、ソート・エンジン１０４のソート完了を待機することになる（ただし、前述したように、実施形態にＦＩＦＯが存在し、且つＦＩＦＯがフルではない場合を除く）。
【００３３】
図２Ｂに示されているように、有利なことに、ＬＺ７７エンジン１０２が入力ブロックをスキャンすることと同時に、ソート・エンジン１０４は頻度でソートされたシンボルのリストをインクリメンタルに持続させ、したがって、シンボルのソート済みリストを維持するために必要な時間は、本明細書でより詳細に説明されているように、入力ブロックのスキャン時間の背後に隠れる。
【００３４】
ここで図３を参照すると、図２ＡのＬＺ７７エンジン１０２及びソート・エンジン１０４の動作を表すフローチャートが示されている。図３において、ＬＺ７７エンジン１０２はブロック３０２〜３０８における動作を実行し、ソート・エンジン１０４はブロック３１２〜３１８における動作を実行している。フローは、ブロック３０２から始まる。
【００３５】
３０２で、ＬＺ７７エンジン１０２は入力ブロックをスキャンし、入力ブロック内の現在の検索ターゲット位置における文字列の一致を検索する。フローは、判定ブロック３０４に進む。
【００３６】
判定ブロック３０４で、ＬＺ７７エンジン１０２はレディ信号２１４を調べて、ソート・エンジン１０４がＬＺ７７エンジン１０２からトークン２１２を受信する準備ができているかを決定する。準備ができている場合、フローはブロック３０６に進み、準備ができていない場合、ソート・エンジン１０４が準備ができるまでは、フローは判定ブロック３０４に戻る。
【００３７】
ブロック３０６で、ＬＺ７７エンジン１０２はソート・エンジン１０４に対してトークン２１２を生成する。フローはＬＺ７７エンジン１０２に関するブロック３０８に進み、同時に、フローはソート・エンジン１０４に関する判定ブロック３１２に進む。
【００３８】
ブロック３０８で、ＬＺ７７エンジン１０２は現在の検索ターゲット位置を更新する。フローはＬＺ７７エンジン１０２に関するブロック３０２に戻って、ブロック終結文字に直面するまで次の文字列を検索する。
【００３９】
判定ブロック３１２で、ソート・エンジン１０４は、ＬＺ７７エンジン１０２がソート・エンジン１０４のためにトークン２１２を生成したかどうかを決定する。生成していた場合、フローはブロック３１４に進み、生成していない場合、ＬＺ７７エンジン１０２がトークン２１２を生成するまでは、フローは判定ブロック３１２に戻る。
【００４０】
ブロック３１４で、ソート・エンジン１０４は、レディ信号２１４上でｆａｌｓｅ値を出力する。フローはブロック３１６に進む。
【００４１】
ブロック３１６で、ＬＺ７７エンジン１０２から受信されたトークン２１２の各シンボルについて、ソート・エンジン１０４は、図５に関して下でより詳細に説明されているように、シンボルの頻度（例えば、図４の４０２）をインクリメントし、シンボルの出現頻度及び辞書式順序に従ってソート済みリスト（例えば、図４の４０３）を維持する。フローはブロック３１８に進む。
【００４２】
ブロック３１８で、ソート・エンジン１０４は、レディ信号２１４上でｔｒｕｅ値を出力する。フローは判定ブロック３１２に戻る。
【００４３】
前述したように、通常、ソート・エンジン１０４は、ＬＺ７７エンジン１０２がブロック３０２における動作を実行するよりも少ない時間において、ブロック３１６における動作を実行する。その結果、ＬＺ７７エンジン１０２によって生成されたトークンに応答してブロック３１６でソート・エンジン１０４がシンボルのソート済みリストを維持するのに必要とされる時間は、通常、ブロック３０２でＬＺ７７エンジン１０２が次のトークンを生成するのに必要とされる時間の背後に有利に隠れる。これは、本発明者らの観察によれば、シンボルの頻度値は１ずつしか変化せず、その結果、ソート済みシンボル・リスト内でのシンボルの場所を変更する必要がない可能性が非常に高く、変更する必要がある場合でも、ソート済みリスト内のシンボルの場所を短い距離ずつ変更するだけで済む可能性が非常に高く、上記のことを、ソート・エンジン１０４は通常、ＬＺ７７エンジン１０２の文字列検索よりも速く実行することができるからである。
【００４４】
ここで図４を参照すると、図１のソート・エンジン１０４によって使用するための頻度テーブル４０１、ソート済みリスト４０３、及びテール・ポインタ４０７を表すブロック図が示されている。頻度テーブル４０１は、各々が２つのフィールドを有するエントリの配列であり、２つのフィールドとは、頻度フィールド４０２及びソート済みインデックス・フィールド４０４である。各エントリは、図１のハフマン・エンコーディング・エンジン１０８によってエンコードされるべきシンボルのシンボル空間のうちの異なるシンボルに関連付けられている。シンボルの値は、頻度テーブル４０１へのインデックスである。シンボルの頻度４０２は、そのシンボルがＬＺ７７エンジン１０２の出力ストリームに現れるたびに更新される。図４の実施形態例では、シンボル空間は、頻度テーブル４０１のインデックスを指す（index  into）値０〜２８５を含む。シンボル空間の値０〜２８５は、ＤＥＦＬＡＴＥ仕様で規定されたリテラル及び長さシンボルに対応する。ただし、他のシンボル・アルファベットが採用され、（例えば、図２Ｂに示されるように）ハードウェア圧縮エンジンが入力ブロックをスキャンすると同時にハードウェア・ソート・エンジンが頻度でソートされたシンボルのリストをインクリメンタルに持続させる上記記載のアプローチを使用する、他の実施形態が企図される。図５に関して下でより詳細に説明されているように、シンボル値によってインデックスを指された頻度テーブル４０１内のエントリのソート済みインデックス４０４は、ソート・エンジン１０４がシンボル値４０６をソートした、ソート済みリスト４０３内のエントリを指し示す。
【００４５】
ソート済みリスト４０３は、頻度テーブル４０１と同じ数のエントリを含む配列である。ソート済みリスト４０３の先頭のエントリ、エントリ０は、ＬＺ７７エンジン１０２の出力ストリーム内で最も頻繁に出現したシンボルのシンボル値４０６を保持し、エントリ１は、ＬＺ７７エンジン１０２の出力ストリーム内で次に最も頻繁に出現したシンボルのシンボル値４０６を保持する、などのようになる。同じ回数出現したシンボルは、辞書式順序で現れ、すなわち、より小さいシンボル値４０６は、リスト４０３内で、より大きいシンボル値４０６よりも高いところにソートされる。したがって、ソート済みリスト４０３へのインデックスは、シンボルの出現頻度及び辞書式順序の値による順序を示し、該シンボルの値４０６は、ソート済みリスト４０３のインデックスを指されたエントリに格納される。
【００４６】
有利なことに、ソート済みリスト４０３は、本質的に頻度テーブル４０１を逆に指している。つまり、ソート済みリスト４０３のエントリ内のシンボル値４０６は、ソート済みリスト４０３のエントリ内にあるシンボルについて、頻度テーブル４０１へのインデックスである。したがって、現在のシンボルの値から始めて（すなわち、該シンボルの頻度４０２がインクリメントされている）、現在のシンボルの１エントリ上のシンボルの頻度４０２は、ソート済みリスト４０３の１つ上のエントリ内のシンボル値４０６を使用して頻度テーブル４０１のインデックスを指すことによって、頻度テーブル４０１から取得されることが可能である。これにより、２つの頻度４０２の比較が（例えば、図５のブロック５１２及び５１６で）実行されて、（例えば、図５のブロック５１４及び５２２で）現在のシンボルがソート済みリスト４０３内で上に移動される必要があるかどうかを決定することができる。
【００４７】
テール・ポインタ４０７は、ソート済みリスト４０３内で使用可能な次のエントリを指し示し、そのエントリの位置に、ＬＺ７７エンジン１０２の出力ストリーム内で新しく現れる次のシンボルが配置される。テール・ポインタ４０７におけるエントリと該エントリの下のエントリとは、空である。
【００４８】
１つの頻度テーブル４０１と１つのソート済みリスト４０３のみが（例えば、リテラル及び長さに対して）示されているが、距離に対しては別の頻度テーブル及びソート済みリストが維持されることが理解されるべきである。ＤＥＦＬＡＴＥ仕様の実施形態では、距離の頻度テーブル４０１及び距離のソート済みリスト４０３は、リテラル及び長さに対して示されている２８６個のエントリではなく、それぞれ３０個のエントリ（０〜２９としてインデックスを指される）を有する。
【００４９】
図４では、頻度テーブル４０１とソート済みリスト４０３の使用方法を説明するために、さまざまな値の例が示されている。例えば、頻度テーブル４０１の頻度のエントリ１は、１８０の頻度４０２及び２４のソート済みインデックス４０４を有し、このインデックスは、ソート済みリスト４０３のエントリ２４を指し示し、このエントリはシンボル値１を有している。同様に、頻度テーブル４０１のエントリ３は、２０の頻度４０２及び１３７のソート済みインデックス４０４を有し、このインデックスは、ソート済みリスト４０３のエントリ１３７を指し示し、このエントリはシンボル値３を有している。頻度テーブル４０１のエントリ２７は、１８０の頻度４０２及び２５のソート済みインデックス４０４を有し、このインデックスは、ソート済みリスト４０３のエントリ２５を指し示し、このエントリはシンボル値２７を有している。頻度テーブル４０１のエントリ２９は、１８１の頻度４０２及び２３のソート済みインデックス４０４を有し、このインデックスは、ソート済みリスト４０３のエントリ２３を指し示し、このエントリはシンボル値２９を有している。頻度テーブル４０１のエントリ２７９は、１０００の頻度４０２及び１のソート済みインデックス４０４を有し、このインデックスは、ソート済みリスト４０３のエントリを指し示し、このエントリはシンボル値２７９を有している。これらの値は、図５に従ってソート・エンジン１０４の動作を示すために、図６〜８において説明の目的で使用される。
【００５０】
ここで図５を参照すると、図３のブロック３１６の実施形態による図１のソート・エンジン１０４の動作を表すフローチャートが示されている。以下の図５の説明では、ソート・エンジン１０４の動作を説明するために擬似コードが提供されているが、ソート・エンジン１０４はソフトウェアというよりも、ハードウェアで表現されたさまざまな動作を実行するハードウェア・エンジンであるということが理解されるべきである。フローは、ブロック５０２から始まる。
【００５１】
ブロック５０２で、ソート・エンジン１０４はＬＺ７７エンジン１０２からトークン２１２を受け取り、トークン２１２に関連付けられたシンボルを決定する。図５は、トークン２１２に関連付けられた１つのシンボルに関するソート・エンジン１０４の動作を表しているが、ソート・エンジン１０４は、すべてのシンボルに対して動作を実行する。前述したように、トークン２１２がバック・ポインタである場合、トークン２１２は２つの関連付けられたシンボル、すなわち、バック・ポインタの長さ及び距離を有する。一方、トークン２１２がリテラル文字列である場合、トークン２１２は、その文字列の文字の数と同じ数の関連付けられたシンボルを有し、該シンボルは、文字列の文字値である。例えば、１５個の文字から成るＡＳＣＩＩリテラル文字列のトークン２１２「Ｔｈｉｓ  ｉｓ  ｔｈｅ  ｄａｙ」は、１５個のシンボル、すなわち、「Ｔ」、「ｈ」、「ｉ」、「ｓ」、「  」、「ｉ」、「ｓ」、「  」、「ｔ」、「ｈ」、「ｅ」、「  」、「ｄ」、「ａ」、「ｙ」、又は数値的に、８４、１０４、１０５、１１５、３２、１０５、１１５、３２、１１６、１０４、１０１、３２、１００、９７、１２１を有する。フローは、判定ブロック５０４に進む。次の擬似コードは、ブロック５０２で実行される動作を示している。
ｉｎｃｒｅｍｅｎｔ  ｆｒｅｑ＿ｔｂｌ［ｔｈｉｓ＿ｓｙｍｂｏｌ＿ｖａｌ］．ｆｒｅｑ
【００５２】
判定ブロック５０４で、ソート・エンジン１０４は、これがシンボルの最初の出現であるかどうかを、好ましくは頻度テーブル４０１内のシンボルの頻度４０２の値を調べることによって決定する。これが最初の出現である場合、フローはブロック５０６に進み、そうでない場合、フローは判定ブロック５０８に進む。次の擬似コードは、ブロック５０４で実行される動作を示している。
ｉｆ  （ｆｒｅｑ＿ｔｂｌ［ｔｈｉｓ＿ｓｙｍｂｏｌ＿ｖａｌ］．ｆｒｅｑ  ＝＝  １）
【００５３】
ブロック５０６で、ソート・エンジン１０４はシンボルをソート済みリスト４０３の末尾に（例えば、テール・ポインタ４０７によって指し示されたエントリに）挿入し、テール・ポインタ４０７を更新する（例えば、インクリメントする）。フローはブロック５０６で終了する。次の擬似コードは、ブロック５０６で実行される動作を示している。
ｆｒｅｑ＿ｔｂｌ［ｔｈｉｓ＿ｓｙｍｂｏｌ＿ｖａｌ］．ｓｏｒｔｅｄ＿ｉｄｘ  ＝  ｔａｉｌ＿ｐｔｒ
ｓｏｒｔｅｄ＿ｌｉｓｔ［ｔａｉｌ＿ｐｔｒ］  ＝  ｔｈｉｓ＿ｓｙｍｂｏｌ＿ｖａｌ
ｉｎｃｒｅｍｅｎｔ  ｔａｉｌ＿ｐｔｒ
【００５４】
判定ブロック５０８で、ソート・エンジン１０４は、シンボルがソート済みリスト４０３の先頭にあるかどうかを決定する。先頭にある場合、フローが終了し、先頭にない場合、フローは判定ブロック５１２に進む。次の擬似コードは、ブロック５０８で実行される動作を示している。
ｉｆ  （ｆｒｅｑ＿ｔｂｌ［ｔｈｉｓ＿ｓｙｍｂｏｌ＿ｖａｌ］．ｓｏｒｔｅｄ＿ｉｄｘ  ＝＝  ０）
【００５５】
判定ブロック５１２で、ソート・エンジン１０４は、シンボルの頻度４０２がソート済みリスト４０３内のその上にあるシンボルの頻度４０２よりも大きいかどうかを決定する。大きい場合、フローはブロック５１４に進み、そうでない場合、フローは判定ブロック５１６に進む。次の擬似コードは、ブロック５１２で実行される動作を示している。
Ｘ  ＝  ｆｒｅｑ＿ｔｂｌ［ｔｈｉｓ＿ｓｙｍｂｏｌ＿ｖａｌ］．ｆｒｅｑ
ｔｈｉｓ＿ｓｏｒｔｅｄ＿ｉｄｘ  ＝  ｆｒｅｑ＿ｔｂｌ［ｔｈｉｓ＿ｓｙｍｂｏｌ＿ｖａｌ］．ｓｏｒｔｅｄ＿ｉｄｘ
ａｂｏｖｅ＿ｓｙｍｂｏｌ＿ｖａｌ  ＝  ｓｏｒｔｅｄ＿ｌｉｓｔ［ｔｈｉｓ＿ｓｏｒｔｅｄ＿ｉｄｘ  −  １］
Ｙ  ＝  ｆｒｅｑ＿ｔｂｌ［ａｂｏｖｅ＿ｓｙｍｂｏｌ＿ｖａｌ］．ｆｒｅｑ
ｉｆ  （Ｘ  ＞  Ｙ）
【００５６】
ブロック５１４で、ソート・エンジン１０４は、シンボルをソート済みリスト４０３内で上に移動する。つまり、ソート・エンジン１０４は、ソート済みリスト４０３内のシンボルの場所と、ソート済みリスト４０３内の上にあるエントリ内のシンボルの場所を交換する。これによって、ソート済みリスト４０３の関連するエントリ内のシンボル値４０６が更新されるだけでなく、頻度テーブル４０１の関連するエントリのソート済みインデックス４０４の値も更新される。フローは、ブロック５１４から判定ブロック５０８に戻り、シンボルをソート済みリスト４０３内で再び上に移動する必要があるかどうかを決定する。次の擬似コードは、ブロック５１４及びブロック５２２で実行される動作を示している。
ｄｅｃｒｅｍｅｎｔ  ｆｒｅｑ＿ｔｂｌ［ｔｈｉｓ＿ｓｙｍｂｏｌ＿ｖａｌ］．ｓｏｒｔｅｄ＿ｉｄｘ
ｉｎｃｒｅｍｅｎｔ  ｆｒｅｑ＿ｔｂｌ［ａｂｏｖｅ＿ｓｙｍｂｏｌ＿ｖａｌ］．ｓｏｒｔｅｄ＿ｉｄｘ
ｓｏｒｔｅｄ＿ｌｉｓｔ［ｔｈｉｓ＿ｓｏｒｔｅｄ＿ｉｄｘ］  ＝  ａｂｏｖｅ＿ｓｙｍｂｏｌ＿ｖａｌ
ｓｏｒｔｅｄ＿ｌｉｓｔ［ｔｈｉｓ＿ｓｏｒｔｅｄ＿ｉｄｘ  −  １］  ＝  ｔｈｉｓ＿ｓｙｍｂｏｌ＿ｖａｌ
【００５７】
判定ブロック５１６で、ソート・エンジン１０４は、シンボルの頻度４０２がソート済みリスト４０３内のその上にあるシンボルの頻度４０２に等しいかどうかを決定する。等しい場合、フローは判定ブロック５１８に進み、そうでない場合、フローは終了する。次の擬似コードは、ブロック５１６で実行される動作を示している。
Ｘ  ＝  ｆｒｅｑ＿ｔｂｌ［ｔｈｉｓ＿ｓｙｍｂｏｌ＿ｖａｌ］．ｆｒｅｑ
ｔｈｉｓ＿ｓｏｒｔｅｄ＿ｉｄｘ  ＝  ｆｒｅｑ＿ｔｂｌ［ｔｈｉｓ＿ｓｙｍｂｏｌ＿ｖａｌ］．ｓｏｒｔｅｄ＿ｉｄｘ
ａｂｏｖｅ＿ｓｙｍｂｏｌ＿ｖａｌ  ＝  ｓｏｒｔｅｄ＿ｌｉｓｔ［ｔｈｉｓ＿ｓｏｒｔｅｄ＿ｉｄｘ  −  １］
Ｙ  ＝  ｆｒｅｑ＿ｔｂｌ［ａｂｏｖｅ＿ｓｙｍｂｏｌ＿ｖａｌ］．ｆｒｅｑ
ｉｆ  （Ｘ  ＝＝  Ｙ）
【００５８】
判定ブロック５１８で、ソート・エンジン１０４は、シンボルの値の辞書式順序が、ソート済みリスト４０３内のその上にあるシンボルの値の辞書式順序よりも先かどうか（つまり、値が小さいかどうか）を決定する。小さい場合、フローは判定ブロック５２２に進み、そうでない場合、フローは終了する。次の擬似コードは、ブロック５１８で実行される動作を示している。
ｉｆ  （ｔｈｉｓ＿ｓｙｍｂｏｌ＿ｖａｌ  ＜  ｓｏｒｔｅｄ＿ｌｉｓｔ［ｔｈｉｓ＿ｓｙｍｂｏｌ＿ｖａｌ−１］）
【００５９】
判定ブロック５２２で、ソート・エンジン１０４は、上のブロック５１４に関して説明したのと同様の方法で、シンボルをソート済みリスト４０３内で上に移動する。フローは、ブロック５２２から判定ブロック５１６に戻って、シンボルをソート済みリスト４０３内で再び上に移動する必要があるかどうかを決定する。
【００６０】
ここで図６を参照すると、ソート・エンジン１０４によって更新された図４の頻度テーブル４０１、ソート済みリスト４０３、及びテール・ポインタ４０７を表すブロック図が示されている。図６は、図４の頻度テーブル４０１及びソート済みリスト４０３の、ソート・エンジン１０４が受信したシンボル２７を処理した後の状態を表している。具体的には、ソート・エンジン１０４は、頻度テーブル４０１のインデックス２７にある頻度４０２を、図５のブロック５０２に従って１８０から１８１にインクリメントしている。さらにソート・エンジン１０４は、図５の判定ブロック５１２で、シンボル２７の頻度４０２（１８１）が、図４のソート済みリスト４０３内のその上にあったシンボル（シンボル１）の頻度４０２（シンボル１は１８０の頻度を有する）よりも大きいと決定している。その結果、図５のブロック５１４に従い、ソート・エンジン１０４はソート済みリスト４０３内のシンボル２７の位置とシンボル１の位置を交換している。これによって、エントリ２４のシンボル値４０６が１から２７に変更され、エントリ２５のシンボル値４０６が２７から１に変更されている。さらに、これによってソート済みインデックス４０４の各値が交換されており、好ましくはソート・エンジン１０４によって、シンボル１のソート済みインデックス４０４が２４から２５にインクリメントされ、シンボル２７のソート済みインデックス４０４が２５から２４にデクリメントされる。これらの変更は、図６で、変更された値を含む灰色の長方形と、変更されたソート済みインデックス４０４のポインタ値に対応する破線矢印で強調表示されている。
【００６１】
ここで図７を参照すると、ソート・エンジン１０４によって更新された図６の頻度テーブル４０１、ソート済みリスト４０３、及びテール・ポインタ４０７を表すブロック図が示されている。図７は、図６の頻度テーブル４０１及びソート済みリスト４０３の、ソート・エンジン１０４が受信したシンボル２７をさらに処理した後の状態を表している。具体的には、ソート・エンジン１０４は、図５の判定ブロック５１６で、シンボル２７の頻度４０２（１８１）が、図６のソート済みリスト４０３内のその上にあったシンボル（シンボル２９）の頻度４０２（シンボル２９もまた１８１の頻度を有する）に等しいと決定しており、また、ソート・エンジン１０４は、判定ブロック５１８で、シンボル２７の値がソート済みリスト４０３内のその上にあるシンボル２９の値よりも辞書的に前であると決定している。その結果、図５のブロック５２２に従い、ソート・エンジン１０４はソート済みリスト４０３内のシンボル２７の位置とシンボル２９の位置を交換している。これによって、エントリ２３のシンボル値４０６が２９から２７に変更され、エントリ２４のシンボル値４０６が２７から２９に変更されている。さらに、これによってソート済みインデックス４０４の各値が交換されており、好ましくはソート・エンジン１０４によって、シンボル２９のソート済みインデックス４０４が２３から２４にインクリメントされ、シンボル２７のソート済みインデックス４０４が２４から２３にデクリメントされる。これらの変更は、図７で、変更された値を含む灰色の長方形と、変更されたソート済みインデックス４０４のポインタ値に対応する破線矢印で強調表示されている。
【００６２】
ここで図８を参照すると、ソート・エンジン１０４によって更新された図７の頻度テーブル４０１、ソート済みリスト４０３、及びテール・ポインタ４０７を表すブロック図が示されている。図８は、図７の頻度テーブル４０１及びソート済みリスト４０３の、ソート・エンジン１０４が受信したシンボル２８３を処理した後の状態を表している。具体的には、ソート・エンジン１０４は、頻度テーブル４０１のインデックス２８３にある頻度４０２を、図５のブロック５０２に従って０から１にインクリメントしている。さらに、ソート・エンジン１０４は、図５の判定ブロック５０４で、これがシンボル２８３の最初の出現であると決定している。その結果、図５のブロック５０６に従い、ソート・エンジン１０４は、シンボル２８３をソート済みリスト４０３の末尾（図８の例では、ソート済みリスト４０３のインデックス２７８）に挿入している。これによって、シンボル値２８３が、図７のテール・ポインタ４０７によって指し示されたエントリのシンボル値４０６のフィールド（例では、エントリ２７８）に挿入されている。さらに、これによって図７のテール・ポインタ値４０７（２７８）が、頻度テーブル４０１のエントリ２８３のソート済みインデックス４０４に格納されている。さらに、ソート・エンジン１０４は、テール・ポインタ４０７を２７８から２７９にインクリメントしている。これらの変更は、図８で、変更された値を含む灰色の長方形と、変更されたソート済みインデックス４０４のポインタ値及びテール・ポインタ４０７の値に対応する破線矢印で強調表示されている。
【００６３】
図３〜８で説明された方法で動作することによって、ソート・エンジン１０４は、頻度及び辞書式順序でソートされたシンボル４０３のリストを、ＬＺ７７エンジン１０２による入力ブロックのスキャンの終了時、又は終了に極めて近い時点で効果的に提供する。つまり、シンボルのソート時間（図１０のタイミング図のブロック１００３で図示される）は、最後のトークンに関連付けられたシンボルのソート済みリスト内での位置の更新に必要になる可能性のある時間を除き、ＬＺ７７エンジン１０２による入力ブロックのスキャン時間（図１０のブロック１００２で図示される）に重ね合わせられ、その結果、図９に示された従来の圧縮時間よりも合計圧縮時間が減少する。さらに、ＬＺ７７出力トークンのストリームの最後のトークン２１２に関連付けられたシンボルの、ソート済みリスト４０３内の位置の更新に必要な時間も、ほとんどの場合、極めて短くなる。これは、この時点では、頻度テーブル４０１内の頻度の分布が相対的に不均一である可能性が高く、最後のシンボルの頻度４０２のインクリメントが、ほとんどの場合、ソート済みリスト４０３の更新を必要とせず、更新が必要な場合でも、１つ上に移動するだけで済む可能性が高いからである。実際、最後のシンボルは、一般にブロック終結シンボルであり、それ以前に見られていないため、ソート済みリストの末尾に挿入されることになる。したがって、ソート・エンジン１０４は、必ずリテラルになり、バック・ポインタから指されることのないブロック終結シンボルについて、専用のチェックを行うことができ、ゆえに、ブロック終結シンボルのためにハフマン・コード・テーブルの構築を遅らせる必要はない。
【００６４】
ここで図９を参照すると、従来方法におけるＤＥＦＬＡＴＥ方式入力ブロック圧縮に関連付けられた圧縮時間の構成要素をグラフィカルに表すタイミング図が示されている。圧縮の開始時に、ブロック９０２で、入力ブロックがスキャンされ、ＬＺ７７トークンのストリームが生成され、シンボルの出現頻度のヒストグラムが持続される。ブロック９０２が完了すると、ブロック９０３で、シンボルがその頻度による順序でソートされる。ブロック９０３が完了すると、ブロック９０４で、頻度でソートされたシンボルを使用してハフマン・コード・テーブルが構築される。ブロック９０４が完了すると、ブロック９０６で、ハフマン・コード・テーブルが使用されて、入力ブロックをハフマン・エンコードする、すなわち、ＬＺ７７トークン出力ストリームをハフマン・エンコードする。ブロック９０２、９０４、９０６、及び９０８に関連付けられた動作が連続して順番に実行され、その結果、合計圧縮時間は、図に示されるように、ブロック９０２、９０４、９０６、及び９０８のすべてに関連付けられた時間の合計になる。
【００６５】
ここで図１０を参照すると、本明細書に記載された同時シンボル・リスト・ソートの実施形態によるＤＥＦＬＡＴＥ方式入力ブロック圧縮に関連付けられた圧縮時間の構成要素をグラフィカルに表すタイミング図が示されている。圧縮の開始時に、ブロック１００２で、本明細書に記載されているように、ＬＺ７７エンジン１０２が入力ブロック・メモリ１０１内の複数の文字から成る入力ブロックをスキャンし、トークン２１２のストリームを生成し、例えば、図３のブロック３０２〜３０８に関して説明されているように、各々の生成されるトークン２１２について繰り返される。圧縮開始に極めて近い時点、すなわち、最初のトークン２１２がＬＺ７７エンジン１０２によって生成されたときに、ブロック１００３で、ソート・エンジン１０４は、例えば図３のブロック３１２〜３１８に関して説明されているように、出現頻度及び等しい頻度内での辞書式のシンボル順序でソートされたシンボルのリストを継続的に維持する。ブロック１００３での動作時間は、主としてブロック１００２での動作時間の背後に有利に隠れることができる。これは、前述したように、ＬＺ７７エンジン１０２によって生成されたトークンに応答して図３のブロック３１６でシンボルのソート済みリストを維持するためにソート・エンジン１０４によって必要とされる時間が、ほとんどのトークンについて、図３のブロック３０２で次のトークンを生成するためにＬＺ７７エンジン１０２によって必要とされる時間の背後に有利に隠れるからである。
【００６６】
ＬＺ７７エンジン１０２が複数の文字から成る入力ブロックのスキャンを完了し、ソート・エンジン１０４が（必要に応じて）最後のトークン２１２に関連付けられたシンボルについてソート済みリスト４０３の更新を完了した場合、ブロック１００４で、ハフマン・コード・テーブル構築エンジン１０６は、ソート済みリスト４０３を使用してハフマン・コード・テーブルを構築する。それから、ブロック１００６で、ハフマン・エンコーディング・エンジン１０８は、ブロック１００４で構築されたハフマン・コード・テーブルを使用して、複数の文字から成る入力ブロックを、より正確には、ＬＺ７７エンジン１０２により生成された置換バック・ポインタと入力ブロックの置換されていないリテラルとをエンコードし、圧縮された出力を出力メモリ１０９に書き込む。（ハフマン・コード・テーブルもまたハフマン・エンコードされ、出力メモリに書き込まれる。これにより、解凍器が、圧縮に使用されたハフマン・コード・テーブルを再形成することができる）。図９と図１０を比較することで観察できるように、ＬＺ７７エンジン１０２が入力ブロックをスキャンすると同時にソート・エンジン１０４がソート済みシンボル・リストを維持することによって、従来方法と比較して合計圧縮時間が有利に減少する。
【００６７】
ここで図１１Ａを参照すると、代替の実施形態によるソート済みリスト４０３を表すブロック図が示されている。図１１Ａの実施形態では、ソート済みリスト４０３の各エントリは、シンボル値４０６に関連付けられたハフマン・コード１１０８及びビット長１１１２をさらに含んでいる。この方法では、ハフマン・コード・テーブル構築エンジン１０６は、ソート済みリスト４０３のシンボルに対して、ハフマン・コード１１０８及び関連するビット長１１１２を割り当てることができる。好ましくは、ハフマン・コード・テーブル構築エンジン１０６は、標準的なハフマン・エンコーディングに従ってハフマン・コード１１０８を割り当てる。ビット長１１１２は、ハフマン・コード１１０８のビット数を示す。図１１Ａのソート済みリスト４０３の実施形態は、図４の頻度テーブル４０１と併せて、ハフマン・コード・テーブルとして使用されることが可能である。つまり、あるシンボル値（例えば、ＤＥＦＬＡＴＥ方式リテラル／長さテーブルの値０〜２８５、又はＤＥＦＬＡＴＥ方式距離テーブルの値０〜２９）を入力として与えられた場合、そのシンボル値は、頻度テーブル４０１へのインデックスとして使用されてシンボルのソート済みインデックス４０４の値を決定し、それから、このソート済みインデックス４０４の値は図１１Ａのソート済みリスト４０３のインデックスを指すように使用されて、シンボルに関連付けられたハフマン・コード１１０８が取得される。間接のレベルを回避してハフマン・コード・テーブルを実現する代替の実施形態が、図１１Ｂに関して以下で説明される。
【００６８】
ここで図１１Ｂを参照すると、代替の実施形態による頻度テーブル４０１を表すブロック図が示されている。図１１Ｂの実施形態では、頻度テーブル４０１の各エントリは、シンボルに関連付けられたハフマン・コード・フィールド１１０８及びビット長１１１２をさらに含み、上記シンボルの値は、頻度テーブル４０１へのインデックスである。この方法で、ハフマン・コード・テーブル構築エンジン１０６は、シンボルの値が頻度テーブル４０１のインデックスを指すシンボルに対してハフマン・コード１１０８と関連するビット長１１１２とを割り当て、（例えば、図１０のブロック１００４で）頻度テーブル４０１の一部として直接ルックアップ・ハフマン・コード・テーブルを構築することができる。
【００６９】
ここで図１２を参照すると、代替の実施形態による図１のハードウェア・データ圧縮器１００に関連付けられたハードウェアを表すブロック図が示されている。図１２のハードウェア・データ圧縮器１００は、ソート済みリスト変更フラグ１２０２及びソート済みリスト未変更カウンタ１２０４を含む。ソート・エンジン１０４がソート済みリスト４０３を（例えば、ブロック５１４及び５２２で）変更するたびに、ソート・エンジン１０４は、ソート済みリスト変更フラグ１２０２を設定し、ソート済みリスト未変更カウンタ１２０４をリセットする。ハフマン・コード・テーブル構築エンジン１０６は、（例えば、ブロック１００４で）ソート済みリスト４０３を使用してハフマン・コード・テーブルの構築を成功裏に完了するたびに、ソート済みリスト変更フラグ１２０２をクリアする。ハフマン・コード・テーブル構築エンジン１０６がハフマン・コード・テーブルの構築の処理中である場合、ソート・エンジン１０４がソート済みリスト４０３を変更すると、ハフマン・コード・テーブル構築エンジン１０６は、ハフマン・コード・テーブルの構築を停止し、それらの構築を再開する。ソート・エンジン１０４は、ＬＺ７７エンジン１０２がソート済みリスト４０３の変更を必要としないトークン２１２を生成するたびに、ソート済みリスト未変更カウンタ１２０４をインクリメントする。ソート済みリスト変更フラグ１２０２及びソート済みリスト未変更カウンタ１２０４の使用方法については、図１３に関する一実施形態で説明される。
【００７０】
ここで図１３を参照すると、代替の実施形態での圧縮時間の構成要素をグラフィカルに表すタイミング図が示されている。図１３の実施形態は図１０の実施形態に類似しているが、図１３の実施形態では、ブロック１００４がブロック１３０４で置き換えられている。ブロック１００２でＬＺ７７圧縮エンジン１０２が入力ブロックをスキャンすると同時に、且つブロック１００３でソート・エンジン１０４がソート済みリスト４０３を維持すると同時に、ブロック１３０４で、ハフマン・コード・テーブル構築エンジンが動作して、ハフマン・コード１１０８をソート済みリスト４０３のシンボル値４０６に割り当てる。その結果、ブロック１３０４でソート済みリスト４０３を使用してハフマン・コード・テーブルを構築するために必要な時間が、ブロック１００２での入力ブロックのスキャン時間及びブロック１００３でのソート済みリストの維持時間に大きく重ね合わせられ、隠され、これにより、合計圧縮時間がさらに減少する。好ましくは、図１３の実施形態は、図１２のソート済みリスト変更フラグ１２０２、及び、必要に応じてソート済みリスト未変更カウンタ１２０４を採用する。つまり、ソート・エンジン１０４は、（例えば、ブロック５１４又は５２２で）ソート済みリスト４０３を変更するたびに、ソート済みリスト変更フラグ１２０２を設定し、ハフマン・コード・テーブル構築エンジン１０６に通知し、応答的に、ハフマン・コード・テーブル構築エンジン１０６は、ソート済みリスト４０３内のシンボル値４０６を使用してハフマン・コード値１１０８の構築を開始する。ソート・エンジン１０４がソート済みリスト４０３を再び変更する前に、ハフマン・コード・テーブル構築エンジン１０６がハフマン・コード・テーブルの構築を成功裏に完了した場合、ハフマン・コード・テーブル構築エンジン１０６は、ソート済みリスト変更フラグ１２０２をクリアする。ブロック１００２で入力ブロックのスキャンが完了しているとき、ソート済みリスト変更フラグ１２０２がクリアされていると、ハフマン・エンコーディング・エンジン１０８は、ブロック１００６で入力ブロックのハフマン・エンコーディングを開始する。この方法で、ブロック１３０４でハフマン・コード・テーブルを構築するために必要な時間の一部、又は、場合によってはすべてが、ブロック１００２での入力ブロックのスキャン時間及びブロック１００３でのソート済みリストの維持時間と重ね合わせられ、隠される。
【００７１】
一実施形態では、ハフマン・コード・テーブル構築エンジン１０６は、ソート・エンジン１０４がソート済みリスト４０３を変更するたびに、ハフマン・コード値１１０８を構築する。しかし、代替の実施形態では、ソート・エンジン１０４がソート済みリスト４０３を変更したとき、ハフマン・コード・テーブル構築エンジン１０６は、ソート済みリスト未変更カウンタ１２０４が、ソート・エンジン１０４がソート済みリスト４０３を最後に変更して以降、所定数のトークン２１２が見られたことを示す場合にのみ、ハフマン・コード値１１０８の構築を開始する。上記所定数は、プログラム可能にすることができる。この方法では、ブロック１００２における入力ブロックのスキャンの間、ハフマン・コード・テーブル構築エンジン１０６が、ブロック１３０４における動作をより低い頻度で実行することになるため、ハードウェア・データ圧縮器１００の消費電力が削減され、テーブル・メモリ１０７へのアクセス輻輳を減らすことが可能である。ソート済みリスト未変更カウンタ１２０４を採用してハフマン・コード・テーブルの構築を抑制する実施形態について説明されているが、別の基準を使用する他の実施形態が企図される。例えば、ソート・エンジン１０４がソート済みリスト４０３を変更したとき、ハフマン・コード・テーブル構築エンジン１０６は、ソート・エンジン１０４が最後にソート済みリスト４０３を変更して以降、所定数のトークン２１２ではなく、所定数のシンボルが見られた場合にのみ、ハフマン・コード値１１０８の構築を開始する。別の例では、ソート・エンジン１０４がソート済みリスト４０３を変更したとき、ハフマン・コード・テーブル構築エンジン１０６は、ソート・エンジン１０４が最後にソート済みリスト４０３を変更して以降、所定数のトークン２１２ではなく、所定数のクロック・サイクルが経過した場合にのみ、ハフマン・コード値１１０８の構築を開始する。
【００７２】
ただし、入力ブロックのスキャンの初期では、頻度の分布が相対的に均一になる可能性が高いため、通常、ソート済みリスト４０３は頻繁に変更されることが注目される。しかし、入力ブロックのスキャンの後期では、前述したように、頻度の分布が相対的に不均一になる可能性が高いため、通常、ソート済みリスト４０３が変更される頻度は低くなる。したがって、場合によっては、ハフマン・コード・テーブル構築エンジン１０６によるハフマン・コード値１１０８の最後の構築は、入力ブロックのスキャンが完了されるかなり前に始まることになり、場合によっては、ハフマン・コード値１１０８の最後の構築は、入力ブロックのスキャンが完了される前に完了することになる。例えば、最後のＮ個のトークン２１２がソート済みリスト４０３における変更を引き起こさず、入力ブロックをスキャンして最後のＮ個のトークン２１２を生成するためにＬＺ７７エンジン１０２によって費やされる時間が、少なくとも、ソート済みリスト４０３からハフマン・コード・テーブルを構築するためにハフマン・コード・テーブル構築エンジンによって必要とされる時間と同じくらい大きい場合である。
【００７３】
可逆圧縮アルゴリズム（例えば、ＬＺ７７）を採用する圧縮エンジンによってトークン・ストリームが生成されるのと同時に、ソート・エンジンがトークン・ストリーム内の出現頻度でソートされたシンボルのリストを維持するハードウェア・データ圧縮器の実施形態が説明されたが、不可逆圧縮アルゴリズム（ＪＰＥＧ、ＭＰＥＧ、ＭＰ３）を採用する圧縮エンジンによってトークン・ストリームが生成されるのと同時に、ソート・エンジンがトークン・ストリーム内の出現頻度でソートされたシンボルのリストを維持し、その後、その出力が、ソート済みシンボル・リストからの恩恵を受けるエンコーディング・エンジン（例えば、ハフマン・エンコーディング）によって、コード・テーブルを構築するためにエンコードされる他の実施形態が企図されるということが理解されるべきである。
【００７４】
従来方法での（すなわち、本明細書に記載されているような、入力ブロックのスキャンと同時のインクリメンタルな方法ではない）シンボルのリストのソートは、通常、メモリを大量に使用するということに注目するべきである。このことは、システム・メモリなどの大量のメモリへのアクセスを一般に有するソフトウェア・データ圧縮プログラム（例えば、ｇｚｉｐ）にとっては、問題にならない可能性がある。しかし、大量のメモリの使用は、相対的に少量のメモリを使用することが望ましいハードウェア・データ圧縮器にとって、ハードウェア・データ圧縮器上のメモリが大きくなるほどメモリへのアクセス待ち時間が大きくなるため、コストと性能の両方の理由から望ましくない。したがって、ソート済みリストを、入力ブロックのスキャンと同時にインクリメンタルに維持することは、ハードウェア・データ圧縮器の実施形態にとって特に有利である。
【００７５】
「ダイナミック−プライム」ハフマン・コーディング
ここで図１４Ａを参照すると、ダイナミック−プライム・ハフマン・エンコーディングと連動してデータ圧縮を実行するための図１のＬＺ７７エンジン１０２の動作を表すフローチャートが示されている。好ましくは、図１４ＡでのＬＺ７７エンジン１０２の動作は、図１４Ｂによるハフマン・コード・テーブル構築エンジン１０６の動作と連動し、且つ図１４Ｃによるハフマン・エンコーディング・エンジン１０８の動作と連動して実行され、したがって、例えば図１６に示されるように、３つの動作の大部分が同時に実行されて、複数の文字から成る入力ブロックのハードウェア・データ圧縮を実現する。フローは、ブロック１４０２から始まる。
【００７６】
ブロック１４０２で、ＬＺ７７エンジン１０２は、入力ブロック内の現在の検索ターゲット位置を初期化する。好ましくは、ハードウェア・データ圧縮器１００は、検索ターゲット位置の値を格納するレジスタ（図に示されていない）を含む。現在の検索ターゲット位置は、複数の文字から成る入力ブロックへのインデックスである。好ましくは、検索ターゲット位置は、入力ブロックの２番目の文字を指し示すように初期化される。フローはブロック１４０４に進む。
【００７７】
ブロック１４０４で、ＬＺ７７エンジン１０２は、入力ブロック内の検索ターゲット位置で始まる文字列の一致を検索する。つまり、ＬＺ７７エンジン１０２は、入力ブロック内の検索ターゲット位置で始まる文字の文字列、ターゲット文字列を取り込み、ターゲット文字列との一致について入力ブロックの以前の部分を検索する。一般的に言えば、ＬＺ７７エンジン１０２は、入力ブロック内の以前の部分で検出可能な最長の文字列の一致を検索する。ただし、ＬＺ７７エンジン１０２は、検索時間を削減し、及び／又はバック・ポインタの最大長を制限するために、検索される文字列の長さを制限することができる。さらに、ＬＺ７７エンジン１０２は、検索時間を削減し、及び／又はバック・ポインタの最大距離を制限するために、現在の検索ターゲット位置から後方に検索する距離を制限することができる。ＬＺ７７エンジン１０２は、現在の検索ターゲット位置の文字列との一致について、入力ブロック内の以前の部分を検索するために、さまざまな手法を採用することができ、それらの一部は、図２４及び２５に関して下で説明されている２つのハッシュ・テーブルの実施形態などについて、本明細書に記載されている。フローはブロック１４０６に進む。
【００７８】
ブロック１４０６で、ＬＺ７７エンジン１０２はトークン２１２を生成する。前述したように、トークン２１２は、バック・ポインタ又は入力ブロックからのリテラルのいずれかである。一実施形態では、入力ブロックからリテラルを生成することは、単にリテラルを入力ブロック・メモリ１０１内の適所に（in  place）残すことであるため、上記リテラルは、その後、ハフマン・エンコーディング・エンジン１０８によって入力ブロック・メモリ１０１から読み出され、ダイナミック−プライム・ハフマン・コード・テーブルを使用してハフマン・エンコードされることが可能である。一実施形態では、前述したように、バック・ポインタは、バック・ポインタ・メモリ１０５に書き込まれ、メモリ１０５内のフラグが、置換バック・ポインタの存在を示すように、置換される／一致したターゲット文字列の先頭の文字の入力ブロックでの位置に対応して設定される。ＬＺ７７エンジン１０２は、検索ターゲット位置をさらに更新する。好ましくは、ＬＺ７７エンジン１０２は、バック・ポインタを生成する場合、一致する文字列の長さずつ検索ターゲット位置をインクリメントし、一方、リテラルを生成する場合、生成されるリテラルの数ずつ検索ターゲット位置をインクリメントする。ソート・エンジン１０４を含む実施形態では、図３のブロック３１６でのように、ソート済みリスト４０３がさらに更新される。フローは、判定ブロック１４０８に進む。
【００７９】
判定ブロック１４０８で、ＬＺ７７エンジン１０２は、ダイナミック−プライム・ハフマン・コード・テーブルの構築を信号で伝えることができるように、複数の文字から成る入力ブロックの初期部分をスキャンしたかどうかを決定する。入力ブロックの初期部分は、さまざまな方法で決定されることが可能である。一実施形態では、ＬＺ７７エンジン１０２は、所定数の入力文字（例えば、３，０００文字）をスキャンした後に、初期部分をスキャンしたと決定する。一実施形態では、ＬＺ７７エンジン１０２は、入力ブロック・サイズのうちの所定部分（例えば、入力ブロックの複数の文字のうちの最初の１０分の１）をスキャンした後に、初期部分をスキャンしたと決定する。一実施形態では、ＬＺ７７エンジン１０２は、それまでの入力ブロック内で少なくとも第１の所定回数（例えば、１回、２回、３回）観測されたシンボル空間のシンボルの総数が、第２の所定値よりも大きい場合に、初期部分をスキャンしたと決定する。例えば、第１の所定回数を３と仮定すると、ハードウェア・データ圧縮器１００は、頻度４０２を３の値にインクリメントするたびに、ゼロに初期化されていたカウンタをインクリメントし、カウンタが第２の所定値（例えば、８５）に達したときに、初期部分のスキャンが完了する。第２の所定値は、シンボル空間内のシンボル数の所定パーセンテージ（例えば、３３％）にすることが可能である。一実施形態では、入力ブロックの初期部分は、図１８及び１９などに関して説明されているように、ソート済みリスト４０３に対する変更の発生に基づいて、好ましくはソート・エンジン１０４によって決定される。一実施形態では、初期部分は、例えば、ハードウェア・データ圧縮器への圧縮命令のオペランドとして、ユーザ指定されることが可能である。一般的に言えば、圧縮速度を犠牲にして圧縮効率を向上するには、より大きい初期部分の値が選択され、圧縮効率を犠牲にして圧縮速度を向上するには、より小さい初期部分の値が選択されることに注目するべきである。ＬＺ７７エンジン１０２が入力ブロックの初期部分のスキャンを完了した場合、フローはブロック１４１２に進み、そうでない場合、フローはブロック１４１４に進む。
【００８０】
ブロック１４１２で、ＬＺ７７エンジン１０２は、ハフマン・コード・テーブルを構築するようにハフマン・コード・テーブル構築エンジン１０６に信号で伝える。つまり、入力ブロックの初期部分のスキャンが完了しており、したがって、ハフマン・コード・テーブルが（例えば、図１４Ｂのブロック１４２４で）構築されることが可能であり、ハフマン・エンコーディングが（例えば、図１４Ｃのブロック１４３４で）開始可能である。フローはブロック１４０４に戻って、検索ターゲット位置の更新された値で一致を検索する。図１４Ａは、いったん初期部分がスキャンされているとブロック１４０４、１４０６、及び１４０８のループを通るたびにハフマン・コード・テーブルを構築するように信号で伝えることを示すように見えるが、この信号送信が実行されるのは１回だけであることが理解されるべきである。
【００８１】
ブロック１４１４で、頻度４０２は、ブロック１４０６で生成されたトークン２１２に関連付けられたシンボルの各々について更新される。一実施形態では、ソート・エンジン１０４が、各シンボルの頻度４０２をインクリメントする。別の実施形態では、ソート・エンジン１０４が存在せず、ＬＺ７７エンジン１０２が各シンボルの頻度４０２をインクリメントする。さらに別の実施形態では、ソート・エンジン１０４が存在せず、図２Ａに関して説明されている、ソート・エンジン１０４に提供するためにＬＺ７７エンジン１０２がトークン２１２を生成するのと同様の方法で、ＬＺ７７エンジン１０２がハフマン・コード・テーブル構築エンジン１０６に提供するためにトークン２１２を生成し、ハフマン・コード・テーブル構築エンジン１０６が各シンボルの頻度４０２をインクリメントする。フローはブロック１４０４に戻って、検索ターゲット位置の更新された値で一致を検索する。ブロックの終わりに達すると（例えば、ブロック終結文字に直面すると）、フローは終了し、ブロック１４１２、１４１４、又は１４１６からブロック１４０４に戻らず、図１４Ａに従う動作が次の入力ブロックに対して繰り返されることが理解されるべきである。
【００８２】
前述したように、入力ブロックの初期部分のスキャンが完了すると、頻度テーブル４０１内の頻度４０２は更新されなくなる。有利なことに、ハードウェア・データ圧縮器１０２は、入力ブロックの初期部分のスキャンが完了すると、頻度テーブル４０１の更新を停止し、その間、入力ブロックをスキャンする。これは、頻度４０２を更新するためのテーブル・メモリ１０７へのアクセス数が減少することによって、消費電力量が低減し、テーブル・メモリ１０７の競合が減少し、その他のエンジンがテーブル・メモリ１０７により素早くアクセスできるようになることにより、特にテーブル・メモリ１０７のポートが共有される実施形態において性能を改善することができるため、有利である。さらに、より少ないポートでのメモリの使用を容易にすることができるため、デザインを小さくすることができる。
【００８３】
ここで図１４Ｂを参照すると、ダイナミック−プライム・ハフマン・エンコーディングと連動してデータ圧縮を実行するための図１のハフマン・コード・テーブル構築エンジン１０６の動作を表すフローチャートが示されている。フローは、ブロック１４２２から始まる。
【００８４】
ブロック１４２２で、ハフマン・コード・テーブル構築エンジン１０６は、ハフマン・コード・テーブルを構築するための信号を受信する。一実施形態では、ＬＺ７７エンジン１０２が、ハフマン・コード・テーブルを構築するようにハフマン・コード・テーブル構築エンジン１０６に信号で伝える。一実施形態では、ソート・エンジン１０４が、ハフマン・コード・テーブルを構築するようにハフマン・コード・テーブル構築エンジン１０６に信号で伝える。フローはブロック１４２４に進む。
【００８５】
ブロック１４２４で、ハフマン・コード・テーブル構築エンジン１０６は、入力ブロックの初期部分のみのスキャン後の、すなわち、ブロック１４２２でハフマン・コード・テーブル構築エンジン１０６に信号が送信された時点での頻度４０２の値を有する頻度テーブル４０１を使用して、ダイナミック−プライム・ハフマン・コード・テーブルを構築する。図１７Ａ〜１７Ｃは、ダイナミック−プライム・ハフマン・コード・テーブルが構築される実施形態を表している。フローはブロック１４２６に進む。
【００８６】
ブロック１４２６で、ハフマン・コード・テーブル構築エンジン１０６は、ハフマン・エンコーディング・エンジン１０８に、入力ブロックのハフマン・エンコーディングを開始するように信号で伝える。フローはブロック１４２６で終了する。
【００８７】
ここで図１４Ｃを参照すると、ダイナミック−プライム・ハフマン・エンコーディングと連動してデータ圧縮を実行するための図１のハフマン・エンコーディング・エンジン１０８の動作を表すフローチャートが示されている。フローは、ブロック１４３２から始まる。
【００８８】
ブロック１４３２で、ハフマン・エンコーディング・エンジン１０８は、入力ブロックのハフマン・エンコーディングを開始するために図１４Ｂのブロック１４２６で発生された信号を受信する。フローはブロック１４３４に進む。
【００８９】
ブロック１４３４で、ハフマン・エンコーディング・エンジン１０８は、ブロック１４２４で構築されたハフマン・コード・テーブルを使用して入力ブロック全体をエンコードする。つまり、ハフマン・エンコーディング・エンジン１０８は、入力ブロックの初期部分のみのスキャンに基づいてブロック１４２４で構築されたハフマン・コード・テーブルを使用して、入力ブロック全体のバック・ポインタ及び置換されていないリテラルをハフマン・エンコードし、ハフマン・エンコードされた出力（及び、ハフマン・エンコードされたバージョンのハフマン・コード・テーブル）を出力メモリ１０９に格納する。フローはブロック１４３４で終了する。
【００９０】
ここで図１５を参照すると、従来方法におけるＤＥＦＬＡＴＥ方式入力ブロック圧縮に関連付けられた圧縮時間の構成要素をグラフィカルに表すタイミング図が示されている。圧縮時間の開始時に、ブロック１５０２で、入力ブロック全体がスキャンされ、ＬＺ７７トークンのストリームが生成され、シンボルの出現頻度のヒストグラムが持続される。ブロック１５０２が完了すると、ブロック１５０４で、入力ブロック全体に対して持続されたシンボルの頻度を使用して、ハフマン・コード・テーブルが構築される。ブロック１５０４が完了すると、ブロック１５０６でハフマン・コード・テーブルが使用されて、入力ブロックをハフマン・エンコードする、すなわち、ＬＺ７７トークン出力ストリームをハフマン・エンコードする。ブロック１５０２、１５０４、及び１５０６に関連付けられた動作が連続して順番に実行され、その結果、合計圧縮時間は、図に示されるように、ブロック１５０２、１５０４、及び１５０６のすべてに関連付けられた時間の合計になる。
【００９１】
ここで図１６を参照すると、本明細書に記載されたダイナミック−プライム・ハフマン・コード・テーブルの実施形態によるＤＥＦＬＡＴＥ方式入力ブロック圧縮に関連付けられた圧縮時間の構成要素をグラフィカルに表すタイミング図が示されている。圧縮時間の開始時に、ブロック１６０２−Ａで、本明細書に記載されているように、ＬＺ７７エンジン１０２が入力ブロック・メモリ１０１内の複数の文字から成る入力ブロックの初期部分をスキャンし、トークン２１２のストリームを生成し、例えば、図１４Ａ（及び図３のブロック３０２〜３０８）に関して説明されているように、各々の生成されるトークン２１２について繰り返される。入力ブロックの初期部分のスキャンが完了した後に、ハフマン・コード・テーブルを構築するように信号が（例えば、図１４Ａのブロック１４１２に従って）与えられ、ブロック１６０４で、ハフマン・コード・テーブル構築エンジン１０６が、（例えば、図１４Ｂのブロック１４２４に従って）ブロック１６０２−Ａでの入力ブロックの初期部分のスキャンの間に維持された頻度テーブル４０１の頻度４０２を使用して、ハフマン・コード・テーブルを構築する。さらに、ブロック１６０２−Ｂで、ＬＺ７７エンジン１０２は、入力ブロック・メモリ１０１内の複数の文字から成る入力ブロックの残りの部分を引き続きスキャンし、トークン２１２のストリームを生成する。
【００９２】
ハフマン・コード・テーブル構築エンジン１０６が、ブロック１６０４で初期部分の頻度を使用してダイナミック−プライム・ハフマン・コード・テーブルの構築を完了すると、ブロック１６０６で、ハフマン・エンコーディング・エンジン１０８が、ダイナミック−プライム・ハフマン・コード・テーブルを使用して、入力ブロック全体（又は、より正確には、ＬＺ７７エンジン１０２によって生成された置換バック・ポインタ及び入力ブロックの置換されていないリテラル）をハフマン・エンコードし、圧縮された出力を出力メモリ１０９に書き込む。従来方法で実行されていたような入力ブロック全体のスキャンからではなく、入力ブロックの初期部分のみのスキャンからの出現頻度を使用してダイナミック−プライム・ハフマン・コード・テーブルが構築されるため、ブロック１６０４及び１６０６での動作時間は、主としてブロック１６０２−Ｂでの動作時間の背後に有利に隠れることが可能である。図１５及び図１６を比較することによって観察できるように、ダイナミック−プライム・ハフマン・コード・テーブル、つまり、入力ブロックの初期部分のみのスキャンからの出現頻度を使用して構築されたハフマン・コード・テーブルを使用することで、合計圧縮時間が従来方法と比較して有利に削減される。
【００９３】
ここで図１７Ａを参照すると、一実施形態によるダイナミック−プライム・ハフマン・コード・テーブルを構築するためのハードウェア・データ圧縮器１００の動作を表すフローチャートが示されている。フローは、ブロック１７０２から始まる。
【００９４】
ブロック１７０２で、頻度テーブル４０１の頻度４０２は、例えばＬＺ７７エンジン１０２、ソート・エンジン１０４、又はハフマン・コード・テーブル構築エンジン１０６によって、ゼロに初期化される。フローはブロック１７０４に進む。
【００９５】
ブロック１７０４で、ＬＺ７７エンジン１０２は入力ブロックの初期部分をスキャンし、生成されたトークンに関連付けられたシンボルの頻度４０２が（例えば、ＬＺ７７エンジン１０２、ソート・エンジン１０４、又はハフマン・コード・テーブル構築エンジン１０６によって）インクリメントされる。フローはブロック１７０６に進む。
【００９６】
ブロック１７０６で、ハフマン・コード・テーブルの構築の初期部分で（例えば、ブロック１６０４で）ゼロの値の頻度４０２を有するシンボル空間内（例えば、リテラル及び長さテーブル４０１のシンボル値０〜２８５と、距離のテーブル４０１のシンボル値０〜２９）の各シンボルについて、ハフマン・コード・テーブル構築エンジン１０６（又は、代替の実施形態におけるソート・エンジン１０４）は、ゼロの値の頻度をゼロ以外の値で置換する。好ましくは、ゼロ以外の値は、小さい値、例えば、値１である。これは、ハフマン・コード・テーブルが構築されるときに、シンボル空間内の各シンボル値についてハフマン・コードが存在するようにするためである。これが必要なのは、前述したように、（例えば、ブロック１６０２−Ａで）入力ブロックの初期部分のスキャンに現れなかったシンボルが、（例えば、ブロック１６０２−Ｂで）入力のブロックの残りの部分のスキャンに現れる可能性があり、ハフマン・エンコーディング・エンジン１０８が、（例えば、ブロック１６０６で）入力ブロックをハフマン・エンコードするときに、ダイナミック−プライム・ハフマン・コード・テーブル内にそのシンボルのハフマン・コード値を必要とするからである。フローはブロック１７０８に進む。
【００９７】
ブロック１７０８で、ハフマン・コード・テーブル構築エンジン１０６は、ブロック１７０２〜１７０６に従って作成された頻度テーブル４０１の頻度４０２を使用して、ハフマン・コード・テーブルを構築する。重要なことに、構築されたダイナミック−プライム・ハフマン・コード・テーブルは、各シンボルがゼロ以外の頻度４０２の値を持っているため、シンボル空間内の各シンボルについてハフマン・コード値を含むことになる。前述したように、好ましくは、ハフマン・コード・テーブル構築エンジン１０６は、標準的なハフマン・コード・テーブルを構築する。フローはブロック１７０８で終了する。
【００９８】
ここで図１７Ｂを参照すると、一実施形態によるダイナミック−プライム・ハフマン・コード・テーブルを構築するためのハードウェア・データ圧縮器１００の動作を表すフローチャートが示されている。フローは、ブロック１７１２から始まる。
【００９９】
ブロック１７１２で、頻度テーブル４０１の頻度４０２は、１に、又はその他のゼロ以外の値に初期化される。各頻度４０２をゼロ以外の値に初期化した結果、ハフマン・コード・テーブル構築エンジン１０６は、ハフマン・コードを（例えば、ブロック１７１８で構築される）ダイナミック−プライム・ハフマン・コード・テーブルのシンボル空間の各シンボルに割り当てることになる。フローはブロック１７１４に進む。
【０１００】
ブロック１７１４で、ＬＺ７７エンジン１０２は、入力ブロックの初期部分をスキャンし、生成されたトークンに関連付けられたシンボルの頻度４０２は、上のブロック１７０４で説明されたのと同様の方法でインクリメントされる。フローはブロック１７１８に進む。
【０１０１】
ブロック１７１８で、ハフマン・コード・テーブル構築エンジン１０６は、ブロック１７１２〜１７１４に従って作成された頻度テーブル４０１の頻度４０２を使用して、ハフマン・コード・テーブルを構築する。重要なことに、構築されたダイナミック−プライム・ハフマン・コード・テーブルは、ブロック１７１２で初期されることによって保証されているように、各シンボルがゼロ以外の頻度４０２の値を有するため、シンボル空間内の各シンボルについてハフマン・コード値を含むことになる。フローはブロック１７１８で終了する。
【０１０２】
ここで図１７Ｃを参照すると、一実施形態によるダイナミック−プライム・ハフマン・コード・テーブルを構築するためのハードウェア・データ圧縮器１００の動作を表すフローチャートが示されている。フローは、ブロック１７２２から始まる。
【０１０３】
ブロック１７２２で、頻度テーブル４０１の頻度４０２は、シンボル空間のシンボルに対応する事前に蓄積された（pre-compiled）ゼロ以外の値のセット内で指定されたゼロ以外の値のセットに初期化される。つまり、各シンボルの頻度４０２を、図１７Ｂのブロック１７１２で実行されたように同じゼロ以外の値に割り当てるのではなく、ブロック１７２２で、各シンボルの頻度は、シンボル空間のシンボルの相対的頻度の見込みに関する事前知識（すなわち、入力ブロックの圧縮開始の前の知識）に基づいて特定のシンボルに対する調整された値に初期化される。例えば、長さのより短いバック・ポインタが極めて頻繁に出現する傾向があることが一般に知られている。したがって、事前に蓄積されたゼロ以外の頻度のセットは、シンボル空間のより短いバック・ポインタ長について、比較的大きいゼロ以外の頻度値を含んでいる可能性がある。別の例では、入力ブロックがＡＳＣＩＩ文字テキストであると仮定する。入力ブロック内のＡＳＣＩＩの「Ｅ」の頻度が、ＡＳＣＩＩの「Ｚ」の頻度よりも高くなる見込みが高いことが一般に知られている。したがって、事前に蓄積されたゼロ以外の頻度のセットは、ＡＳＣＩＩの「Ｚ」についてよりもＡＳＣＩＩの「Ｅ」について、より大きいゼロ以外の頻度値を含むことになる。このようにして、初期のゼロ以外の値は、同じゼロ以外の値を使用してあらゆるシンボルを初期化するのではなく、教授された推測に基づいて頻度４０２を事前に偏らせる。前述したように、この方法の利点は、図２Ａ〜８などでのようにソート・エンジン１０４が使用される実施形態において、頻度テーブル４０１の頻度４０２の初期値の不均一性によって、必要なソート量、すなわち、図５のブロック５１４及び５２２でのような、ソート済みリスト４０３のシンボル位置交換の量を減らすことができることである。一実施形態では、ハードウェア・データ圧縮器１００は、事前に蓄積されたゼロ以外の値の複数のセットを使用することができ、入力ブロックの取得元のファイルのタイプ（例えば、画像ファイル、オーディオ・ファイル、テキスト・ファイル、スプレッドシート、ワード・プロセッサやプレゼンテーション・アプリケーションによって生成されたファイル、又は他のタイプのファイル）などの基準に基づいて、事前に蓄積されたセットのうちの１つを選択する。フローはブロック１７２４に進む。
【０１０４】
ブロック１７２４で、ＬＺ７７エンジン１０２は、入力ブロックの初期部分をスキャンし、生成されたトークンに関連付けられたシンボルの頻度４０２は、上のブロック１７０４で説明されたのと同様の方法でインクリメントされる。フローはブロック１７２８に進む。
【０１０５】
ブロック１７２８で、ハフマン・コード・テーブル構築エンジン１０６は、ブロック１７２２〜１７２４に従って作成された頻度テーブル４０１の頻度４０２を使用して、ハフマン・コード・テーブルを構築する。重要なことに、構築されたダイナミック−プライム・ハフマン・コード・テーブルは、ブロック１７２２で初期されることによって保証されているように、各シンボルがゼロ以外の頻度４０２の値を有するため、シンボル空間内の各シンボルについてハフマン・コード値を含むことになる。フローはブロック１７２８で終了する。
【０１０６】
ここで図１８を参照すると、一実施形態による図１のハードウェア・データ圧縮器１００に関連付けられたハードウェアを表すブロック図が示されている。図１２のハードウェア・データ圧縮器１００は、ソート済みリスト変更カウンタ（ｓｏｒｔｅｄ  ｌｉｓｔ  ｃｈａｎｇｅ  ｃｏｕｎｔｅｒ：ＳＬＣＣ）１８０４、しきい値１８０６、シンボル・カウントダウン・カウンタ（ｓｙｍｂｏｌ  ｃｏｕｎｔｄｏｗｎ  ｃｏｕｎｔｅｒ：ＳＣＤＣ）１８０８、及びこれらが接続されるロジック１８０２を含む。しきい値１８０６は、プログラム可能なレジスタにすることができる。ＳＬＣＣ１８０４は、ＳＬＣＣ１８０４の最後のリセット以降、ソート済みリスト４０３が（例えば、ブロック５１４又はブロック５２２で）変更された回数のカウントを示す。ＳＣＤＣ１８０８は、所定値をロードされ、シンボルの頻度４０２が（例えば、ブロック１４１４で）インクリメントされるたびにカウントダウンされる。図１９に関してより詳細に説明されているように、ＳＣＤＣ１８０８がゼロにカウントダウンされたとき、ＳＬＣＣ１８０４がしきい値１８０６よりも小さい場合、ロジック１８０２は、ハフマン・コード・テーブルを構築するように信号で伝え、そうでない場合、ＳＣＤＣ１８０８が再び所定値をロードされる。好ましくは、図１８のハードウェアが、（例えば、図１４Ａのブロック１４１２での）ＬＺ７７エンジン１０２ではなくソート・エンジン１０４に含まれ、ソート・エンジン１０４が、（例えば、図１９のブロック１９１４で）ハフマン・コード・テーブルを構築するようにハフマン・コード・テーブル構築エンジン１０６に信号で伝える。一実施形態では、カウンタ１８０８は、シンボル頻度４０２がインクリメントされるたびではなく、トークン２１２が生成されるたびにカウントダウンされる。一実施形態では、カウンタ１８０８は、シンボル頻度４０２がインクリメントされるたびではなく、クロック・サイクルごとにカウントダウンされる。
【０１０７】
ここで図１９を参照すると、ハフマン・コード・テーブルの構築を信号で伝えるためのソート・エンジン１０４の動作を表すフローチャートが示されている。フローは、ブロック１９０２から始まる。
【０１０８】
ブロック１９０２で、ソート・エンジン１０４は図１８のＳＬＣＣ１８０４をゼロに初期化する。フローはブロック１９０４に進む。
【０１０９】
ブロック１９０４で、ソート・エンジン１０４は初期カウント又は所定値（例えば、１００）をＳＣＤＣ１８０８にロードする。フローはブロック１９０６に進む。
【０１１０】
ブロック１９０６で、ソート・エンジン１０４は、ＬＺ７７エンジン１０２からトークン２１２を受信し、そのトークン２１２に関連付けられた各シンボルに応答してＳＣＤＣ１８０８をデクリメントする。また、トークン２１２に関連付けられたシンボルに基づいてソート済みリスト４０３の変更が必要だった場合、ソート・エンジン１０４はＳＬＣＣ１８０４をインクリメントする。フローは、判定ブロック１９０８に進む。
【０１１１】
判定ブロック１９０８で、ロジック１８０２は、ＳＣＤＣ１８０８の値がゼロに達したかどうかを決定する。ゼロに達した場合、フローは判定ブロック１９１２に進み、そうでない場合、フローはブロック１９０６に戻って次のトークン２１２を待機する。
【０１１２】
判定ブロック１９１２で、ロジック１８０２は、ＳＬＣＣ１８０４がしきい値１８０６よりも小さいかどうかを決定する。小さい場合、フローは判定ブロック１９１４に進み、そうでない場合、フローはブロック１９０４に戻る。
【０１１３】
ブロック１９１４で、ロジック１８０２は、ハフマン・コード・テーブルを構築するようにハフマン・コード・テーブル構築エンジン１０６に信号で伝える。一実施形態では、ソート・エンジン１０４は、入力ブロックの少なくとも最小文字数（例えば、５００又は５％）がスキャンされるまで、ハフマン・コード・テーブルを構築するように信号で伝えない。フローはブロック１９１４で終了する。
【０１１４】
ここで図２０を参照すると、代替の実施形態によるＤＥＦＬＡＴＥ方式入力ブロック圧縮に関連付けられた圧縮時間の構成要素をグラフィカルに表すタイミング図が示されている。上の図１４Ａ〜１９の説明から観察できるように、入力ブロックの初期部分のみがスキャンされた後に入力ブロックのハフマン・エンコードを開始することによって、合計圧縮時間が有利に削減されることが可能である。図２０の代替の実施形態では、ハードウェア・データ圧縮器１００は、入力ブロックの初期部分のスキャンから維持された頻度を使用して構築されたダイナミック−プライム・ハフマン・コード・テーブルを使用するのではなく、複数の事前蓄積済みハフマン・コード・テーブルのうちの１つを選択して、入力ブロックの初期スキャンのみが実行された後に入力ブロックのハフマン・エンコーディングを開始し、それによって、ハフマン・エンコーディング時間を入力ブロックの残りの部分のスキャン時間に重ね合わせることによる恩恵を享受する。この実施形態では、ハードウェア・データ圧縮器１００は、入力ブロックの初期部分のスキャンの間、事前蓄積済みハフマン・コード・テーブルの各々について、事前蓄積済みハフマン・コード・テーブルを使用して作り出された圧縮済み出力のサイズを記録する。それから、ハードウェア・データ圧縮器１００は、初期部分を最も小さい出力に圧縮した事前蓄積済みハフマン・コード・テーブルを選択し、選択された事前蓄積済みハフマン・コード・テーブルを使用して入力ブロック全体をハフマン・エンコードする。
【０１１５】
圧縮の開始時に、ブロック２００２−ＡでＬＺ７７エンジン１０２は、本明細書で説明されているように、入力ブロック・メモリ１０１内の複数の文字から成る入力ブロックの初期部分をスキャンし、トークン２１２のストリームを生成する。入力ブロックの初期部分がスキャンされると、ブロック２００３で、ハードウェア・データ圧縮器１００は、複数の事前蓄積済みハフマン・コード・テーブルの対（例えば、リテラル／長さテーブル及び距離テーブル）の各々を使用して、事前蓄積済みハフマン・コード・テーブルの対を使用して入力ブロックの初期部分をハフマン・エンコードするのに作り出されるであろう出力のサイズを計算する（ただし、作り出さない）。さらに、ブロック２００２−Ｂで、ＬＺ７７エンジン１０２は、入力ブロック・メモリ１０１内の複数の文字から成る入力ブロックの残りの部分を引き続きスキャンし、トークン２１２のストリームを生成する。
【０１１６】
入力ブロックの初期部分がスキャンされた後に、ブロック２００４で、ハードウェア・データ圧縮器１００は、事前蓄積済みハフマン・コード・テーブルの対のうちの１つを選択する。それから、ブロック２００６で、ハフマン・エンコーディング・エンジン１０８は、選択された事前蓄積済みハフマン・コード・テーブルの対を使用して入力ブロック全体をハフマン・エンコードし、圧縮された出力を出力メモリ１０９に書き込む。ブロック２００４及び２００６での動作時間は、図に示されるように、ブロック２００２−Ｂでの動作時間の背後に有利に隠れて、合計圧縮時間を有利に削減することができる。
【０１１７】
図２０の実施形態は、ハフマン・コード・テーブル構築エンジン１０６の負担を軽減するという、図１４Ａ〜１９の実施形態を上回る利点を持つ可能性がある。ただし、図１４Ａ〜１９のダイナミック−プライム・ハフマン・コード・テーブルの実施形態は、図２０の実施形態と同じ高速な圧縮速度の恩恵を享受する可能性が高いが、さらなる利点を有している。図１４Ａ〜１９の実施形態は、ハードウェア・データ圧縮器１００が選択するための適切な事前蓄積済みハフマン・コード・テーブルが存在しない入力ブロックに対して、図２０の実施形態よりも小さい出力を生成する可能性が高い。例えば、入力ブロックの文字が、事前蓄積済みハフマン・コード・テーブルが存在しない比較的難解な言語の文字、例えば、ハンガリー語のユニコードであると仮定する。その場合、図１４Ａ〜１９の実施形態に従って構築されたダイナミック−プライム・ハフマン・コード・テーブルは、事前蓄積済みハフマン・コード・テーブルの対よりも小さい出力を生成する可能性が高い。
【０１１８】
一致した文字列又は一致した文字列へのバック・ポインタを選択的にハフマン・エンコードする事前ハフマン・エンコーディング
ここで図２１を参照すると、図１のハードウェア・データ圧縮器１００の一部を表すブロック図が示されている。図１のＬＺ７７エンジン１０２は、図１のテーブル・メモリ１０７と通信する。テーブル・メモリ１０７は、「参照」ハフマン・コード・テーブル２１０２を保持する。図２２及び２３に関してより詳細に説明されているように、参照ハフマン・コード・テーブル２１０２は、ＬＺ７７エンジン１０２によって、トークンを「事前ハフマン・エンコード（pre-Huffman  encode）」してトークンのサイズを決定するために使用され、それによって、一致した文字列のリテラルを生成するのか、それとも一致した文字列へのバック・ポインタを生成するのかを判定する。参照ハフマン・コード・テーブル２１０２は、後でＬＺ７７エンジン１０２の出力ストリームをハフマン・エンコードするためにハフマン・エンコーディング・エンジン１０８によって使用される同じハフマン・コード・テーブルである場合もあれば、そうでない場合もある。
【０１１９】
ＬＺ７７エンジン１０２は、参照ハフマン・コード・テーブル２１０２を使用して２つのサイズを決定するロジックを含む。サイズＸと呼ばれる第１のサイズは、一致した文字列のリテラル・シンボルが参照ハフマン・コード・テーブル２１０２を使用してハフマン・エンコードされた場合に出力されるであろう、ハフマン・コードの総ビット数である。つまり、ＬＺ７７エンジン１０２は、参照ハフマン・コード・テーブル２１０２を使用して、リテラル・シンボルごとにハフマン・コードのビット数を決定し、それらを加算して合計（サイズＸ）を作り出す。好ましくは、ＬＺ７７エンジン１０２のロジックは、好ましくは並行して、リテラルの参照ハフマン・コード・テーブル２１０２内でリテラル・シンボルの各々をルックアップして、各ハフマン・コードのビット数（例えば、図１１Ｂのビット長１１１２）を決定し、それらを一緒に加算してサイズＸを作り出す。一実施形態では、所定文字数、例えば、５以下の文字列に関してサイズＸを決定するようにロジックが構成され、したがって、文字列が所定文字数より長い場合、下の判定ブロック２２０６で、サイズＸがサイズＹよりも大きいと仮定される。サイズＹと呼ばれる第２のサイズは、一致した文字列（存在すると仮定する）へのバック・ポインタが参照ハフマン・コード・テーブル２１０２を使用してハフマン・エンコードされた場合に出力されるであろう、ハフマン・コードの総ビット数である。つまり、ＬＺ７７エンジン１０２は、参照ハフマン・コード・テーブル２１０２を使用して、追加ビットを含めてポインタの長さ及び距離の各々についてハフマン・コードのビット数（例えば、図１１Ｂのビット長１１１２）を決定し、それらを加算して合計（サイズＹ）を作り出す。好ましくは、ＬＺ７７エンジン１０２のロジックは、好ましくは並行して、参照長さ及び距離ハフマン・コード・テーブル２１０２内で長さ及び距離シンボルの各々をルックアップして、各ハフマン・コードのビット数を決定し、それらを一緒に加算してサイズＹを作り出す。
【０１２０】
ここで図２２を参照すると、データを圧縮するためのハードウェア・データ圧縮器１００の動作を表すフローチャートが示されている。フローは、ブロック２２０２から始まる。
【０１２１】
ブロック２２０２で、ＬＺ７７エンジン１０２は、現在の検索ターゲット位置で文字列の一致を検索し、検出し、（例えば、ブロック３０２又はブロック１４０４に関して）前述したのと同様の方法で、現在の検索ターゲット位置から一致する文字列へのバック・ポインタを算出する。フローはブロック２２０４に進む。
【０１２２】
ブロック２２０４で、ＬＺ７７エンジン１０２は、図２１に関して前述したように、サイズＸ及びサイズＹを決定する。つまり、ＬＺ７７エンジン１０２は、リテラル及びバック・ポインタの両方を事前ハフマン・エンコードして、そのそれぞれのハフマン・エンコードされたサイズを、ビット数を単位として決定する。フローは、判定ブロック２２０６に進む。
【０１２３】
判定ブロック２２０６で、ＬＺ７７エンジン１０２は、サイズＸがサイズＹよりも小さいかどうかを判定する。小さい場合、フローはブロック２２１２に進み、そうでない場合、フローはブロック２２０８に進む。
【０１２４】
判定ブロック２２０８で、ＬＺ７７エンジン１０２は、ブロック２２０２で算出されたバック・ポインタを生成する。つまり、ＬＺ７７エンジン１０２は、後でハフマン・エンコーディング・エンジン１０８によってハフマン・エンコードするために、バック・ポインタを（例えば、ブロック３０６又はブロック１４０６でのように）出力する。フローはブロック２２１４に進む。
【０１２５】
ブロック２２１２で、ＬＺ７７エンジン１０２は、一致した文字列のリテラルを生成する。つまり、ＬＺ７７エンジン１０２は、後でハフマン・エンコーディング・エンジン１０８によってハフマン・エンコードするために、リテラルの指標を（例えば、ブロック３０６又はブロック１４０６でのように）出力する。フローはブロック２２１４に進む。
【０１２６】
ブロック２２１４で、ハフマン・エンコーディング・エンジン１０８は、ブロック２２０８又はブロック２２１２で生成された出力、すなわち、一致した文字列のバック・ポインタ又はリテラルをハフマン・エンコードする。一実施形態では、ハフマン・エンコーディング・エンジン１０８は、参照ハフマン・コード・テーブル２１０２とは異なるハフマン・コード・テーブルを使用して、バック・ポインタ又はリテラルをハフマン・エンコードする。例えば、入力ブロックをハフマン・エンコードするためにハフマン・エンコーディング・エンジン１０８によって（例えば、ブロック１００６、１４３４、１６０６、又は２００６でのように）使用されるハフマン・コード・テーブルは、入力ブロックの初期部分がスキャンされた後に構築されたか（例えば、図１６を参照）、又は選択された（例えば、図２０を参照）ハフマン・コード・テーブルにすることができ、そのため、入力ブロックの初期部分がスキャンされている間は、サイズＸ及びサイズＹを算出するために、参照ハフマン・コード・テーブル２１０２が使用されなければならない。つまり、参照ハフマン・コード・テーブル２１０２は、図２２のブロック２２０２〜２２１２に従って実行される最適化が実行される時点で、既知でなければならない。最終的に入力ブロックをハフマン・エンコードするために使用されるハフマン・コード・テーブルとは異なるハフマン・コード・テーブルが使用されてサイズＸ及びサイズＹを計算した場合でも、図２２による動作は、依然として圧縮率を改善し、すなわち、図２２による動作を使用しない従来方法よりも出力のサイズを削減することができる。フローはブロック２２１４で終了する。
【０１２７】
好ましくは、図２２による事前ハフマン・エンコーディングの動作は、複数の文字から成る入力ブロック全体のスキャンに対してＬＺ７７エンジン１０２によって生成された各トークン２１２について実行される。ただし、以下で説明されているように、一部の実施形態では、事前ハフマン・エンコーディングは、例えばダイナミック−プライム・ハフマン・コード・テーブルを使用する場合に、初期部分がスキャンされた後の入力ブロックの残りの部分など、入力ブロックのスキャンの一部のみに対して生成されたトークン２１２に対して実行されることが可能である。
【０１２８】
ここで図２３Ａを参照すると、一実施形態による図２２のブロック２２０４の動作を表すフローチャートが示されている。フローはブロック２３０２で始まり、終了する。
【０１２９】
ブロック２３０２で、ＬＺ７７エンジン１０２は、事前蓄積済みハフマン・コード・テーブルを使用してサイズＸ及びサイズＹを決定する。事前蓄積済みハフマン・コード・テーブルは、ハードウェア・データ圧縮器１００が複数の文字から成る入力ブロックの圧縮を開始する前に蓄積される。例えば、事前蓄積済みハフマン・コード・テーブルは、ＤＥＦＬＡＴＥ仕様によって規定された固定ハフマン・コード・テーブルにすることができ、そのリテラル／長さのテーブルは、基本的に下の表３（変更は括弧で示される）のように再現される。ＤＥＦＬＡＴＥ仕様では、固定ハフマン・コード・テーブルの距離コード０〜３１は、（固定長）５ビット・コードと、場合によっては、上の表２に示すように、さらなるビットを使用して表されると規定されている。或いは、事前蓄積済みハフマン・コード・テーブルは、代表的な入力ブロック又は代表的な入力ブロックのサンプルのシンボルの頻度に基づいて構築されたハフマン・コード・テーブルにすることができる。一実施形態では、事前蓄積済みハフマン・コード・テーブルは、シンボル空間内のあらゆるシンボルのハフマン・コードを含む。代替の実施形態では、ハフマン・コード・テーブルは、シンボル空間の一部のシンボルのハフマン・コードを含まず、ＬＺ７７エンジン１０２は、それらのシンボルに対してサイズＸ及びサイズＹを計算せず、判定ブロック２２０６での比較を実行せず、ブロック２２０８でバック・ポインタを生成する。
【０１３０】
【表３】
0006363581.tif 000004
【０１３１】
ここで図２３Ｂを参照すると、代替の実施形態による図２２のブロック２２０４の動作を表すフローチャートが示されている。フローはブロック２３１２で始まり、終了する。
【０１３２】
ブロック２３１２で、ＬＺ７７エンジン１０２は、図１４Ａ〜２０に関して前述したように構築されたダイナミック−プライム・ハフマン・コード・テーブルなどのダイナミック−プライム・ハフマン・コード・テーブルを使用して、サイズＸ及びサイズＹを決定する。一実施形態では、図２２の動作は、ダイナミック−プライム・ハフマン・コード・テーブルが（例えば、図１６のブロック１６０４で）構築されるまでトークン２１２に対して実行されず、ダイナミック−プライム・ハフマン・コード・テーブルが構築される前に、ＬＺ７７圧縮エンジン１０２は、サイズＸ及びサイズＹを計算してサイズＸ及びサイズＹの関係に基づいてバック・ポインタの生成に関して選択的になるのではなく、ブロック２２０８でのように、単にバック・ポインタを生成する。代替の実施形態では、ダイナミック−プライム・ハフマン・コード・テーブルの構築前は、参照ハフマン・コード・テーブル２１０２が使用されてステップ２２０４を実行し、ダイナミック−プライム・ハフマン・コード・テーブルの構築後に、ダイナミック−プライム・ハフマン・コード・テーブルが使用されてステップ２２０４を実行する。
【０１３３】
本明細書に記載された事前ハフマン・エンコーディングの実施形態の利点は、次のように説明されることが可能である。一部の従来方法では、ＬＺ７７圧縮アルゴリズムは、バック・ポインタで置換するための３バイト文字列の一致の検索を考慮しない。一方、本明細書に記載された実施形態は、場合によっては、３バイトの一致した文字列へのバック・ポインタの一部を（例えば、ブロック２２０８で）生成する。そのため、ＬＺ７７エンジン１０２のロジックが、ブロック２２０４の事前ハフマン・エンコーディング及びブロック２２０６の判定を実行し、それと並行して一致する文字列について入力ブロックの次のスキャンを行うように構成されている範囲において、本明細書に記載された実施形態は、より高い圧縮率を実現しながら、速度の低下を招かない。
【０１３４】
異なるハッシュ・サイズにそれぞれ基づく複数の文字列一致検索ハッシュ・テーブル
ＬＺ７７方式の圧縮を実行する場合、検索ターゲット文字列の一致を検出するための入力ブロック内の後方検索に、非常に時間がかかる可能性がある。明らかな検索方法の１つは、入力ブロックの先頭から開始し、入力ブロック全体を１文字ずつ（現在の検索位置まで）移動し、最長の一致する文字列の位置を示すことである。しかし、この方法は極めて低速である。
【０１３５】
さらに高速な方法は、ハッシュ・テーブルを使用することである。下でより詳細に説明されているように、入力ブロックがスキャンされると、ハッシュ・テーブルが構築されて使用され、入力ブロック内で検索される位置を減らす。つまり、ハッシュ・テーブルによって、一致を生む可能性の高い、すなわち、検索ターゲットの少なくとも少数の文字（例えば、３文字）を保持している可能性の高い入力ブロック内の位置に、検索の焦点を合わせることができる。これは、現在の検索ターゲット位置の前の入力ブロックの文字が、入力ブロックのスキャンの間に前に見られていることを利用して実現される。
【０１３６】
例えば、現在の検索ターゲット位置の３文字が、ハッシュ・アルゴリズムに従ってハッシュされて、ハッシュ・テーブルのエントリのインデックスを指すインデックスを作り出す。ハッシュ・テーブルのエントリは、同じインデックスに対して以前にハッシュされた、入力ブロック内の位置へのポインタのハッシュ・チェーンの先頭である。これによって、検索ターゲット位置の３文字が、ポインタによって指し示された位置にもあるという相対的に高い見込みが（ハッシュ・アルゴリズム、ハッシュ・テーブルのサイズ、及び入力ブロックの文字の特徴に依存して）生まれる。これは、ＤＥＦＬＡＴＥ仕様のセクション４に記載されている。
【０１３７】
一般的に言って、少なくとも一部の入力ファイル（例えば、ルイス・キャロル作の本「不思議の国のアリス」のテキスト）に対して４文字のハッシュを使用した場合、３文字のハッシュよりも出力ファイルが大きくなるが、より高速に出力ファイルを生成し、その他については同等になることが観察されている。出力ファイルが大きくなる理由は、多くの事例で、いくつかの３文字の一致が喪失されることにより、入力ブロックのリテラルをバック・ポインタに置換する機会が失われるという事実によって説明される。
【０１３８】
速度の向上については、複数の要因の組み合わせによって説明される可能性がある。少なくとも１つの要因は、次のようにハッシュ・チェーン検索が短くなることが予想されることである。３文字の文字列「ｓｈｅ」の３７回の出現が、それまでの入力ブロックのスキャンで現れたと仮定する。３７回の出現はすべて、３文字のハッシュ・テーブル内の同じハッシュ・チェーンに挿入される。３７回出現した「ｓｈｅ」のうちのいくつかの後に、別の文字が続いたと仮定し、例えば、「ｓｈｅａ」が２１回出現し、「ｓｈｅｌ」が１２回出現し、「ｓｈｅｄ」が４回出現したと仮定する。これら３つの異なる４文字の文字列を、４文字のハッシュ・テーブルの３つの異なるハッシュ・チェーンに挿入する、４文字のハッシュ・アルゴリズムを仮定する。これは、４文字のハッシュ・テーブル内において「ｓｈｅ」で始まる文字列の一致について検索されるハッシュ・チェーンが、３文字のハッシュ・テーブル内において検索されるハッシュ・チェーンよりも短くなる可能性が高く、その他の点については同じであるということを意味している。その他の点は、例えば、３文字のハッシュ・テーブル内の「ｓｈｅ」と同じハッシュ・チェーンにハッシュされる、「ｓｈｅ」以外の文字列との衝突を無視することや、４文字のハッシュ・テーブル内の「ｓｈｅ」の後に「ａ」、「ｌ」、及び「ｄ」がそれぞれ続く文字列と同じ３つのハッシュ・チェーンにハッシュされる、別の文字が後に続く「ｓｈｅ」以外の文字列との衝突を無視することである。
【０１３９】
４文字のハッシュの速度と３文字のハッシュの出力サイズに近づく試みにおいて、ハードウェア・データ圧縮器１００が２つのハッシュ・テーブルを維持する実施形態について説明する。１つは３文字のハッシュに基づくハッシュ・テーブルであり、もう１つは４文字のハッシュに基づくハッシュ・テーブルである。４文字のハッシュ・テーブルは、最初に少なくとも４文字の一致を検索するために使用され、３文字のハッシュ・テーブルは、４文字のハッシュ・テーブルを使用して４文字の一致が検出されなかった場合にのみ、少なくとも３文字の一致を検索するために使用される。一部の入力ブロックに対しては、４文字のハッシュ・テーブル内のハッシュ・チェーンがより短くなるため、一般に、より短いハッシュ・チェーンの検索は、より高速になることが可能である。しかし、必要に応じて３文字のハッシュ・テーブルが使用されるため、３文字のハッシュ・テーブルの圧縮率に近づくことが可能である。４文字のハッシュ・テーブルを使用して一致が検出された場合、３文字のハッシュ・テーブルを使用して検索する必要はないことが留意される。これは、一般的に言って、４文字のハッシュ・テーブルを使用して検出されるいかなる一致も、３文字のハッシュ・テーブルを使用して検出される一致と少なくとも同じ長さになるからである。
【０１４０】
再びになるが、３文字のハッシュ・テーブルと４文字のハッシュ・テーブルとの目的は、３文字のハッシュ単独よりも高速化することと、４文字のハッシュ単独よりも圧縮率を高くすることとの双方である。説明のために、所与の入力ブロックに対して、時間の９０％で４文字以上の一致が検出され、時間の１０％のみで３文字の一致が検出されたと仮定する。この場合、圧縮器は、４文字のハッシュのみの実施形態では得られない、１０％の３文字の一致による圧縮率の恩恵を受けるため、圧縮された出力は、通常、４文字のハッシュのみを使用した場合よりも小さくなるが、４文字のハッシュ・チェーンが統計的により短いため、各検索が統計的により高速になることにより、３文字のハッシュのみの実施形態よりも高速に出力を作り出す。
【０１４１】
ここで図２４を参照すると、図１のＬＺ７７エンジン１０２の一部を表すブロック図が示されている。ＬＺ７７エンジン１０２は、４文字のハッシュ・テーブル２４４８を含む。４文字のハッシュ・テーブル２４４８は、４文字のハッシュ・テーブル・インデックス２４４４によってインデックスを指されるエントリの配列である。４文字のハッシュ・テーブル・インデックス２４４４は、４文字のハッシュ・アルゴリズムを使用して、４文字のハッシュ・テーブル・インデックス・ジェネレータ２４４２によって、複数の文字から成る入力ブロック２４０４の現在の検索ターゲット位置２４０２の４文字をハッシュして作り出される。４文字のハッシュ・アルゴリズムの一実施形態が、下の表５で説明されている。ただし、他の実施形態が企図されており、表５のハッシュ・アルゴリズムは、説明のための例として提供されている。一実施形態では、ハッシュ・アルゴリズムは、図３９〜４１に関して下で説明されているように、入力ブロック・タイプに依存する。４文字のハッシュ・テーブル・インデックス２４４４は、４文字値ではなく、４文字のハッシュ・テーブル２４４８へのインデックスであることが理解されるべきである（インデックス２４４４のサイズは、ハッシュ・テーブル２４４８のサイズに依存する）。４文字のハッシュ・テーブル２４４８の各エントリは、ノード２４０６のハッシュ・チェーン２４４１の先頭である。好ましくは、各ハッシュ・チェーン２４４１は、ノード２４０６のリンク・リストであるが、他の実施形態、例えば、配列、ツリーが企図される。各ノードは、チェーン２４４１内の次のノードへのポインタを含む。各ノードは、入力ブロック２４０４内の、現在の検索ターゲット位置２４０２の後方にある４文字の文字列の位置へのポインタをさらに含み、これら４文字の文字列は、４文字のハッシュ・テーブル２４４８内のエントリのインデックス２４４４の値に事前にハッシュされており、４文字のハッシュ・テーブル２４４８のハッシュ・チェーン２４４１は、ノード２４０６を含む。ノード２４０６の投入が、図２５に関して下で詳細に説明される。図２４に示されているように、各ハッシュ・チェーン２４４１の長さは、入力ブロック２４０４がスキャンされるときに変化することになり、一部のハッシュ・チェーン２４４１は、空である場合がある。一実施形態では、４文字のハッシュ・テーブル２４４８のエントリ数は１６，３８４であるが、他の実施形態が企図される。
【０１４２】
ＬＺ７７エンジン１０２は、３文字のハッシュ・テーブル２４３８をさらに含む。３文字のハッシュ・テーブル２４３８は、３文字のハッシュ・テーブル・インデックス２４３４によってインデックスを指されるエントリの配列である。３文字のハッシュ・テーブル・インデックス２４３４は、３文字のハッシュ・アルゴリズムを使用して、３文字のハッシュ・テーブル・インデックス・ジェネレータ２４３２によって、複数の文字から成る入力ブロック２４０４の現在の検索ターゲット位置２４０２の３文字をハッシュして作り出される。３文字のハッシュ・アルゴリズムの実施形態は、下の表４で説明されている。ただし、他の実施形態が企図されており、表４のハッシュ・アルゴリズムは、説明のための例として提供されている。一実施形態では、ハッシュ・アルゴリズムは、図３９〜４１に関して下で説明されているように、入力ブロック・タイプに依存する。３文字のハッシュ・テーブル・インデックス２４３４は、３文字値ではなく、３文字のハッシュ・テーブル２４３８へのインデックスであるということが理解されるべきである（インデックス２４３４のサイズは、ハッシュ・テーブル２４３８のサイズに依存する）。３文字のハッシュ・テーブル２４３８の各エントリは、ノード２４０６のハッシュ・チェーン２４３１の先頭である。好ましくは、各ハッシュ・チェーン２４３１は、ノード２４０６のリンク・リストであるが、他の実施形態、例えば、配列やツリーが企図される。各ノードは、チェーン２４３１内の次のノードへのポインタを含む。各ノードは、入力ブロック２４０４内の、現在の検索ターゲット位置２４０２の後方にある３文字の文字列の位置へのポインタをさらに含み、これら３文字の文字列は、３文字のハッシュ・テーブル２４３８内のエントリのインデックス２４３４の値に事前にハッシュされており、３文字のハッシュ・テーブル２４３８のハッシュ・チェーン２４３１は、ノード２４０６を含む。ノード２４０６の投入が、図２５に関して下でより詳細に説明される。図２４に示されているように、各ハッシュ・チェーン２４３１の長さは、入力ブロック２４０４がスキャンされるときに変化し、一部のハッシュ・チェーン２４３１は、空である場合がある。一実施形態では、３文字のハッシュ・テーブル２４３８のエントリ数は１６，３８４であるが、他の実施形態が企図される。
【０１４３】
一実施形態では、４文字のハッシュ・テーブル２４４８及び３文字のハッシュ・テーブル２４３８は、図１のハッシュ・メモリ１０３に格納される。別の実施形態では、ハードウェア・データ圧縮器１００は、４文字のハッシュ・テーブル２４４８用及び３文字のハッシュ・テーブル２４３８用の別個のメモリを含む。一実施形態では、ハッシュ・チェーン２４４１／２４３１のノード２４０６は、ハッシュ・テーブル２４３８／２４４８のエントリとは別個のメモリに格納される。
【０１４４】
下の表４及び５は、それぞれ３バイト・ハッシュ・アルゴリズム及び４バイト・ハッシュ・アルゴリズムの例である。
【０１４５】
【表４】
0006363581.tif 000005
【０１４６】
【表５】
0006363581.tif 000006
【０１４７】
ここで図２５を参照すると、図２４のＬＺ７７エンジン１０２の動作を表すフローチャートが示されている。フローは、ブロック２５０１及び２５１１から、好ましくは同時に、開始する。
【０１４８】
ブロック２５０１で、４文字のハッシュ・インデックス・ジェネレータ２４４２が、入力ブロック２４０４内の現在の検索ターゲット位置２４０２の４文字をハッシュして、４文字のハッシュ・テーブル・インデックス２４４４を作り出す。フローはブロック２５０１からブロック２５０２に進む。
【０１４９】
ブロック２５１１で、３文字のハッシュ・インデックス・ジェネレータ２４３２が、入力ブロック２４０４内の現在の検索ターゲット位置２４０２の３文字をハッシュして、３文字のハッシュ・テーブル・インデックス２４３４を作り出す。フローはブロック２５１１からブロック２５０２に進む。
【０１５０】
ブロック２５０２で、ＬＺ７７エンジン１０２は、ブロック２５０１で作り出されたインデックス２４４４で、４文字のハッシュ・テーブル２４４８のハッシュ・チェーン２４４１を使用して、現在の検索ターゲット位置２４０２の文字列の一致について入力ブロック２４０４を検索する。つまり、ＬＺ７７エンジン１０２は、検索中断基準（例えば、使用されたノード２４０６の数、使用されたハッシュ・チェーン２４４１のパーセンテージ、又は一致した文字列の長さが所定値を超える）又はチェーン２４４１の末尾に達するまで、インデックスを指されたチェーン２４４１の先頭にあるノード２４０６によって指し示された入力ブロック２４０４の位置で一致について最初検索し、インデックスを指されたチェーン２４４１内の次のノード２４０６によって指し示された入力ブロック２４０４の位置でさらに長い一致について検索し、インデックスを指されたチェーン２４４１内のその次のノード２４０６によって指し示された入力ブロック２４０４の位置でさらに長い一致について検索する、というように動作する。フローは、判定ブロック２５０３に進む。
【０１５１】
判定ブロック２５０３で、ブロック２５０２で一致が検出されていた場合、フローはブロック２５０４に進み、そうでない場合、フローはブロック２５１２に進む。
【０１５２】
ブロック２５０４で、ＬＺ７７エンジン１０２は、検出された文字列の一致に対してバック・ポインタを生成する。フローは、ブロック２５０６及び２５１６に、好ましくは同時に、進む。
【０１５３】
ブロック２５０６で、ＬＺ７７エンジン１０２は、ノード２４０６を、ブロック２５０１で作り出された４文字のハッシュ・テーブル２４４８のインデックス２４４４でハッシュ・チェーン２４４１に挿入する。このノード２４０６は、現在の検索ターゲット位置２４０２を指し示している。好ましくは、このノード２４０６はハッシュ・チェーン２４４１の先頭に挿入され、より新しいノード２４０６がより古いノード２４０６よりも先に検索されるようにし、このことは、バック・ポインタの距離値を減らす傾向がある。ただし、異なる順序のノード２４０６が維持される代替の実施形態が、図２６〜３５に関して下で説明される。フローはブロック２５０７に進む。
【０１５４】
ブロック２５０７で、ＬＺ７７エンジン１０２は、現在の検索ターゲット位置２４０２を更新する。好ましくは、位置２４０２は、３文字のハッシュ・テーブル２４３８が使用される場合は３文字ずつ、４文字のハッシュ・テーブル２４４８が使用される場合は４文字ずつ進む。フローはブロック２５０７で終了する。
【０１５５】
ブロック２５１２で、ＬＺ７７エンジン１０２は、ブロック２５０１で作り出されたインデックス２４３４で、３文字のハッシュ・テーブル２４３８のハッシュ・チェーン２４３１を使用して、現在の検索ターゲット位置２４０２の文字列の一致について入力ブロック２４０４を検索する。つまり、ＬＺ７７エンジン１０２は、検索中断基準（例えば、使用されたノード２４０６の数、使用されたハッシュ・チェーン２４３１のパーセンテージ、又は一致した文字列の長さが所定値を超える）又はチェーン２４３１の末尾に達するまで、インデックスを指されたチェーン２４３１の先頭にあるノード２４０６によって指し示された入力ブロック２４０４の位置で一致について最初検索し、インデックスを指されたチェーン２４３１内の次のノード２４０６によって指し示された入力ブロック２４０４の位置でさらに長い一致について検索し、インデックスを指されたチェーン２４３１内のその次のノード２４０６によって指し示された入力ブロック２４０４の位置でさらに長い一致について検索する、というように動作する。一実施形態では、検索中断基準は、３文字のハッシュ・テーブル２４３８の検索に対しては存在するが、４文字のハッシュ・テーブル２４４８の検索に対しては存在しない。フローは、判定ブロック２５１３に進む。
【０１５６】
判定ブロック２５１３で、ブロック２５１２で一致が検出されていた場合、フローはブロック２５１４に進み、そうでない場合、フローはブロック２５１５に進む。
【０１５７】
ブロック２５１４で、ＬＺ７７エンジン１０２は、検出された文字列の一致に対してバック・ポインタを生成する。フローは、ブロック２５０６及び２５１６に、好ましくは同時に、進む。
【０１５８】
ブロック２５１５で、ＬＺ７７エンジン１０２は、現在の検索ターゲット位置２４０２でリテラル・シンボルを生成する。一実施形態では、ＬＺ７７エンジン１０２は３つのリテラル・シンボルを生成し、一方、別の実施形態では、ＬＺ７７エンジン１０２は４つのリテラル・シンボルを生成する。一実施形態では、生成されるリテラル・シンボルの数は、プログラム可能である。フローは、ブロック２５０６及び２５１６に、好ましくは同時に、進む。
【０１５９】
ブロック２５１６で、ＬＺ７７エンジン１０２は、ノード２４０６を、ブロック２５１１で作り出された３文字のハッシュ・テーブル２４３８のインデックス２４３４でハッシュ・チェーン２４３１に挿入する。このノード２４０６は、現在の検索ターゲット位置２４０２を指し示している。好ましくは、このノード２４０６はハッシュ・チェーン２４３１の先頭に挿入され、より新しいノード２４０６がより古いノード２４０６よりも先に検索されるようにし、このことは、バック・ポインタの距離値を減らす傾向がある。ただし、異なる順序のノード２４０６が維持される代替の実施形態が、図２６〜３５に関して下で説明される。フローはブロック２５０７に進む。
【０１６０】
３文字のハッシュ・テーブル及び４文字のハッシュ・テーブルを含む実施形態が説明されているが、実施形態はこれらに限定されないということが理解されるべきである。むしろ、さらに一般的に、Ｍ文字のハッシュ・テーブル及びＮ文字のハッシュ・テーブルが使用され、Ｍは２よりも大きく、ＮはＭよりも大きい実施形態が企図される。したがって、例えば、３文字のハッシュ・テーブル及び５文字のハッシュ・テーブルを使用する実施形態が企図されたり、４文字のハッシュ・テーブル及び６文字のハッシュ・テーブルを使用する実施形態が企図されたりするなどである。
【０１６１】
さらに、２つのハッシュ・テーブルを含む実施形態が説明されているが、実施形態は２つのハッシュ・テーブルに限定されないということが理解されるべきである。むしろ、さらに一般的に、Ｊ個のハッシュ・テーブルを含む実施形態が企図され、ここで、Ｊは１よりも大きい。したがって、例えば、３文字のハッシュ・テーブル、４文字のハッシュ・テーブル、及び６文字のハッシュ・テーブルを使用する実施形態が企図されたり、３文字のハッシュ・テーブル、５文字のハッシュ・テーブル、及び６文字のハッシュ・テーブルを使用する実施形態が企図されたりするなどである。ただし、複数のハッシュ・テーブルを有することは、通常、１つのハッシュ・テーブルよりも多くのメモリを必要とし、より高速な圧縮を実現するための望ましいトレードオフになる場合がある。
【０１６２】
ノードの文字列の一致確率に基づくハッシュ・チェーンのソート
前述したように、ＬＺ７７エンジン１０２は、一致する文字列を検索してバック・ポインタを生成するとき、検索中断基準に達した場合、インデックスを指されたハッシュ・チェーン内の横断を打ち切ることができ、すなわち、ハッシュ・チェーンのすべてのノードを使用して検索するようハッシュ・チェーン全体を横断しなくてもよい。例えば、ＬＺ７７エンジン１０２は、長さが所定値を超える一致した文字列を検出したか、又は所定数のノードを使用して一致する文字列を検索したか、又はハッシュ・チェーンのノードのうちの所定パーセンテージを使用した後に、検索を停止することができる。これによって圧縮速度を向上することができるが、より長い文字列の一致が喪失される可能性があるため、圧縮率の低下を犠牲にする可能性がある。
【０１６３】
一般的に言えば、長さがより長く、距離のより短いバック・ポインタを生成することで、圧縮率が向上する。長さがより長いと、入力ブロックのより多くの文字が置換されるため、圧縮率が向上する。距離がより短いと、より短い距離値のハフマン・コードについて必要な追加ビットはより少ないため、圧縮率が向上する。ＤＥＦＬＡＴＥ仕様は、距離がより短いと必要な追加ビットが減るため、ハフマン・エンコーディングによる圧縮を改善するために、小さい距離値を持つバック・ポインタを推奨している。ＤＥＦＬＡＴＥ仕様は、このことを、新しいノードをハッシュ・チェーンの先頭に挿入することによって実施する。つまり、この実装は、ハッシュ・チェーンのノードを、世代のみによって順序付ける。こうすることで、通常は、より距離の短いバック・ポインタが生成されるが、好ましくない、長さのより短いバック・ポインタが生成される場合もある。
【０１６４】
検索中断基準に対する動機は、特定のハッシュ・チェーンが極めて長くなる可能性があるためである。例えば、入力ブロックが英語テキストであると仮定する。３文字の文字列「Ｔｈｅ」のハッシュ先のハッシュ・チェーンは、この文字列が入力ブロック内で頻繁に出現する可能性が高いため、相対的に長くなる可能性が非常に高い。しかし、一般的に言えば、「Ｔｈｅ」で始まる入力ブロック内のすべての位置が、その後の検索ターゲットとの一致を生み出す同じ確率を持っているわけではない。つまり、入力ブロック内には、「Ｔｈｅ」で始まり、且つその後に文字列の一致を生む可能性のある多くの異なる文字の組み合わせが続く、多くの異なる位置が存在する可能性が高く、上記の異なる組み合わせの各々は、一致を生み出す異なった見込みを有している。例えば、「Ｔｈｅｚ」、「Ｔｈｅｑ」、又は「Ｔｈｅｊ」を指し示すノードは、通常、「Ｔｈｅｒ」又は「Ｔｈｅｎ」を指し示すノードよりも一致を生む可能性が低い。しかし、厳密に世代に従ってハッシュ・チェーン・ノードを順序付ける従来の実装では、「Ｔｈｅｚ」、「Ｔｈｅｑ」、及び「Ｔｈｅｊ」を指し示すノードは、相対的に新しく、ハッシュ・チェーン内で先に出現する、さらに具体的には、ハッシュ・チェーン内で検索中断ポイントよりも前の場所を占める可能性があり、「Ｔｈｅｒ」又は「Ｔｈｅｎ」を指し示す一部のノードは、ハッシュ・チェーン内の検索中断ポイントよりも後ろの場所を占める可能性がある。したがって、「Ｔｈｅｒ」又は「Ｔｈｅｎ」を指し示すノードがハッシュ・チェーン内の検索中断基準を超えて順序付けられた場合、ＬＺ７７エンジン１０２は、それらのノードにたどり着かず、それらのノードを使用しない可能性がある。
【０１６５】
ここで図２６を参照すると、一実施形態によるハードウェア・データ圧縮器１００の一部を表すブロック図が示されている。ハードウェア・データ圧縮器１００は、図１の入力ブロック・メモリ１０１、ＬＺ７７エンジン１０２、及びハッシュ・メモリ１０３を含む。複数の文字から成る入力ブロック２６０６は、入力ブロック・メモリ１０１に格納される。ハッシュ・チェーン２６１１（及び、図に示されていないが、ハッシュ・チェーン２６１１を指し示すハッシュ・テーブル）は、ハッシュ・メモリ１０３に格納される。ハッシュ・チェーン２６１１は、前述したハッシュ・チェーンと同様である。ただし、図２６のハッシュ・チェーン２６１１は、確率２７０３を付加して強化されたノード２７０６（図２７に関して下で説明される）を含む。ＬＺ７７エンジン１０２は、厳密に世代に従うのではなく、下で詳細に説明されているように、確率２７０３に従って、且つ等しい確率２７０３内では世代に従ってハッシュ・チェーン２６１１内のノード２７０６を有利に順序付けして、より長い一致した文字列を検出する見込みを改善することが可能である。
【０１６６】
ＬＺ７７エンジン１０２は、互いに結合されたスキャン・エンジン２６０２及びチェーン・ソート・エンジン２６０４を含み、各エンジンは、入力ブロック・メモリ１０１及びハッシュ・メモリ１０３に結合される。一実施形態では、チェーン・ソート・エンジン２６０４は、ハッシュ・メモリ１０３へのスキャン・エンジン２６０２の接続を探って、スキャン・エンジン２６０２によってどのハッシュ・チェーン２６１１（例えば、ハッシュ・チェーンのインデックス）がアクセスされたかを検出する。それに応じて、チェーン・ソート・エンジン２６０４は、下でより詳細に説明されているように、スキャン・エンジン２６０２によって更新されたハッシュ・チェーン２６１１をソートする。
【０１６７】
ここで図２７を参照すると、図２６のハッシュ・チェーン２６１１のノード２７０６を表すブロック図が示されている。ノード２７０６は、入力ブロック・ポインタ２７０２、確率２７０３、世代２７０４、及び次のポインタ（ネクスト・ポインタ）２７０５を含む。ネクスト・ポインタ２７０５は、チェーン２６１１内の次のノード２７０６を指し示す。入力ブロック・ポインタ２７０２は、図２６の複数の文字から成る入力ブロック２６０６内の文字の位置を指し示し、この文字は、例えば、図２８のブロック２８０２で説明されているように、ハッシュ・テーブルへのインデックスを作り出すために、隣接する文字（例えば、３文字の文字列）とともにハッシュされている。世代２７０４は、ノード２７０６が、ハッシュ・テーブルのその他のノード２７０６に対してどの程度最近作成されたかを示す。一実施形態では、次の世代（ネクスト世代）の値がカウンタで維持され、ＬＺ７７エンジン１０２が入力ブロックのスキャンを開始するときにゼロに初期化され、新しいノード２７０６が作成されるたびにインクリメントされる。この意味で、世代２７０４はシリアル・ナンバーに類似している。確率２７０３は、入力ブロック・ポインタ２７０２によって指し示された文字で始まる一致する文字列へのバック・ポインタがＬＺ７７エンジン１０２によって生成されることになる見込みの相対的な指標である。チェーン・ソート・エンジン２６０４は、確率２７０３を使用して、ハッシュ・チェーン２６１１内のノード２７０６を順序付けして、より最適に一致する文字列を検出する見込みを有利に増やすことができる。以下では、動的確率の実施形態及び静的確率の実施形態が説明される。さらに、静的確率の実施形態は、ノード２７０６の確率２７０３の初期値を提供するために採用されることが可能であり、その後、この初期値は、動的確率の実施形態に従って更新されることが可能であると理解されるべきである。
【０１６８】
ここで図２８を参照すると、動的ノード確率の実施形態による、新しいノードをハッシュ・チェーンに挿入するための図２６のハードウェア・データ圧縮器１００の動作を表すフローチャートが示されている。フローは、ブロック２８０２から始まる。
【０１６９】
ブロック２８０２で、スキャン・エンジン２６０２は、現在の検索ターゲット位置で３文字をハッシュして、ハッシュ・テーブル・インデックスを作り出す。図２４及び２５に関して前述された文字数などの、異なる文字数がハッシュされる他の実施形態が企図される。フローはブロック２８０４に進む。
【０１７０】
ブロック２８０４で、チェーン・ソート・エンジン２６０４は、新しいノード２７０６を作成し、入力ブロック・ポインタ２７０２に現在の検索ターゲット位置を代入し（populates）、確率２７０３にゼロの値を代入し、世代２７０４にネクスト世代レジスタの現在の値を代入し、それから、ネクスト世代レジスタをインクリメントする。好ましくは、スキャン・エンジン２６０２が、現在の検索ターゲット位置などの、新しいノード２７０６を作成するために必要な情報をチェーン・ソート・エンジン２６０４に提供する。代替の実施形態では、スキャン・エンジン２６０２が新しいノード２７０６を作成し、チェーン・ソート・エンジン２６０４に通知する。フローはブロック２８０６に進む。
【０１７１】
ブロック２８０６で、チェーン・ソート・エンジン２６０４は、新しいノード２７０６を、ブロック２８０２で作り出されたハッシュ・テーブル・インデックスでハッシュ・チェーン２６１１に挿入する。好ましくは、チェーン・ソート・エンジン２６０４が、ゼロの確率２７０３を有する最も先の（すなわち、最も先頭に近い）ノード２７０６（ここでは、ノードＸと呼ぶ）を検出し、新しいノード２７０６のネクスト・ポインタ２７０５に、ノードＸを指し示すように代入し、ノードＸを指し示していたノード２７０６のネクスト・ポインタ２７０５（ノードＸがチェーン２６１１の先頭にあった場合は、先頭ポインタであり得る）を、新しいノード２７０６を指し示すように更新する。代替の実施形態では、スキャン・エンジン２６０２が、新しいノードをハッシュ・チェーン２６１１の先頭に挿入し、ハッシュ・チェーン２６１１をソートすること、すなわち、新しいノード２７０６をハッシュ・チェーン２６１１内の適切な位置に配置することが必要であることを、チェーン・ソート・エンジン２６０４に通知する。フローはブロック２８０６で終了する。
【０１７２】
ここで図２９を参照すると、図２８による図２６のハードウェア・データ圧縮器１００の動作を例で表すタイミング図が示されている。図２９において、時間は下向きに流れ、ノード２７０６が、それらの世代２７０４及び確率２７０３の値とともに示されている。入力ブロック・ポインタ２７０２は図に示されていないが、各ノード２７０６からの矢印は、そのノードのネクスト・ポインタ２７０５が指すノードを示している。最初の行において、１回目では、ハッシュ・チェーン２６１１は５つのノードを含んでいる。２の世代２７０４の値及び３の確率２７０３の値を持つノード２７０６がチェーン２６１１の先頭にあり、１の世代２７０４の値及び２の確率２７０３の値を持つノード２７０６がそれに続き、４の世代２７０４の値及び０の確率２７０３の値を持つノード２７０６がそれに続き、３の世代２７０４の値及び０の確率２７０３の値を持つノード２７０６がそれに続き、０の世代２７０４の値及び０の確率２７０３の値を持つ最後のノード２７０６がそれに続いている。
【０１７３】
１回目の後の２回目では、５の世代２７０４の値及び０の確率２７０３の値を持つ新しいノード２７０６が（例えば、ブロック２８０４でのように）作成される。新しいノード２７０６は、４の世代２７０４の値を持つノード２７０６が、ゼロの確率２７０３の値を持つチェーン２６１１内で最も先のノード２７０６だったため、１の世代２７０４の値を持つノード２７０６と、４の世代２７０４の値を持つノード２７０６との間に（例えば、図２８のブロック２８０６でのように）挿入される。
【０１７４】
ここで図３０を参照すると、動的ノード確率の実施形態による、ハッシュ・チェーンをソートするための図２６のハードウェア・データ圧縮器１００の動作を表すフローチャートが示されている。フローは、ブロック３００２から始まる。
【０１７５】
ブロック３００２で、スキャン・エンジン２６０２は、入力ブロック２６０６内の文字の一致する文字列を検出する。この一致する文字列は、ブロック２８０２で作り出されたインデックスによってインデックスを指されたハッシュ・チェーン２６１１内の、ノード２７０６（ここでは、ノードＫと呼ぶ）の入力ブロック・ポインタ２７０２によって指し示された位置で始まる。つまり、その一致する文字列は、現在の検索ターゲット位置によって指し示された文字で始まる入力ブロック２６０６内の文字の文字列に一致する。それに応じて、スキャン・エンジン２６０２は、一致する文字列へのバック・ポインタ、すなわち、長さ及び距離の順序付けされた対を生成する。好ましくは、一致する文字列は、例えば、バック・ポインタの距離が所定しきい値以下になる、又は中断条件が与えられた場合に検出される最長の長さになるなどの、所与の制限の下での最適な一致になるように、ＬＺ７７エンジン１０２によって考慮される。フローはブロック３００４に進む。
【０１７６】
ブロック３００４で、スキャン・エンジン２６０２は、ノードＫの確率２７０３をインクリメントする。代替の実施形態では、チェーン・ソート・エンジン２６０４は、スキャン・エンジン２６０２がチェーン・ソート・エンジン２６０４に必要な情報、例えば、ノードＫの位置を提供することに応答して、確率２７０３をインクリメントする。フローはブロック３００６に進む。
【０１７７】
ブロック３００６で、チェーン・ソート・エンジン２６０４は、インクリメントされた確率２７０３に基づいて、ノードＫを含むハッシュ・チェーン２６１１をソートする。さらに具体的には、チェーン・ソート・エンジン２６０４は、ノードＫの確率２７０３がハッシュ・チェーン２６１１内のノードＫの前のノード２７０６よりも大きい限り、ノードＫをハッシュ・チェーン２６１１内のより先の位置に（すなわち、ハッシュ・チェーン２６１１の先頭に向かって）移動する。それから、チェーン・ソート・エンジン２６０４は、ノードＫの確率２７０３がハッシュ・チェーン２６１１内のノードＫの前のノード２７０６と等しく、且つノードＫの世代２７０４がノードＫの前のノード２７０６より新しい限り、ノードＫをハッシュ・チェーン２６１１内のより先の位置に移動する。ここで、ネクスト世代２７０４の値をインクリメントする実施形態では、第１のノード２７０６が、第２のノード２７０６の世代２７０４の値よりも大きい世代２７０４の値を持っている場合、第１のノード２７０６が第２のノード２７０６よりも若い／新しいことに注意する。フローはブロック３００６で終了する。
【０１７８】
ここで図３１を参照すると、図３０による図２６のハードウェア・データ圧縮器１００の動作を例で表すタイミング図が示されている。図３１において、時間は下向きに流れ、ノード２７０６は、それらの世代２７０４及び確率２７０３の値とともに示されている。入力ブロック・ポインタ２７０２は図に示されていないが、各ノード２７０６からの矢印は、そのノードのネクスト・ポインタ２７０５が指すノードを示している。最初の行において、１回目では、ハッシュ・チェーン２６１１は３つのノードを含んでいる。０の世代２７０４の値及び３の確率２７０３の値を持つノード２７０６がチェーン２６１１の先頭にあり、１の世代２７０４の値及び２の確率２７０３の値を持つノード２７０６がそれに続き、２の世代２７０４の値及び１の確率２７０３の値を持つ最後のノード２７０６がそれに続いている。
【０１７９】
その後、スキャン・エンジン２６０２は、例えば図３０のブロック３００２で、ノード２（すなわち、２の世代２７０４の値を持つノード２７０６）の入力ブロック・ポインタ２７０２を使用して、文字列の一致に基づいてバック・ポインタを生成する。１回目の後の２回目では、２番目の行に示すように、スキャン・エンジン２６０２がノード２の確率２７０３の値を１から２にインクリメントする。それに応じて、チェーン・ソート・エンジン２６０４は、例えば図３０のブロック３００６で、ノード２と、ノード２の前のノード２７０６であるノード１（すなわち、１の世代２７０４の値を持つノード２７０６）との、ハッシュ・チェーン２６１１内での場所を交換する。これは、２番目の行でも示されているように、現在、ノード２がノード１と同じ確率２７０３の値（２）を有しており、ノード２がノード１よりも新しいからである。
【０１８０】
その後、２回目、スキャン・エンジン２６０２は、ノード２の入力ブロック・ポインタ２７０２を使用して、文字列の一致に基づいてバック・ポインタを生成する。２回目の後の３回目では、３番目の行に示すように、スキャン・エンジン２６０２がノード２の確率２７０３の値を２から３にインクリメントする。それに応じて、チェーン・ソート・エンジン２６０４は、ノード２と、ノード２の前のノード２７０６であるノード０（すなわち、０の世代２７０４の値を持つノード２７０６）との、ハッシュ・チェーン２６１１内での場所を交換する。これは、３番目の行でも示されているように、現在、ノード２がノード０と同じ確率２７０３の値（３）を有しており、ノード２がノード０よりも新しいからである。
【０１８１】
ここで図３２及び３３を参照すると、図３３に示されたルックアップ・テーブル３３０２を作成するための方法を表すフローチャートが図３２に示されており、このルックアップ・テーブル３３０２は、静的なハッシュ・チェーン・ノード確率の実施形態で使用される。好ましくは、図３２に関して説明される方法は、自動化された方法、例えば、ソフトウェアで実行される。好ましくは、ハードウェア・データ圧縮器１００による複数の文字から成る入力ブロックの圧縮の前に、ユーザ（例えば、ハードウェア・データ圧縮器１００の製造業者又はエンド・ユーザ）がこの方法を実行する。例えば、この方法は、製造業者によって実行され、ハードウェア・データ圧縮器１００とともにエンド・ユーザに提供されることが可能である。或いは、製造業者がルックアップ・テーブル３３０２を作成し、その後、エンド・ユーザが製造業者からルックアップ・テーブル３３０２をダウンロードする。或いは、ハードウェア・データ圧縮器１００を使用してエンド・ユーザが頻繁に圧縮するファイルに合わせて調整されたカスタム・ルックアップ・テーブル３３０２を、エンド・ユーザ自身が作成する。この場合、好ましくは、製造業者がエンド・ユーザに、この方法を具現化するソフトウェアを提供する。一実施形態では、ルックアップ・テーブル３３０２は、テーブル・メモリ１０７内に格納されるが、ルックアップ・テーブル３３０２が他のメモリの１つ（例えば、１０１、１０３、又は１０５）に格納される他の実施形態が企図される。一実施形態では、ルックアップ・テーブル３３０２は、連想記憶装置（ｃｏｎｔｅｎｔ−ａｄｄｒｅｓｓａｂｌｅ  ｍｅｍｏｒｙ：ＣＡＭ）に格納され、このＣＡＭ内で、図３３の４文字の文字列３３０３は入力アドレスと比較される内容であり、ＣＡＭは、一致する文字列３３０３に対応するスコア３３０４を出力し、一致が検出されない場合、ＣＡＭは失敗のインジケータとしてｔｒｕｅ値を発生させる。フローは、ブロック３２０２から始まる。
【０１８２】
ブロック３２０２で、ユーザ（例えば、製造業者、又はサーバ・ファーム管理者などのエンド・ユーザ）は、その後ハードウェア・データ圧縮器１００によって圧縮される入力ブロックの代表になることを期待する、複数の文字から成る入力ブロックのセットを収集する。例えば、英語テキストの場合、ユーザは数百の英語の作品から入力ブロックのセットを収集できる。別の例では、ユーザは多くのＨＴＭＬファイル、オーディオファイル、又は画像ファイルから入力ブロックのセットを収集できる。その後ユーザは、入力ブロックのセット内で最も頻繁に出現するＪ個の４文字の文字列、及びこれら４文字文字列の各々の出現頻度をリストにまとめる。Ｊは、相対的に大きい整数（例えば、５００〜５，０００）であり、ルックアップ・テーブル３３０２のサイズに割り当てることができる所望のメモリ量、及びノード２７０６の確率２７０３に基づくハッシュ・チェーン２６１１のソートに起因する文字列一致検索の効率向上による所望のスピードアップに依存する。フローはブロック３２０４に進む。
【０１８３】
ブロック３２０４で、ユーザは、ブロック３２０２で蓄積されたテーブルのＪ個の４文字の文字列の各々について、ＬＺ７７エンジン１０２によって採用される（例えば、図２４の３文字のハッシュ・インデックス・ジェネレータ２４３２によって採用される）同じハッシュ・アルゴリズムを使用して文字列の最初の３文字をハッシュして、文字列のインデックスを作り出す。したがって、このインデックスは、その後ＬＺ７７エンジン１０２によって作り出されることが可能であり、ハッシュ・メモリ１０３内のハッシュ・テーブルへのインデックス（例えば、図２４の３文字のハッシュ・テーブル２４３８への３文字のハッシュ・テーブル・インデックス２４３４）と同じ値を持つ。フローはブロック３２０６に進む。
【０１８４】
ブロック３２０６で、ユーザは、ブロック３２０４で作り出された各インデックス値について、Ｊ個の文字列のうち、その先頭３文字がインデックスにハッシュされている文字列の各グループについて、グループ内の文字列の頻度を調べ、グループの各文字列の、グループの他の文字列に対する頻度に基づいて、グループの各文字列にスコアを割り当てる。例えば、４つの文字列が同じインデックスにハッシュされ、ブロック３２０２により、それぞれ８、１１、９８、及び１６の頻度を持ったと仮定する。次にユーザは、最低のスコアを第１の文字列に、次に低いスコアを第２の文字列に、最高のスコアを第３の文字列に、次に高いスコアを第４の文字列に割り当てる。例えば、１、２、４、３である。その後、これらスコアは、例えば、ブロック３２０８で、ルックアップ・テーブル３３０２に代入するために使用されることが可能である。これらの４文字の文字列が、後でハードウェア・データ圧縮器１００によって圧縮される複数の文字から成る入力ブロック内で出現した場合、ノード２７０６がそれらに対して作成され、ハッシュ・チェーン２６１１に挿入され、下でより詳細に説明されているように、チェーン・ソート・エンジン２６０４が、ルックアップ・テーブル３３０２内の上記スコアを利用して、ハッシュ・チェーン２６１１をソートする。フローはブロック３２０８に進む。
【０１８５】
ブロック３２０８で、ユーザは、ブロック３２０２で蓄積された４文字の文字列及びブロック３２０６で割り当てられたそれらに関連するスコアのルックアップ・テーブル３３０２を作成する。その例が、図３３に示されている。ルックアップ・テーブル３３０２は、図３３で配列として示されているが、ツリーやハッシュ・テーブルなどのさまざまな形態で配置されることも可能である。ルックアップ・テーブル３３０２は、図３４及び３５に関して下で説明されているように、確率２７０３をハッシュ・チェーン２６１１のノード２７０６に割り当てるために使用されることが可能である。フローはブロック３２０８で終了する。
【０１８６】
ここで図３４を参照すると、静的なノード確率の実施形態による、ハッシュ・チェーンをソートするための図２６のハードウェア・データ圧縮器１００の動作を表すフローチャートが示されている。フローは、ブロック３４０２から始まる。
【０１８７】
ブロック３４０２で、スキャン・エンジン２６０２は、現在の検索ターゲット位置で３文字をハッシュして、ハッシュ・テーブル・インデックスを作り出す。フローはブロック３４０４に進む。
【０１８８】
ブロック３４０４で、チェーン・ソート・エンジン２６０４は、新しいノード２７０６を作成し、入力ブロック・ポインタ２７０２に現在の検索ターゲット位置を代入し、世代２７０４にネクスト世代レジスタの現在の値を代入し、その後、ネクスト世代レジスタをインクリメントする。好ましくは、スキャン・エンジン２６０２が、現在の検索ターゲット位置などの、新しいノード２７０６を作成するために必要な情報をチェーン・ソート・エンジン２６０４に提供する。代替の実施形態では、スキャン・エンジン２６０２が新しいノード２７０６を作成し、チェーン・ソート・エンジン２６０４に通知する。フローはブロック３４０６に進む。
【０１８９】
ブロック３４０６で、チェーン・ソート・エンジン２６０４は、入力ブロック２６０６の現在の検索ターゲット位置の３文字（すなわち、ブロック３４０２でハッシュされた３文字）及び隣接する次の文字で構成された４文字の文字列を受け取る。フローはブロック３４０８に進む。
【０１９０】
ブロック３４０８で、チェーン・ソート・エンジン２６０４は、ブロック３４０６で作成された４文字の文字列の、ルックアップ・テーブル３３０２内の文字列３３０３の１つとの一致を検索する。一致が検出された場合、チェーン・ソート・エンジン２６０４は、新しいノード２７０６の確率２７０３に、一致する文字列３３０３に関連付けられたスコア３３０４を割り当て、一致が検出されない場合、チェーン・ソート・エンジン２６０４は、新しいノード２７０６の確率２７０３に、ゼロの値を割り当てる。フローはブロック３４１２に進む。
【０１９１】
ブロック３４１２で、チェーン・ソート・エンジン２６０４は、新しいノード２７０６を、ブロック３４０２で作り出されたインデックスでハッシュ・チェーン２６１１に挿入する。チェーン・ソート・エンジン２６０４は、ハッシュ・チェーン２６１１内の他のノード２７０６に対する確率に基づいて、新しいノード２７０６を挿入する。具体的には、チェーン・ソート・エンジン２６０４は、新しいノード２７０６を、ハッシュ・チェーン２６１１内の低い確率２７０３を持つノード２７０６よりも先で、高い確率２７０３を持つノード２７０６よりも後に挿入する。等しい確率２７０３のノード２７０６について、チェーン・ソート・エンジン２６０４は、より新しいノード２７０６を、相対的により古いノード２７０６の前に順序付ける。したがって、現在最新のノード２７０６である新しいノード２７０６は、それと同じ確率２７０３を持つ他のすべてのノード２７０６の前に挿入される。フローはブロック３４１２で終了する。
【０１９２】
ここで図３５を参照すると、図３４による図２６のハードウェア・データ圧縮器１００の動作を例で表すタイミング図が示されている。図３５において、時間は下向きに流れ、ノード２７０６は、世代２７０４及び確率２７０３の値とともに示されている。入力ブロック・ポインタ２７０２は図に示されていないが、各ノード２７０６からの矢印は、そのノードのネクスト・ポインタ２７０５が指すノードを示している。最初の行において、１回目では、ハッシュ・チェーン２６１１は５つのノードを含んでいる。２の世代２７０４の値及び８の確率２７０３の値を持つノード２７０６がチェーン２６１１の先頭にあり、１の世代２７０４の値及び６の確率２７０３の値を持つノード２７０６がそれに続き、４の世代２７０４の値及び５の確率２７０３の値を持つノード２７０６がそれに続き、３の世代２７０４の値及び１の確率２７０３の値を持つノード２７０６がそれに続き、０の世代２７０４の値及び０の確率２７０３の値を持つ最後のノード２７０６がそれに続く。
【０１９３】
１回目の後の２回目では、５の世代２７０４の値及び１の確率２７０３の値を持つ新しいノード２７０６が（例えば、ブロック３４０４〜３４０８でのように）作成される。新しいノード２７０６は、４の世代２７０４の値を持つノード２７０６と、３の世代２７０４の値を持つノード２７０６との間に（例えば、図３４のブロック３４１２で）挿入される。これは、４の世代２７０４の値を持つノード２７０６が、新しいノード２７０６よりも大きい確率２７０３の値を有しており、新しいノード２７０６は、３の世代２７０４の値を持つノード２７０６と等しい確率２７０３の値を有し、且つ３の世代２７０４の値を持つノード２７０６よりも新しいからである。
【０１９４】
３文字がハッシュされ、ルックアップ・テーブル３３０２の文字列３３０３の長さが４文字である実施形態が説明されているが、ハッシュされる文字数が３よりも大きく、文字列の長さが４よりも長い他の実施形態が企図される。ただし、その実施形態では、ハッシュされる文字の後に続く１つ又は複数の文字を決定するために、文字列の長さの文字数はハッシュの文字数よりも多い。
【０１９５】
図２６〜３５の説明から観察できるように、ハッシュ・チェーン２６１１の各ノード２７０６は、その確率２７０３に従って順序付けされることが可能である。その場合、入力ブロック２６０６内の文字で始まる一致する文字列へのバック・ポインタは、スキャン・エンジン２６０２が中断基準に達する前に、世代のみによって順序付けされたハッシュ・チェーン２６１１を使用して検出されるであろう文字列よりも長い一致する文字列が検出され、それにより圧縮率ができれば改善されることになる見込みが増えることを期待して、スキャン・エンジン２６０２によって生成される。図２８〜３１に関連する実施形態は、入力ブロック２６０６のスキャンの間、一致する文字列を検出してバック・ポインタを生成するためにノード２７０６がより頻繁に使用されるとき、ノード２７０６の確率２７０３が増えることが可能な動的スキームを採用しており、一方、図３２〜３５に関連する実施形態は、ノード２７０６の確率２７０３が、入力ブロックの代表的なサンプル内の文字列の頻度についての事前解析に基づいて割り当てられる、静的スキームを採用している。
【０１９６】
ＬＺ７７エンジンからのトークンを直接ハフマン・エンコードするハードウェア・データ圧縮器
ファイルを圧縮してインターネットを経由して転送するＷｅｂサーバなどのサーバの利用が急増するにつれて、そのようなサーバで使用するためのハードウェア・データ圧縮器の必要性も急増する可能性が高い。その結果、低コスト且つ低消費電力のハードウェア・データ圧縮器に対する需要が促進される可能性がある。
【０１９７】
ここで図３６を参照すると、代替の実施形態によるハードウェア・データ圧縮器３６００を表すブロック図が示されている。ハードウェア・データ圧縮器３６００は、図１のハードウェア・データ圧縮器１００と同様に、入力ブロック・メモリ１０１、ＬＺ７７エンジン１０２、ハッシュ・メモリ１０３、ハフマン・エンコーディング・エンジン１０８、及び出力メモリ１０９を含む。下でより詳細に説明されているように、ハードウェア・データ圧縮器３６００は、トークン３６１２を直接ハフマン・エンコーディング・エンジン１０８に供給し、ハフマン・エンコーディング・エンジン１０８は、各トークン３６１２が受信されると、それらを直ちにハフマン・エンコードし、結果として生じるハフマン・コードを出力メモリ１０９に書き込む。したがって、ハードウェア・データ圧縮器３６００は、バック・ポインタ・メモリ１０５を含む必要がない。さらに、事前蓄積済みハフマン・コード・テーブルが採用されるため、図１のソート・エンジン１０４もハフマン・コード・テーブル構築エンジン１０６も、ハードウェア・データ圧縮器３６００に含まれる必要がない。本明細書に記載された代替モードでの動作の間、ハードウェア・データ圧縮器３６００において、バック・ポインタ・メモリ１０５（及び、ソート・エンジン１０４とハフマン・コード・テーブル構築エンジン１０６）が存在しないか、又は少なくとも使用されないことによって、図１の実施形態などの他の実施形態よりもコスト、サイズ、及び消費電力を有利に削減することができる。
【０１９８】
一実施形態では、ハフマン・エンコーディング・エンジン１０８はＣＡＭを備え、ＣＡＭにおいて、ハフマン・コード・テーブルのシンボル値は、ハフマン・エンコードされる入力シンボルと比較される内容であり、ＣＡＭは、一致した入力シンボルに対応するハフマン・コードを出力する。好ましくは、ＣＡＭは、３つのリテラル・シンボルがトークン３６１２に関連付けられた場合、又はバック・ポインタのトークン３６１２の長さ及び距離がＣＡＭに入力された場合に対応するために、３つのシンボル入力を同時に受信し、３つのそれぞれのハフマン・コードを同時に出力するように構成される。ＬＺ７７エンジン１０２が入力ブロックのスキャンを開始する前に、事前に蓄積されたリテラル／長さ及び距離のハフマン・コード・テーブルが、ＣＡＭにロードされる。好ましくは、ＣＡＭへの３つの入力の各々が、ＬＺ７７エンジン１０２によって提供される関連付けられた信号を有し、該信号は、シンボルがリテラル／長さであるか、又は距離であるかを示し、ＣＡＭがリテラル／長さハフマン・コード・テーブルにアクセスすべきか又は距離ハフマン・コード・テーブルにアクセスすべきかを決定できるようにする。好ましくは、バック・ポインタの長さ及び距離の追加ビットは、ＬＺ７７エンジン１０２から渡され、ＣＡＭによって出力された値と共に適切に順序付けされ、出力メモリ１０９に書き込まれる。
【０１９９】
ここで図３７を参照すると、図３６のハードウェア・データ圧縮器３６００の動作を表すフローチャートが示されている。図３７において、ＬＺ７７エンジン１０２はブロック３７０２及び３７０４で動作し、ハフマン・エンコーディング・エンジン１０８はブロック３７１２及び３７１４で動作する。フローは、ブロック３７０２から始まる。
【０２００】
ブロック３７０２で、ＬＺ７７エンジン１０２は入力ブロックをスキャンし、入力ブロック内の現在の検索ターゲット位置で文字列の一致を検索する。フローはブロック３７０４に進む。
【０２０１】
ブロック３７０４で、ＬＺ７７エンジン１０２は、ハフマン・エンコーディング・エンジン１０８に対してトークン３６１２を生成し、現在の検索ターゲット位置を更新する。フローはＬＺ７７エンジン１０２に関するブロック３７０２に戻って（ブロック終結文字に直面するまで）次の文字列を検索し、同時に、フローはハフマン・エンコーディング・エンジン１０８に関する判定ブロック３７１２に進む。
【０２０２】
判定ブロック３７１２で、ハフマン・エンコーディング・エンジン１０８は、ＬＺ７７エンジン１０２がハフマン・エンコーディング・エンジン１０８のためのトークン３６１２を生成したかどうかを決定する。生成していた場合、フローはブロック３７１４に進み、生成していない場合、ＬＺ７７エンジン１０２がトークン３６１２を生成するまでは、フローは判定ブロック３７１２に戻る。
【０２０３】
ブロック３７１４で、ハフマン・エンコーディング・エンジン１０８は、ＬＺ７７エンジン１０２から受信されたトークン３６１２の各シンボルについて、シンボルをハフマン・エンコードし、ハフマン・コードを出力メモリ１０９に書き込む。フローは判定ブロック３７１２に戻る。
【０２０４】
有利なことに、ハフマン・エンコーディング・エンジン１０８は、ＬＺ７７エンジン１０２がブロック３７０２及び３７０４で動作を実行する時間と同様の時間をかけてブロック３７１２及び３７１４で動作を実行するように構成される。つまり、ＬＺ７７エンジン１０２によって生成される連続する各トークン３６１２間の時間は、トークン３６１２を受信してハフマン・エンコードし、結果として生じるハフマン・コードを出力メモリ１０９に書き込むためにハフマン・エンコーディング・エンジン１０８によって必要とされる時間を上回るか、又は等しい。したがって、トークン３６１２を中間的な格納のためのメモリに書き込む必要がなく、トークン３６１２をメモリから読み出す必要がない。
【０２０５】
ここで図３８を参照すると、図３７の方法による図３６のハードウェア・データ圧縮器３６００の動作を表すタイミング図が示されている。上側部分はＬＺ７７エンジン１０２の動作を示し、下側部分はハフマン・エンコーディング・エンジン１０８の動作を示している。時間は左から右に進んでいる。図に示されている時間はクロック・サイクルを表しているが、ナノ秒などの、関連する他の時間単位が企図される。
【０２０６】
図に示されているように、サイクル０でＬＺ７７エンジン１０２が、（例えば、図３７のブロック３７０２でのように）現在の検索位置での入力ブロックのスキャンを開始して、文字列の一致の最初の検索（Ｓ１で示される）を実行し、サイクル３でトークン３６１２（ＴＯＫ１で示される）をハフマン・エンコーディング・エンジン１０８に出力する。それに応じて、ハフマン・エンコーディング・エンジン１０８は、（例えば、図３７のブロック３７１４でのように）ＴＯＫ１に関連付けられたシンボルの各々をハフマン・エンコードし、結果として生じたハフマン・コードを出力メモリ１０９に書き込む。この動作は、ＬＺ７７エンジン１０２がその次の検索（Ｓ２）を終了し、サイクル１０で２番目のトークン（ＴＯＫ２）を出力する前に、サイクル６で終了する。それに応じて、ハフマン・エンコーディング・エンジン１０８は、ＴＯＫ２に関連付けられたシンボルの各々をハフマン・エンコードし、結果的に生じたハフマン・コードを出力メモリ１０９に書き込む。この動作は、ＬＺ７７エンジン１０２がその次の検索（Ｓ３）を終了し、サイクル１３で別のトークン（ＴＯＫ３）を出力する前に、サイクル１３で終了する。それに応じて、ハフマン・エンコーディング・エンジン１０８は、ＴＯＫ３に関連付けられたシンボルの各々をハフマン・エンコードし、結果的に生じたハフマン・コードを出力メモリ１０９に書き込む。この動作は、ＬＺ７７エンジン１０２がその次の検索（Ｓ４）を終了し、サイクル７２で別のトークン（ＴＯＫ４）を出力する前に、サイクル１６で終了する。それに応じて、ハフマン・エンコーディング・エンジン１０８は、ＴＯＫ４に関連付けられたシンボルの各々をハフマン・エンコードし、結果的に生じたハフマン・コードを出力メモリ１０９に書き込む。この動作は、ＬＺ７７エンジン１０２がその次の検索（Ｓ５）を終了し、サイクル７５で別のトークン（ＴＯＫ５）を出力する前に、サイクル７５で終了する。それに応じて、ハフマン・エンコーディング・エンジン１０８は、ＴＯＫ５に関連付けられたシンボルの各々をハフマン・エンコードし、結果的に生じたハフマン・コードを出力メモリ１０９に書き込む。この動作は、サイクル７８で終了する。
【０２０７】
図３７に示されているように、トークン３６１２を生成するためにＬＺ７７エンジン１０２によって必要とされるクロック・サイクル数は変化する可能性があり、例えば、Ｓ４は５９クロック・サイクルを必要とし、通常これは比較的長いハッシュ・チェーンを示し、一方、Ｓ１、Ｓ３、及びＳ５は３クロック・サイクルしか必要とせず、通常これはハッシュ・チェーンが空だったことを示す。それにもかかわらず、有利なことにハフマン・エンコーディング・エンジン１０８は、ＬＺ７７エンジン１０２によって生成された各トークン３６１２に関連付けられたシンボルを、各トークンが生成されたときにハフマン・エンコードし、それにより、バック・ポインタをメモリに書き込む必要性又はこれらをメモリから読み出す必要性を有利に軽減する。
【０２０８】
一実施形態では、約２５ＫＢのメモリが、図１に関して説明されたような実施形態で節約される。この実施形態では、バック・ポインタ及びフラグ・メモリ１０５が、約８Ｋｘ２４ビットのバック・ポインタと１６Ｋｘ１ビットのフラグとを保持するように構成されている。
【０２０９】
一実施形態では、ハードウェア・データ圧縮器１００は、（例えば、図３〜２０に関して前述したモードなどの、他のモードで動作するために）バック・ポインタ及びフラグ・メモリ１０５を含む。ただし、図３６〜３８に関して説明されるモードで動作する場合、そのような実施形態では、メモリ・ハードウェアの節約は実現されないが、それでもなお、電力の節約は実現されることが可能である。これは、電力が、ＬＺ７７エンジン１０２によるメモリへのバック・ポインタ及びフラグの書き込みによって消費されず、ハフマン・エンコーディング・エンジン１０８によるメモリからのバック・ポインタ及びフラグの読み出しによっても消費されないからである。
【０２１０】
入力ブロック・タイプに基づく動的ハッシュ・アルゴリズムを使用したハードウェア・データ圧縮器
図２４のハッシュ・インデックス・ジェネレータ２４３２及び２４４２などのハッシュ・インデックス・ジェネレータによって使用されるハッシュ・アルゴリズムを作成する際に考慮すべき目標の１つは、ハッシュ・テーブル上のハッシュ・インデックスの分布をできるだけ相対的に均一にすることである。そうすることで、非常に長いハッシュ・チェーンが発生する見込みが減るか、又は少なくとも問題を悪化させない傾向があり、ＬＺ７７エンジン１０２のスキャンに関連した一致する文字列の検索時間を改善することができる。これは少なくとも、ある程度は、ハッシュのエイリアシング又はハッシュの衝突の概念に起因する。ハッシュのエイリアシングは、異なる入力が同じハッシュ・インデックスにハッシュされた場合に生じる。例えば、ハッシュ・アルゴリズムに依存して、文字「ｔｈｅ」は文字「ｗａｓ」と同じインデックスにハッシュされる場合がある。これは、例えば、英語テキストでは「ｔｈｅ」及び「ｗａｓ」が頻繁に出現する傾向があり、そのインデックスのハッシュ・チェーンが非常に長くなる可能性があるため、ほとんどの英語テキストの入力ブロックにとって特に望ましくない。
【０２１１】
上の例からわかるように、一般的な英単語が異なるインデックスにハッシュされる傾向がある英語テキスト用のハッシュ・アルゴリズムが存在することは有利である。ただし、ハードウェア・データ圧縮器１００は、英語テキスト以外のタイプの入力ブロックを圧縮するために使用されることが可能である。したがって、話されない／記述される言語（例えば、ＨＴＭＬ、Ｊａｖａなど）を含むその他の言語のための、相対的に均一なハッシュ・インデックスの分布を生成する傾向があるハッシュ・アルゴリズムが存在することは有利である。さらに、非言語タイプ（例えば、スプレッドシート、実行可能バイナリ・ファイルなど）を含むその他の入力ブロック・タイプのための、相対的に均一なハッシュ・インデックスの分布を生成する傾向があるハッシュ・アルゴリズムが存在することは有利である。
【０２１２】
ここで図３９を参照すると、図１のＬＺ７７エンジン１０２の一部を表すブロック図が示されている。図３９〜４１の実施形態では、圧縮される入力ブロックの種類を示すために、入力ブロック・タイプ３９０１（例えば、テキスト、スプレッドシート、ワード・プロセッサ、ＰＤＦ、ＨＴＭＬ、Ｊａｖａなど）がハードウェア・データ圧縮器１００に提供され、ＬＺ７７エンジン１０２が、入力ブロック・タイプ３９０１に依存して異なるハッシュ・アルゴリズムを採用する。一部の実施形態では、ハッシュされるビットの数は、入力ブロック・タイプ３９０１によって変化する。例えば、入力ブロック・タイプがＡＳＣＩＩテキストである場合、各文字（バイト）の上位ビットはハッシュに含まれず、例えば、２４ビットでなく２１ビットがハッシュされる。例えば、図４１を参照されたい。一般的に言えば、上位ビットは常にゼロであり、分布を歪める可能性があるため、上記のことは、より良好な分布を提供する。他の実施形態では、ハッシュ・アルゴリズムによって実行される算術／論理演算が、入力ブロック・タイプによって変化する。さらに、他の実施形態では、ハッシュ・アルゴリズムによってハッシュされる入力ブロックの文字の数が、入力ブロック・タイプによって変化する。
【０２１３】
ＬＺ７７エンジン１０２は、ハッシュ・テーブル３９４８とノード３９０６のハッシュ・チェーン３９４１とを含む。ハッシュ・テーブル３９４８、ハッシュ・チェーン３９４１、及びノード３９０６は、図２４、２６、及び２７のハッシュ・テーブル、ハッシュ・チェーン、及びノード２４４８、２４３８、２４３１、２４４１、２６１１、２４０６、及び２７０６と同様とすることが可能である。ハッシュ・テーブル３９４８は、ＭＵＸ３９９９の出力であるインデックス３９４４によってインデックスを指される。ＭＵＸ３９９９は、入力ブロック・タイプ・インジケータ３９０１を制御入力として受信する。入力ブロック・タイプ３９０１に基づき、ＭＵＸ３９９９は、複数のインデックス３９５４−Ａ、３９５４−Ｂ、及び３９５４−Ｃ（個々を一般化して３９５４と呼び、且つまとめて３９５４と呼ぶ）のうちの１つを選択して、インデックス３９４４として出力する。複数のインデックス３９５４の各々は、それぞれのハッシュ・テーブル・インデックス・ジェネレータ３９４２−Ａ、３９４２−Ｂ、及び３９４２−Ｃ（個々を一般化して３９４２と呼び、且つまとめて３９４２と呼ぶ）によって作り出される。ハッシュ・テーブル・インデックス・ジェネレータ３９４２の各々は、現在の検索ターゲット位置３９０２で、複数の文字から成る入力ブロック３９０４の最初の文字３９３６（例えば３）をハッシュするが、そのそれぞれのインデックス３９５４を生成するために、アルゴリズムＡ、アルゴリズムＢ、及びアルゴリズムＣと呼ばれる異なるハッシュ・アルゴリズムを各々が使用する。一実施形態では、１つ又は複数のハッシュ・アルゴリズムは、図２４及び２５に関して前述したハッシュ・アルゴリズム、つまり、３バイト・ハッシュ・アルゴリズム及び４バイト・ハッシュ・アルゴリズムにすることができる。
【０２１４】
ここで図４０を参照すると、図３９のＬＺ７７エンジン１０２の動作を表すフローチャートが示されている。フローは、ブロック４００２から始まる。
【０２１５】
ブロック４００２で、ＭＵＸ３９９９は入力ブロック・タイプ３９９９を受信する。フローはブロック４００４に進む。
【０２１６】
ブロック４００４で、ハッシュ・テーブル・インデックス・ジェネレータ３９４２の各々は、それぞれ異なるハッシュ・アルゴリズムを使用して最初の文字３９３６をハッシュして、ＭＵＸ３９９９に提供されるそれぞれのインデックス３９５４を生成し、ＭＵＸは、入力ブロック・タイプ３９０１に基づいて、インデックス３９５４のうちの１つを選択してインデックス３９４４として出力する。こうして、ＭＵＸ３９９９は、入力ブロック・タイプ３９０１に基づいて、ハッシュ・アルゴリズムのうちの１つを効率的に選択する。フローはブロック４００６に進む。
【０２１７】
ブロック４００６で、ブロック４００４で作り出されたインデックス３９４４は、ハッシュ・テーブル３９４８のインデックスを指してハッシュ・チェーン３９４１のうちの１つを選択するために使用され、その選択されたハッシュ・チェーン３９４１をＬＺ７７エンジン１０２が使用して、現在の検索ターゲット位置３９０２によって指し示された入力ブロック３９０４の位置で始まる文字列の一致について、上記選択されたハッシュ・チェーン３９４１のノード３９０６によって指し示された位置で入力ブロック３９０４内を検索する。フローはブロック４００６で終了する。
【０２１８】
ここで図４１を参照すると、図３９のハッシュ・インデックス・ジェネレータ３９４２のうちの１つをより詳細に表すブロック図が示されている。図４１のハッシュ・インデックス・ジェネレータ３９４２は、そのハッシュ・アルゴリズムにおいて、入力ブロック３９３６からの文字のすべてのビットを使用するわけではないという点が、他と異なっている。さらに具体的には、図に示されているように、ハッシュ・インデックス・ジェネレータ３９４２は、入力ブロック３９３６の３文字（図４１では、第１の文字、第２の文字、及び第３の文字で示される）の、３文字の各々の最上位ビット（ｍｏｓｔ  ｓｉｇｎｉｆｉｃａｎｔ  ｂｉｔ：ＭＳＢ）を除くあらゆるビットを受信し、そのハッシュ・アルゴリズムで使用する。ハッシュ・インデックス・ジェネレータ３９４２は、図に示されている２１ビット、すなわち、第１の文字、第２の文字、及び第３の文字のそれぞれの下位７ビットをハッシュして、図３９のＭＵＸ３９９９に提供されるインデックス３９５４を作り出す。下の表６は、図４１のハッシュ・インデックス・ジェネレータ３９４２によって２１ビットをハッシュするために使用されるハッシュ・アルゴリズムの例である。ただし、他の実施形態が企図されており、表６のハッシュ・アルゴリズムは、説明のための例として提供されている。さらに、入力ブロック３９３６の文字のすべてのビットよりも少ない、各文字の下位７ビット以外のビットがハッシュされる他の実施形態が企図される。図４１の実施形態は、特に、各文字（バイト）の上位ビットがゼロになる傾向があって、それによりハッシュ・インデックスの分布が不均一になりやすい、ＡＳＣＩＩテキストの入力ブロック・タイプ３９０１に適している可能性がある。
【０２１９】
【表６】
0006363581.tif 000007
【０２２０】
ここで図４２を参照すると、図１などのハードウェア・データ圧縮器１００を含むシステム４２００を表すブロック図が示されている。システム４２００は、システム・バス４２０４によってメモリ４２０６、ハードウェア・データ圧縮器１００、及び他のペリフェラル４２０８に接続されたプロセッサ４２０２を含む。プロセッサ４２０２は、システム・バス４２０４を介してコマンドをハードウェア・データ圧縮器１００に送信する。好ましくは、ハードウェア・データ圧縮器１００は、Ｉ／Ｏ空間にマッピングされる制御及びステータス・レジスタ（ｃｏｎｔｒｏｌ  ａｎｄ  ｓｔａｔｕｓ  ｒｅｇｉｓｔｅｒｓ：ＣＳＲ）を含み、このＣＳＲによってプロセッサ４２０２が、複数の文字から成る入力ブロックを圧縮するためなどのコマンドを送信する。或いは、ＣＳＲは、Ｉ／Ｏではなくメモリにマッピングされることも可能である。さらに、好ましくは、ハードウェア・データ圧縮器１００のメモリの１つ又は複数がメモリ空間にマッピングされる。特に、入力ブロック・メモリ１０１、出力メモリ１０９、及びテーブル・メモリ１０７は、プロセッサ４２０２によって書き込み可能及び／又は読み出し可能にすることができる。例えば、プロセッサ４２０２は、圧縮されるべき複数の文字から成る入力ブロックをシステム・メモリ４２０６から入力ブロック・メモリ１０１に書き込む（又は、ダイレクト・メモリ・アクセス（ｄｉｒｅｃｔ  ｍｅｍｏｒｙ  ａｃｃｅｓｓ  ：ＤＭＡ）動作に、この書き込みを実行させる）ことができ、プロセッサ４２０２は、ハードウェア・データ圧縮器１００が入力ブロックの圧縮を終了したときに、圧縮された出力ブロックを出力ブロック・メモリ１０９からシステム・メモリ４２０６に読み出す（又は、ダイレクト・メモリ・アクセス（ＤＭＡ）動作に、この読み出しを実行させる）ことができる。或いは、プロセッサ４２０２は、ハードウェア・データ圧縮器１００に、複数の文字から成る入力ブロックのシステム・メモリ４２０６内のアドレスを提供することができ、ハードウェア・データ圧縮器１００は、そのアドレスを入力ブロック・メモリ１０１に読み出す（又は、ダイレクト・メモリ・アクセス（ＤＭＡ）動作に、この読み出しを実行させる）ことができ、プロセッサ４２０２は、ハードウェア・データ圧縮器１００に、圧縮されたブロックを書き込ませたいシステム・メモリ４２０６内のアドレスを提供することができ、ハードウェア・データ圧縮器１００は、入力ブロックの圧縮を終了したときに、圧縮されたブロックを出力ブロック・メモリ１０９からそのアドレスに書き込む（又は、ダイレクト・メモリ・アクセス（ＤＭＡ）動作に、この書き込みを実行させる）ことができる。さらに、プロセッサ４２０２は、前述した事前に蓄積されたテーブル及び／又は「参照」テーブルなどのハフマン・コード・テーブルを、（前述した方法と同様の方法のうちの１つで）テーブル・メモリ１０７に代入することができる。
【０２２１】
ここで図４３を参照すると、代替の実施形態によるハードウェア・データ圧縮器１００を含むシステム４３００を表すブロック図が示されている。図４３のシステム４３００は、図４２のシステム４２００に類似している。ただし、図４３のシステム４３００では、プロセッサ４３０２はハードウェア・データ圧縮器１００を備える。つまり、ハードウェア・データ圧縮器１００は、プロセッサ４３０２のアーキテクチャ的な機能ユニットである。プロセッサ４３０２は、命令セット・アーキテクチャ（ｉｎｓｔｒｕｃｔｉｏｎ  ｓｅｔ  ａｒｃｈｉｔｅｃｔｕｒｅ：ＩＳＡ）内に命令を含み、プロセッサ４３０２上で実行されるソフトウェアは、上記命令を実行して、ハードウェア・データ圧縮器１００を制御したり、ハードウェア・データ圧縮器１００にアクセスしたりすることができる。一実施形態では、プロセッサ４３０２は、ソース・オペランドとデスティネーション・オペランドと制御オペランドとが含まれるＣＯＭＰＲＥＳＳ  ＢＬＯＣＫ命令を含む。ソース・オペランドは、圧縮されるべき複数の文字から成る入力ブロックのシステム・メモリ４２０６内の位置を指定し、デスティネーション・オペランドは、圧縮されたブロックが書き込まれるべき位置を指定し、制御オペランドは、データ圧縮を実行するためにハードウェア・データ圧縮器１００によって必要とされる制御情報を指定する。例えば、制御情報は、速度を圧縮率よりも優先するかどうか、及び／又は速度を圧縮率よりもどの程度優先するかを示すパラメータを含むことができる。そのパラメータに応じて、ハードウェア・データ圧縮器１００は、同時的なシンボル・リストのソートを採用するか否か；ダイナミック−プライム・ハフマン・コード・テーブルを採用するか否か；一致する文字列を生成するか又はバック・ポインタを生成するかを決定するための事前ハフマン・エンコーディングを採用するか否か；２つのハッシュ・テーブルを採用するか否か；ノードの文字列の一致確率に基づくハッシュ・チェーンのソートを採用するか否かであって、採用する場合、静的優先順位アプローチ又は動的優先順位アプローチを採用するか否か、さらに静的優先順位アプローチを使用する場合は、ルックアップ・テーブルを採用するか否か；入力ブロック・タイプに基づく複数のハッシュ・アルゴリズムからの選択を採用するか否か；及び／又は、ＬＺ７７エンジンからの出力トークンの直接ハフマン・エンコーディングを採用するか否かを判定することができる。或いは、制御情報は、上記の各々について別個のパラメータを含む。他のパラメータには、例えば、ＤＥＦＬＡＴＥ仕様によって規定される固定ハフマン・コード・テーブル、「参照」ハフマン・コード・テーブルを含む事前蓄積済みハフマン・コード・テーブル、ダイナミック−プライム・ハフマン・コード・テーブルを使用するかどうかなどの、使用されるハフマン・コード・テーブルに関する情報を含むことができる。
【０２２２】
本明細書では本発明のさまざまな実施形態が説明されているが、これらの実施形態は例として提示されており、これらに限定されないということが理解されるべきである。関連するコンピュータ分野の当業者にとって、本明細書における形態及び詳細のさまざまな変更が、本発明の範囲を逸脱することなく行われることが可能であるということは明らかである。例えば、ソフトウェアは、本明細書に記載された装置及び方法の機能、製造、モデリング、シミュレーション、記述、及び／又はテストなどを可能にすることができる。これは、一般的なプログラミング言語（例えば、Ｃ、Ｃ＋＋）、Ｖｅｒｉｌｏｇ  ＨＤＬ、ＶＨＤＬなどを含むハードウェア記述言語（ＨＤＬ）、又は他の使用可能なプログラムの使用を通じて実現可能である。そのようなソフトウェアは、磁気テープ、半導体、磁気ディスク若しくは光ディスク（例えば、ＣＤ−ＲＯＭ、ＤＶＤ−ＲＯＭなど）、ネットワーク、有線、無線、又は他の通信媒体などの、コンピュータが使用できる任意の既知の媒体に配置されることが可能である。本明細書に記載された装置及び方法の実施形態は、（例えば、ＨＤＬで具現化又は規定された）プロセッサ・コアなどの半導体ＩＰコア（ｉｎｔｅｌｌｅｃｔｕａｌ  ｐｒｏｐｅｒｔｙ  ｃｏｒｅ）に含まれ、集積回路の製造においてハードウェアに変換されることが可能である。さらに、本明細書に記載された装置及び方法は、ハードウェアとソフトウェアの組み合わせとして具現化されることが可能である。したがって、本発明は、本明細書に記載された実施形態例によって限定されるべきではなく、以下の特許請求の範囲及びその均等物のみに従って定義されるべきである。具体的には、本発明は、汎用コンピュータで使用できるプロセッサ・デバイス内に実装されることが可能である。最後に、当業者は、本発明と同じ目的を実行するために、添付された特許請求の範囲によって定義された本発明の範囲を逸脱することなく、開示された概念及び特定の実施形態を、他の構造を設計又は変更するための基礎として容易に使用できることを理解するであろう。
【符号の説明】
【０２２３】
１００  ハードウェア・データ圧縮器
１０１  入力ブロック・メモリ
１０２  ＬＺ７７エンジン
１０３  ハッシュ・メモリ
１０４  ソート・エンジン
１０５  バック・ポインタ及びフラグ・メモリ
１０６  ハフマン・コード・テーブル構築エンジン
１０７  テーブル・メモリ
１０８  ハフマン・エンコーディング・エンジン
１０９  出力メモリ
２１２  トークン
２１４  レディ
４０１  頻度テーブル
４０２  頻度
４０３  ソート済みリスト
４０４  ソート済みインデックス
４０６  シンボル値
４０７  テール・ポインタ
１１０８  ハフマン・コード
１１１２  ビット長
１２０２  ソート済みリスト変更フラグ
１２０４  ソート済みリスト未変更カウンタ
１８０２  ロジック
１８０４  ソート済みリスト変更カウンタ（ＳＬＣＣ）
１８０６  しきい値
１８０８  シンボル・カウントダウン・カウンタ（ＳＣＤＣ）
２１０２  「参照」ハフマン・コード・テーブル
２４０２  現在の検索ターゲット位置
２４０４  入力ブロック
２４０６  ノード
２４３１  ハッシュ・チェーン
２４３２  ３文字のハッシュ・インデックス・ジェネレータ
２４３４  ３文字のハッシュ・テーブル・インデックス
２４３６  入力ブロックの３文字
２４３８  ３文字のハッシュ・テーブル
２４４１  ハッシュ・チェーン
２４４２  ４文字のハッシュ・インデックス・ジェネレータ
２４４４  ４文字のハッシュ・テーブル・インデックス
２４４６  入力ブロックの４文字
２４４８  ４文字のハッシュ・テーブル
２６０２  スキャン・エンジン
２６０４  チェーン・ソート・エンジン
２６０６  複数の文字から成る入力ブロック
２６１１  ノードのハッシュ・チェーン
２６０６  複数の文字から成る入力ブロック
２７０２  入力ブロック・ポインタ
２７０３  確率
２７０４  世代
２７０５  ネクスト・ポインタ
２７０６  ノード
３３０２  ルックアップ・テーブル
３６００  ハードウェア・データ圧縮器
３６１２  トークン
３９０１  入力ブロック・タイプ
３９０２  現在の検索ターゲット位置
３９０４  入力ブロック
３９０６  ノード
３９３６  最初の文字
３９４１  ハッシュ・チェーン
３９４２  ハッシュ・インデックス・ジェネレータ
３９４２−Ａ、Ｂ、Ｃ  ハッシュ・インデックス・ジェネレータＡ、Ｂ、Ｃ
３９４４  インデックス
３９４８  ハッシュ・テーブル
３９５４  インデックス
３９５４−Ａ、Ｂ、Ｃ  インデックスＡ、Ｂ、Ｃ
３９９９  ＭＵＸ
４２００、４３００  システム
４２０２、４３０２  プロセッサ
４２０４  システム・バス
４２０６  メモリ
４２０８  他のペリフェラル
【図１】
0006363581.tif 000008
【図２Ａ】
0006363581.tif 000009
【図２Ｂ】
0006363581.tif 000010
【図３】
0006363581.tif 000011
【図４】
0006363581.tif 000012
【図５】
0006363581.tif 000013
【図６】
0006363581.tif 000014
【図７】
0006363581.tif 000015
【図８】
0006363581.tif 000016
【図９】
0006363581.tif 000017
【図１０】
0006363581.tif 000018
【図１１Ａ】
0006363581.tif 000019
【図１１Ｂ】
0006363581.tif 000020
【図１２】
0006363581.tif 000021
【図１３】
0006363581.tif 000022
【図１４Ａ】
0006363581.tif 000023
【図１４Ｂ】
0006363581.tif 000024
【図１４Ｃ】
0006363581.tif 000025
【図１５】
0006363581.tif 000026
【図１６】
0006363581.tif 000027
【図１７Ａ】
0006363581.tif 000028
【図１７Ｂ】
0006363581.tif 000029
【図１７Ｃ】
0006363581.tif 000030
【図１８】
0006363581.tif 000031
【図１９】
0006363581.tif 000032
【図２０】
0006363581.tif 000033
【図２１】
0006363581.tif 000034
【図２２】
0006363581.tif 000035
【図２３Ａ】
0006363581.tif 000036
【図２３Ｂ】
0006363581.tif 000037
【図２４】
0006363581.tif 000038
【図２５】
0006363581.tif 000039
【図２６】
0006363581.tif 000040
【図２７】
0006363581.tif 000041
【図２８】
0006363581.tif 000042
【図２９】
0006363581.tif 000043
【図３０】
0006363581.tif 000044
【図３１】
0006363581.tif 000045
【図３２】
0006363581.tif 000046
【図３３】
0006363581.tif 000047
【図３４】
0006363581.tif 000048
【図３５】
0006363581.tif 000049
【図３６】
0006363581.tif 000050
【図３７】
0006363581.tif 000051
【図３８】
0006363581.tif 000052
【図３９】
0006363581.tif 000053
【図４０】
0006363581.tif 000054
【図４１】
0006363581.tif 000055
【図４２】
0006363581.tif 000056
【図４３】
0006363581.tif 000057