gdbm

[戻る]

概要

GNU版のdbmライブラリ。
基本的な使い方はndbmとあまり変わらない。
ndbmではキーとデータの長さがあわせて4,096バイトを超えられなかったが、gdbmは制限なし。
標準の環境では利用できない。インストールが必要。また、リンクするときにはライブラリとして-lgdbmを付ける必要がある。

データベースファイル

データベースファイルはgdbm_openでオープン、gdbm_closeでクローズする。書式は以下の通り。

#include <gdbm.h>

GDBM_FILE gdbm_open(char *name, int block_size, int read_write, int mode, void (*fatal_func)());
void gdbm_close(GDBM_FILE dbf);
nameで、データベースファイル名を指定する。ndbmとは違い、ここで指定されたファイル名のファイル一つだけが作られる。
block_sizeで、ディスクからメモリへ一度に転送されるサイズを指定する。最小サイズは512で、これより小さいサイズが指定された場合、gdbmはそのファイルシステムのブロック長を使用する。block_sizeは新しくファイルを作るとき以外は無視される。
read_writeは、オープンするデータベースファイルに対するプロセスのモードを指定する。指定できるモードは以下の通り。
GDBM_READER
リーダ
GDBM_WRITER
ライタ
GDBM_WRCREAT
ライタ(データベースが存在しなければ生成する)
GDBM_NEWDB
ライタ(無条件に新しいデータベースを生成する)
データベースファイルファイルをオープンするプロセスはリーダまたはライタと呼ばれ、ライタは読み書き可能だが、リーダは読むことだけができる。一つのファイルは一つのライタまたは複数のリーダによってオープンすることができる。
modeはファイルを作るときのパーミッション。sys/stat.hに記述されているS_*を指定する。通常はS_IRUSR | S_IWUSR | S_IRGRP | S_IROTHとしておけばよい。userが読み書き可、groupとotherは読み込みのみ可となる。chmod 644と同じ。
fatal_funcはgdbmが致命的エラーを検出した場合に呼ばれる関数。NULLが指定された場合デフォルトの関数が呼ばれる。

データの登録

データを登録するときはgdbm_storeを使う。書式は以下の通り。

int gdbm_store(GDBM_FILE dbf, datum key, datum content, int flag);
keyにキーを、contentにデータをセットしておく。datumの構造は以下の通り。
typedef struct {
  char  *dptr;
  int   dsize;
} datum;
dptrはキーまたはデータの実体を差すポインタ。dsizeはキーまたはデータの実体のサイズ。dptrはchar*だが、どんな構造でも大丈夫。
flagにはGDBM_INSERTGDBM_REPLACEを指定する。GDBM_INSERTを指定すると、同じキーのデータが登録されている場合、データは登録されずエラーとなる。GDBM_REPLACEを指定すると、同じキーのデータが登録されている場合、データは置き換えられる。同じキーのデータが登録されていない場合は、どちらを指定してもデータは登録される。
戻り値が負の場合、登録失敗。

データの検索(取り出し)

データをキーで検索して取り出すときはgdbm_fetchを使う。書式は以下の通り。

datum gdbm_fetch(GDBM_FILE dbf, datum key);
戻り値はデータ。戻り値のdptrがNULLの場合、検索失敗。
戻り値のdptrはmallocで確保された領域だが、gdbmは自動的にfreeしてくれないので、ちゃんとfreeするようにプログラミングすること。

データの検索

データをキーで検索するきはgdbm_existsを使う。書式は以下の通り。

int gdbm_exists(GDBM_FILE dbf, datum key);
戻り値がtrueなら検索成功、falseなら検索失敗。
gdbm_fetchと違い、メモリの確保は行われないので、レコードの存在のチェックだけしたいときはこちらのほうが便利。

データの削除

指定したキーのデータを削除するときはgdbm_deleteを使う。書式は以下の通り。

int gdbm_delete(GDBM_FILE dbf, datum key);
戻り値が負の場合、削除失敗。

データベースに登録されているデータを全部見るには

データベースに登録されているデータを全部見たい場合、gdbm_firstkeygdbm_nextkeyを使う。書式は以下の通り。

datum gdbm_firstkey(GDBM_FILE dbf);
datum gdbm_nextkey(GDBM_FILE dbf, datum key);
戻り値はキー。実際に使うときは以下のようにする。
for(key = gdbm_firstkey(dbf); key.dptr != NULL; key = gdbm_nextkey(dbf, key)){
  content = gdbm_fetch(dbf, key);
  free(content.dptr);
}
gdbm_firstkeyもgdbm_nextkeyもキーを返すだけなので、データはgdbm_fetchで取り出さなければならない。
keyのdptrもgdbmは自動的にfreeしてくれないので、ちゃんとfreeすること。

データベースの再構成

gdbm_deleteでデータの削除を行っても、データベースファイルは小さくならない。ファイルサイズを小さくしたい場合はgdbm_reorganizeを再構成する。書式は以下の通り。

int gdbm_reorganize(GDBM_FILE dbf);

データベースのディスクへの書き込み

データベースファイルをオープンするときにread_writeにGDBM_FASTをorで付加すると、データを書き込むときにディスク上のファイルとメモリとの同期をとらない。これにより、書き込みは早くなるが、データの不整合が起こる可能性がある。そこで、gdbm_syncを使って、ファイルとメモリの同期をとらせることができる。書式は以下の通り。

void gdbm_sync(GDBM_FILE dbf);

エラー

データベースのエラーはgdbm_errnoというgdbm_error型のグローバル変数に格納されている。このエラーコードはgdbm_strerrorで英語のテキストに変換する事ができる。書式は以下の通り。

char *gdbm_strerror(gdbm_error errno);

その他

gdbm_setoptでデータベースに対する特定のオプションを設定することができる。書式は以下の通り。

int gdbm_setopt(GDBM_FILE dbf, int option, int *value, int size);

char*型のグローバル変数gdbm_versionにバージョン情報が文字列で格納されている。たとえばこんな感じ。

This is GDBM version 1.7.3, as of May 19, 1994.

実際に使って気付いたこと


Copyright © 1999 by Jun Takahashi