区分データセットのディレクトリー構造

区分データセットのしくみについては、以前に「z/OS(MVS)、MSP、VOS3のしくみ\基礎編\07.データセットの種類とアクセス方式」の「ディレクトリー部の構造」でも解説しましたが、各ディレクトリー・ブロック内のデータ構造についてもう少し詳細を補足します。z/OSでは、拡張区分データセット(PDSE)も使用できますが、ここで解説するディレクトリー・ブロック構造は、従来からある区分データセットについてのものです。

PDSディレクトリー部の構造

ディレクトリー・ブロックの構造

ディレクトリー・ブロックは、256バイトの長さを持ちます。ディレクトリー内では、256バイトのディレクトリー・ブロックが、区分データセット作成時に指定されたディレクトリー・ブロックの数だけ順番に並んでいます。区分データセットのディレクトリー部だけを抜き出せば、256バイトの固定長非ブロック化レコードの順次データセットと同様の構造になっています。

実際のディスク・トラック上では、256バイトのレコード・データの前に8バイトのキーが付加されています。このキー部には、そのディレクトリー・ブロックに格納されている最後のメンバー名が格納されています。どのディレクトリー・ブロックに目的メンバーのインデックス・データが書かれているかを探索する際のキーとして利用されます。

ディレクトリー・ブロック内のディレクトリー構成

    メンバーの探索

    メンバー名をキーにしてディレクトリー・ブロックを探索すれば、目的のメンバーがどのディレクトリー・ブロックに入っているかがわかります。メンバー名と各ディレクトリー・ブロックに付加されたキーの値を比較して、等しいかメンバー名が小さければ、目的のメンバーはそのディレクトリー・ブロックに入っている可能性があります。探索すべきディレクトリー・ブロックを見つけたら、そのディレクトリー・ブロックのデータ256バイトを読み込み、先頭の2バイトが示す有効データ長だけディレクトリー・ブロック内で探します。

    データ長フィールドをスキップした位置が、そのディレクトリー・ブロックの最初のメンバー名です。目的のメンバーでなければ、メンバー名+11バイトの位置にあるインジケーター・バイトを読み出してx1Fで論理積を取ります。x1FでANDした答えがそのメンバーのユーザー・データ部の長さです。したがって、メンバー名の8バイト+TTRの3バイト+インジケーター・バイトの1バイト+ユーザー・データ部の長さを加算したバイト数だけ離れた位置が、次のメンバー・ディレクトリー・データの先頭です。そこに次のメンバーのメンバー名があります。このように繰り返してディレクトリー・ブロック内に目的のメンバーがあるかどうか調べて行きます。有効データ長分探しても見つからなければ、目的のメンバーはその区分データセットにはありません。

    区分データセットのディレクトリー部は、必ずメンバー名の昇順にディレクトリー・データが並ぶという決まりがあります。したがって、この仕組みを知っていればメンバーを探すためにすべてのメンバー・ディレクトリー・ブロックを読み込んで探すような必要はなく、キーによって格納されている可能性があるディレクトリー・ブロックを求めてそのブロック内でだけ探せば済むようになっています。実際には、ほとんどのプログラムは自分で直接ディレクトリー・ブロック内を探すようなことはせず、BPAMのBLDLあるいはFINDマクロによって検索または位置付けを行います。しかし、内部ではこのような仕組みになっていることは知っておいて損はありません。

    区分データセットのディレクトリーブロック数はどのくらいにすればいいか?

    PDSEデータセットでは、ディレクトリー・ブロック数を考える必要はないですが、従来のPDS(区分)データセットを作る場合は、ディレクトリー・ブロック数を指定しなければなりません。ディレクトリー・ブロック内のデータ構造とユーザー・データ部の長さがわかれば、1つのディレクトリー・ブロックにいくつのメンバーが格納できるかが計算できます。

    1つのメンバーは、メンバー名の8バイト、TTR(メンバーのレコード・データが区分データセット内のどの位置にあるかを示す)の3バイト、インジケーター・バイトの1バイトの計12バイトを最小でも使用します。これにユーザー・データ部が加わります。ディレクトリー・ブロック内で、メンバー・ディレクトリー・データ用に使用できる最大長は、256バイトから先頭にある有効データ長フィールドの長さ2バイトを引いた254バイトです。したがって、254÷1メンバーあたりのディレクトリー・データ長が、1つのディレクトリー・ブロックに格納できるメンバー数です。ただし、最後のディレクトリー・ブロックには最終エントリーを示すデータ12バイトが予約されるので、1メンバー分少なくなる場合があります。

    代表的なユーザー・データ部の長さ
    ソフトウェア ユーザー・データの長さ メンバー・ディレクトリー・データの合計長
    ISPFエディター 30byte 42byte
    PFDエディター 28byte 40byte
    ASPENエディター 30byte 42byte
    バインダー(z/OS)
    リンケージ・エディター(MSP)
    24byte 36byte
    バインダー(z/OS)別名メンバー 34byte 46byte
    リンケージ・エディター(VOS3) 28byte 40byte

    区分データセットにメンバーを格納する代表的なソフトウェアは、ソース・プログラムやJCLならISPFエディター、ロード・モジュールならバインダー(リンケージエディター)です。上記のテーブルには、主なソフトウェアがメンバー保管時に付加するメンバー・ディレクトリーのユーザー・データの長さを示しました。

    このテーブルからメンバーが使用するディレクトリー・データの長さを求め、その値で254を割れば1DIRブロックあたりのメンバー数を求められます。区分データセットに格納する予定(あるいは格納したい)のメンバー数を、1DIRブロックあたりのメンバー数で割れば、必要なディレクトリー・ブロック数の概算の数を求めることができます。

    z/OSでは、ソース・プログラムやJCLの格納データセット(ISPFエディター使用)なら1DIRブロックあたり6メンバー、ロード・モジュールの格納データセットなら1DIRブロックあたり7メンバー(別名なしの場合)です。ディレクトリー・ブロック数を10個にした場合、ソース・プログラムやJCLライブラリーなら60メンバー、ロード・モジュール・ライブラリーなら70メンバー程度が格納できることになります。

    業務用プログラムのロード・モジュールを格納する場合は、別名を付けたりすることもあるので少し多めにしておく方がいいでしょう。データセット自体のスペースなら不足しても2次数量で拡張することができますが、ディレクトリーは後で拡張することはできません。