Linux Mintでgdbm

Linux Mintでgdbmを使ってみた。
gdbmはまぁ機能の無いISAMみたいなもんで、もしかしていつかどこかで使うこともあるのかもしれない、ということで。

でまず、
man dbm_open
とかやってみたら無い。
なので、
sudo apt-get install libgdbm-dev
とインストール。
manの中身をつらつら見てみると、なんかRetHat系のと違う。
とりあえずmanの説明通りにそれっぽく。
目的はdbm_open等のDBM系関数を使うことなので、manの仰せのとおり
#include <ndbm.h>
とするが見つからず。
ndbmを使うには、gdbm-ndbm.hを使う必要があるようだ。
そいでmanの仰せの通り、
-lgdbm -lgdbm-compat
をコンパイルオプションに付けてコンパイル。


起動時引数で、c:Create and Store、r:キー指定でFetch、f:順に取得、2:キー(int)をshortで取得してみた。
2:ではついでにdbm_errorも呼んでみた。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <gdbm-ndbm.h>

#define DbName "testdb"
void Create();
void Read();
void Fetch();
void Fetch2();

int main(int argc, char **argv)
{
if (argc < 2) { exit(EXIT_FAILURE); }
switch (argv[1][0]) {
case 'C':
case 'c':
Create();
break;
case 'R':
case 'r':
Read();
break;
case 'F':
case 'f':
Fetch();
break;
case '2':
Fetch2();
break;
default:
return 0;
}

return 0;
}

void Create()
{
DBM *dbf = dbm_open(DbName
, O_RDWR | O_CREAT
, S_IRUSR | S_IWUSR
);
if (dbf == NULL) { fprintf(stderr, "dbm_open error\n"); return; }
int i;
for (i = 0; i < 100; i++) {
datum key = {.dsize = sizeof(int), .dptr = (void *)&i };
int n = i * 3;
datum content = {.dsize = sizeof(int), .dptr = (void *)&n };
if (dbm_store(dbf, key, content, DBM_REPLACE) != 0) {
fprintf(stderr, "dbm_store error\n");
dbm_close(dbf);
return;
}
}
dbm_close(dbf);
}

void Read()
{
DBM *dbf = dbm_open(DbName, O_RDONLY, S_IRUSR);
if (dbf == NULL) { fprintf(stderr, "dbm_open error\n"); return; }
datum key = dbm_firstkey(dbf);
while (key.dptr != NULL) {
datum content = dbm_fetch(dbf, key);
if (content.dptr != NULL) {
printf("key=%d content=%d\n"
, *(int *)key.dptr
, *(int *)content.dptr);
}
key = dbm_nextkey(dbf, key);
}
dbm_close(dbf);
}

void Fetch()
{
DBM *dbf = dbm_open(DbName, O_RDONLY, S_IRUSR);
if (dbf == NULL) { fprintf(stderr, "dbm_open error\n"); return; }
int i;
for (i = 0; i < 100; i++) {
datum key = {.dsize = sizeof(int), .dptr = (void *)&i };
datum content = dbm_fetch(dbf, key);
if (content.dptr == NULL) {
fprintf(stderr, "dbm_fetch error\n");
dbm_close(dbf);
return;
}
printf("key=%d content=%d\n"
, *(int *)key.dptr
, *(int *)content.dptr);
}
dbm_close(dbf);
}

void Fetch2()
{
DBM *dbf = dbm_open(DbName, O_RDONLY, S_IRUSR);
if (dbf == NULL) { fprintf(stderr, "dbm_open error\n"); return; }
int i;
for (i = 0; i < 100; i++) {
short n = (short)i;
datum key = {.dsize = sizeof(short), .dptr = (void *)&n };
datum content = dbm_fetch(dbf, key);
if (content.dptr == NULL) {
fprintf(stderr, "dbm_fetch error[%d]\n", dbm_error(dbf));
dbm_close(dbf);
return;
}
printf("key=%d content=%d\n"
, *(short *)key.dptr
, *(int *)content.dptr);
}
dbm_close(dbf);
}


Create、Store、Fetch、順読みはいずれも成功。期待通り。
そしてkeyをshortで読みにいくのは当然不一致エラー。
dbm_errorもヘッダで(0)にdefineしてるだけなので当然0。
まぁいろいろと残念ながら期待通り。

mapのシリアライズには使えるかなぁ?、とまぁそんな感じ。
素直にgdbm_系関数使った方が汎用的かなとかは考えないでおく。
スポンサーサイト

コメントの投稿

非公開コメント

プロフィール

f_yamaki

Author:f_yamaki

アクセスカウンタ
最近の記事
最近のコメント
最近のトラックバック
月別アーカイブ
カテゴリー
ブロとも申請フォーム

この人とブロともになる

ブログ内検索
RSSフィード
リンク