diff options
| author | fukachan <fukachan> | 2003-05-26 08:56:51 +0000 |
|---|---|---|
| committer | fukachan <fukachan> | 2003-05-26 08:56:51 +0000 |
| commit | 00641610acad3d3e3f121faa37b2ce0cbbaa171e (patch) | |
| tree | 4a591bab7e1fc3a19b2858d5a1973de6d78c5c36 /fml/doc | |
| parent | fdec58e32c02968fea088ac8a5ce0b96b3a34f5c (diff) | |
| download | fml8-00641610acad3d3e3f121faa37b2ce0cbbaa171e.tar.gz fml8-00641610acad3d3e3f121faa37b2ce0cbbaa171e.tar.bz2 fml8-00641610acad3d3e3f121faa37b2ce0cbbaa171e.zip | |
consideration on IO abstraction layer
Diffstat (limited to 'fml/doc')
| -rw-r--r-- | fml/doc/ja/tutorial/book.sgml | 3 | ||||
| -rw-r--r-- | fml/doc/ja/tutorial/include/chapters.ent | 3 | ||||
| -rw-r--r-- | fml/doc/ja/tutorial/internals/io_abstraction.sgml | 291 |
3 files changed, 295 insertions, 2 deletions
diff --git a/fml/doc/ja/tutorial/book.sgml b/fml/doc/ja/tutorial/book.sgml index 04740281..72b29245 100644 --- a/fml/doc/ja/tutorial/book.sgml +++ b/fml/doc/ja/tutorial/book.sgml @@ -2,7 +2,7 @@ This is an sgml using DocBook dtd. Use sgmltools version 2.0.x or above to generate various output formats. -$FML: book.sgml,v 1.55 2003/04/13 03:29:01 fukachan Exp $ +$FML: book.sgml,v 1.56 2003/05/12 10:16:38 fukachan Exp $ --> <!doctype book public "-//FML//DTD DocBook V3.1-Based Extension//EN" [ @@ -164,6 +164,7 @@ $FML: book.sgml,v 1.55 2003/04/13 03:29:01 fukachan Exp $ &chapter.virtual; <!-- その他 --> + &chapter.io.abstraction; &chapter.lock; &chapter.db; &chapter.db.thread; diff --git a/fml/doc/ja/tutorial/include/chapters.ent b/fml/doc/ja/tutorial/include/chapters.ent index 9800936a..4bfb331d 100644 --- a/fml/doc/ja/tutorial/include/chapters.ent +++ b/fml/doc/ja/tutorial/include/chapters.ent @@ -1,5 +1,5 @@ <!-- - $FML: chapters.ent,v 1.70 2003/04/13 04:36:11 fukachan Exp $ + $FML: chapters.ent,v 1.71 2003/05/12 10:16:39 fukachan Exp $ --> <!entity versin "1.1"> @@ -138,6 +138,7 @@ <!entity chapter.restriction SYSTEM "internals/restriction.sgml"> <!entity chapter.credential SYSTEM "internals/credential.sgml"> <!entity chapter.lock SYSTEM "internals/lock.sgml"> +<!entity chapter.io.abstraction SYSTEM "internals/io_abstraction.sgml"> <!entity chapter.virtual SYSTEM "virtual/chapter.sgml"> diff --git a/fml/doc/ja/tutorial/internals/io_abstraction.sgml b/fml/doc/ja/tutorial/internals/io_abstraction.sgml new file mode 100644 index 00000000..cba15a45 --- /dev/null +++ b/fml/doc/ja/tutorial/internals/io_abstraction.sgml @@ -0,0 +1,291 @@ +<!-- + $FML$ +--> + + +<chapter id="io.abstraction"> + <title> + IO インターフェイスとオペレーション + </title> + +<para> +移植性や拡張性のためには UNIX における Vnode/VFS interface (vnode(9)参 +照)のような構造をあらゆるレイヤーに導入する必要があります。 +<screen> +struct vnode { + ... + voff_t v_size; /* size of file */ + int v_numoutput; /* num pending writes */ + long v_writecount; /* ref count of writers */ + ... + int (**v_op)(void *); /* vnode ops vector */ + ... + void *v_data; /* private data for fs */ +}; +</screen> +v_op の先に、 +vop_open() +vop_read() +vop_getattr() +などが定義されています。 +</para> + +<para> +つまり struct vnode の **v_op (vnode operation vector) にあたるものが +IO に使われるクラスの各メソッドです。たとえば、IO::Adapter はユーザリ +ストというオブジェクトに対する IO インターフェイスを抽象化したものです。 +</para> + + +<sect1 id="io.abstraction.overview"> + <title> + 基本形としての IO::Adapter + </title> + +<para> +&fmldevel; 全体の基調となる型は +<link linkend="module.io.adapter"> +IO::Adapter +</link> +といえるでしょう。実装もすでに完成形であり、primitive なメソッドは何か +などについて十分考えられています。 +</para> + +<para> +<link linkend="module.io.adapter"> +IO::Adapter +</link> +クラスは +<screen> +KEY => VALUE +</screen> +もしくは +<screen> +KEY => [ VALUE, VALUE2, VALUE3 ] +</screen> +のいづれかの型のデータ構造を抽象化していると考えられます。 +つまり、これは RDBMS の基礎理論同様の表型のデータ構造です。 +</para> +<screen> +KEY1 VALUE1-1 "" "" +KEY2 VALUE2-1 VALUE2-2 VALUE2-3 +KEY3 VALUE3-1 VALUE3-2 VALUE3-3 +KEY4 VALUE4-1 VALUE4-2 VALUE4-3 +</screen> + +<para> +ユーザリストを管理する上で必要最低限の基本メソッド群は、 +IO::Adapter の裏にあるオブジェクト本体を呼びだすための +<screen> +open() +close() +</screen> +および、そのオブジェクトへの IO である +<screen> +add(KEY, ARGV) (ARGV はクラス依存のデータ渡しのためにある引数) +delete(KEY) +find(KEY or REGEXP) +get_next_key() +</screen> +があれば十分のようです。 +少なくとも、ユーザ管理はこれらだけで十分書けます。 +</para> + +</sect1> + + +<sect1 id="io.abstraction.ops"> + <title> + メソッド / operation vector + </title> + +<para> +前述のように IO::Adapter の基本メソッドは次の通りです。 +<screen> +open() +close() +add(KEY, ARGV) (ARGV はクラス依存のデータ渡しのためにある引数) +delete(KEY) +find(KEY or REGEXP) +get_next_key() +</screen> +</para> + +<para> +もちろん、オブジェクトを生成するのは new() ですので、 +これら以外に new() だけは必要です:) +必要なら適宜、ディストラクタも定義して下さい。 +</para> + +<para> +オブジェクトを生成するのは new() です。 +たとえば IO::Adapter であれば、 +<screen> +$obj = new IO::Adapter マップ; +</screen> +などとオブジェクトタイプを引数(マップ)で指定するため、 +それに応じた初期化を行ないます。 +</para> + + +<sect2> + <title> + open() + </title> + +<para> +ファイルであれば open(2)、RDBMS であれば SQL サーバへの接続を確立する +といった具合です。 +</para> + +</sect2> + + +<sect2> + <title> + close() + </title> + +<para> +すなおに open() の逆です。 +</para> + +</sect2> + + +<sect2> + <title> + add(KEY, ARGV) + </title> + +<para> +KEY (プライマリキー)もしくは、KEY および KEY に付随するデータをオブジェ +クトに書き込みます。なお、ARGV はクラス依存のデータ渡しのためにある引 +数で、この引数が使われないこともあります。 +</para> + +<para> +UNIX と異なり、オブジェクトの構造に一定の型があります。型とは RDBMS の +ようなテーブルの形です。 +</para> + +<para> +また、プライマリキーとなるのは通常メールアドレスです。この前提が多くの +場面で正しいため、メールアドレスをプライマリアドレスにしたテーブル型が +基本的なデータ構造といえるわけです。 +</para> + +</sect2> + + +<sect2> + <title> + delete(KEY) + </title> + +<para> +KEY および KEY に付随するデータ構造を削除します。 +</para> + +</sect2> + + +<sect2> + <title> + find(KEY) / find(REGEXP) + </title> + +<para> +オブジェクト内からプライマリキーに該当するデータを探します。 +</para> + +<para> +探す対象を正規表現で指定できるように作る方が便利です。 +正規表現検索が使えると、ユーザ検索などで重宝します。 +</para> + +<para> +返り値は STR か ARRAY_REF (KEY に対する [ VALUE, VALUE2, VALUE3 ])です。 +</para> + +</sect2> + + +<sect2> + <title> + get_next_key() + </title> + +<para> +プライマリキーの一覧を取り出したい場合が多々あります。 +そこで +<screen> +while ($obj->get_next_key()) { ... } +</screen> +のような表現を可能とするために、このメソッドが実装されています。 +</para> + +<para> +これはハッシュの FIRST_KEY() と NEXT_KEY() にあたるといえます。でも、 +我々の場合は open() などのメソッドが別途用意されているため、 +FIRST_KEY() と NEXT_KEY() のように2つに分ける必要はありません。 +</para> + +<para> +XXX すなおに、key() もしくは get_key() でも良い気がする? +</para> + +</sect2> + +</sect1> + + +<sect1 id="io.abstraction.discussion"> + <title> + 議論 + </title> + + +<sect2> + <title> + プライマリキーを全部取り出したい場合は? + </title> + +<para> +定石は全部読んでみること、つまり get_next_key() を呼びまくるコードです。 +専用のメソッドがあった方が便利でしょうけど、 +滅多にそんなコードは必要ないようなので、 +専用メソッドがなくても問題はがないようです。 +</para> + +<para> +もし、あるとしたら get_primary_keys() みたいなメソッド?で、 +ARRAY_REF で返すのでしょうかね? +</para> + +</sect2> + + +<sect2> + <title> + 返り値が HASH_REF の場合? + </title> + +<para> +返り値が HASH_REF であるようなメソッドが欲しいだろうか? +<screen> +返り値 = { + 変数1 => 値1、 + 変数2 => 値2、 +} +</screen> +って、getattr() とかいうメソッドかなぁ。だが、HASH_REF 中の +属性のキーがオブジェクトに強く依存するなぁ…う〜む。 +</para> + +</sect2> + +</sect1> + + +</chapter> |
