Gitの一部のファイル形式では、「チャンク」(chunks)という共通の概念を使用してファイルのセクションを記述します。
これは、残りのデータに対して小さな「目次」(table of
contents)をスキャンすることで、大きなファイルへの構造化されたアクセスを可能にします。 この共通形式は、commit-graph
ファイルと
multi-pack-index
ファイルで使用されます。 チャンクを使用して構造化データを記述する方法については、
the multi-pack-index
format と
the commit-graph
format
を参照してください。
チャンクベースファイル形式(chunk-based file format)は、その形式に合わせたヘッダー情報から始まります。 そのヘッダーには、ファイルタイプ、形式バージョン、ファイル内のチャンクの数、を識別するのに十分な情報が含まれている必要があります。 この情報から、そのファイルはチャンクベース領域(chunk-based region)の開始を決定する事ができます。
チャンクベース領域(chunk-based region)は、各チャンクの開始と終了を説明する目次(table of contents)で始まります。 これは、各行(row)12バイトの (C+1)行(row)で構成されます。ここで、Cはチャンクの数です。 以下の表をじっくり見やがれしてください。
| Chunk ID (4 bytes) | Chunk Offset (8 bytes) |
|--------------------|------------------------|
| ID[0] | OFFSET[0] |
| ... | ... |
| ID[C] | OFFSET[C] |
| 0x0000 | OFFSET[C+1] |
各行(row)は、4バイトのチャンク識別子(ID)と8バイトのオフセットで構成されます。各整数はネットワークバイトオーダーで格納されます。
チャンク識別子 ID[i]
は、 OFFSET[i]
(含む) から OFFSET[i+1]
(含まない) (訳注: OFFSET[i]
⇐ ID[i]のデータ < OFFSET[i+1]) までの、このフィル内に格納されたデータのラベルです。したがって、 i
番目のチャンクのサイズは、OFFSET[i+1]
と OFFSET[i]
の差に等しくなります(訳注: つまり、サイズ =
OFFSET[i+1] - OFFSET[i])。 このためには、チャンクデータが目次と同じ順序で連続して表れる必要があります。
目次の最後のエントリは、4つのゼロバイトである必要があります。 これにより、目次が終了していることが確認され、チャンクベースのデータの終了のオフセットが提供されます。
注意: チャンクベース形式では、ファイルの OFFSET[C+1]
の後に、「少なくとも」末尾のハッシュ(trailing
hash)が含まれている必要があります。
チャンクベースのファイル形式を操作するための関数は、 chunk-format.h
で宣言されています。
これらのメソッドを使用すると、開発者が新しいファイル形式を作成するときに役立つ追加のチェックが提供されます。
Writing chunk-based file formats
チャンクベースファイル形式を作成するには、 init_chunkfile()_ を呼び出して `struct chunkfile
を作成し、
struct hashfile
ポインタを渡します。 呼び出し元は、 hashfile
を開き、ヘッダー情報を書き込む責任があります。これにより、チャンクベース形式が始まる前にファイル形式を識別できます。
次に、書き込み用のチャンクごとに add_chunk()
を呼び出します。 これにより、chunkfile
に書き込む各チャンクの順序とサイズに関する情報が入力されます。 要求に応じてチャンクデータの書き込みを実行するための chunk_write_fn
関数ポインタを提供します。
write_chunkfile()
を呼び出して、目次(table of contents)を hashfile
に書き込み、その後に各チャンクを書き込みます。 これにより、各チャンクが予想される量のデータを書き込んだことを確認し、目次が正しいことを確認します。
最後に、 free_chunkfile()
を呼び出して、 structc hunkfile
データをクリアします。
呼び出し元は、末尾のハッシュ(trailing hash)を書き込んでファイルを閉じることにより、 hashfile
を完成させる責任があります。
Reading chunk-based file formats
チャンクベースファイル形式を読み取るには、ファイルをメモリマップ領域(memory-mapped region)として開く必要があります。 チャンク形式のAPIは、ファイル全体が連続したメモリ領域としてマップされることを想定しています。
init_chunkfile(NULL)
で struct chunkfile
ポインタを初期化します。
ファイルの先頭からチャンクカウント(chunk count)を含むヘッダー情報を読み取った後、 read_table_of_contents()
を呼び出して、 structc hunkfile
にチャンクのリスト、それらのオフセット、およびそれらのサイズを入力します。
pair_chunk()
または read_chunk()
を使用して、各チャンクのデータ情報を抽出します:
-
pair_chunk()
は、そのチャンクのオフセットに対応するメモリマップされたファイル(memory-mapped file)内の場所に特定のポインタを割り当てます。 チャンクが存在しない場合、ポインターは変更されません。 -
read_chunk()
は、chunk_read_fn
関数ポインタを受け取り、適切な初期ポインタとサイズ情報を使用して呼び出します。 チャンクが存在しない場合、関数は呼び出されません。 即時パース(immediate parsing)を実行する必要がある場合、またはチャンクのサイズに基づいてロジックを実行する必要がある場合は、このメソッドを使用してチャンクを読み取ります。
これらのメソッドを呼び出した後、 free_chunkfile()
を呼び出して structc hunkfile
データをクリアします。
これにより、メモリマップ領域は閉じられません。 呼び出し元は、領域へのポインタが必要とされている間はデータを所有しつづけることが期待されます。
Examples
これらのファイル形式はチャンク形式のAPIを使用しており、将来の形式の例として使用できます:
- commit-graph
-
the commit-graph file format に記載されているcommit-graphファイル形式の書き込みとパースにチャンク形式APIを使用する方法については、
commit-graph.c
のwrite_commit_graph_file()
と `parse_commit_graph()`を参照してください。 - multi-pack-index
-
the multi-pack-index file format に記載されているマルチパックインデックスファイル形式の書き込みとパースにチャンク形式APIを使用する方法については、
midx.c
のwrite_midx_internal()
と `load_multi_pack_index()`を参照してください。