C 言語のハッシュテーブル!

※ 2014-05-09 書き直しました

GLib のハッシュテーブルを使う は人気の記事のようなので、もう1つ C 言語のハッシュテーブルをご紹介します!

今回は Apache Portable Runtime のハッシュテーブルを使ってみました。Apache といえば人気の Web サーバーソフトウェアです。Apache は移植性を高めるために、独自のランタイムライブラリである APR の上に構築されています。APR の目玉はメモリ管理機能でしょうか。malloc とか free とかをこまめに呼び出すのではなく、まずメモリプールという 8 KB 程度の領域をあらかじめ確保し、malloc の代わりに apr_palloc でメモリプールから必要な大きさのメモリをもらいます。メモリを解放する時は、メモリプールごとドバッといきます。Apache はコネクション単位やセッション単位で色んなデータを作ったり消したり整理しないといけないので、こういう仕組みが適してる、ということなんでしょう。

APR にはメモリプール版の strdup である apr_pstrdup といった基本的な関数の他に、動的な配列や、ハッシュテーブルといったコンテナも用意しています。

ということで、GLib のハッシュテーブルを使う と同じ例を APR で書いてみました。

/*
 * Apache Portable Runtime のハッシュテーブルの使用例
 *   APR 1.4.5 で動作確認しました。
 *
 *   コンパイルの仕方:
 *     gcc `pkg-config --cflags --libs apr-1` <this_file>
 *
 *   リファレンスマニュアル:
 *     http://apr.apache.org/docs/apr/1.4/modules.html
 *
 *   参考にしたサイト:
 *     ありえるえりあ http://dev.ariel-networks.com/apr/apr-tutorial/html/apr-tutorial-19.html#ss19.3
 *
 * Linux 修験道 https://linuxshugendo.wordpress.com
 *                                             2014-02-28
 */
#include <stdio.h>
#include <assert.h>

#include <apr_pools.h>
#include <apr_strings.h>
#include <apr_hash.h>

int print_hash(void *rec, const void *key, apr_ssize_t klen, const void *value);

int main(int argc, char *argv[])
{
  apr_status_t rv;
  apr_pool_t *mp;
  apr_hash_t *ht;
  char *key;
  int *val;

  /* APR の初期化 */
  rv = apr_initialize();
  if (rv != APR_SUCCESS) {
    assert(0);
    return -1;
  }

  /* メモリプールの作成 */
  apr_pool_create(&mp, NULL);
  /* メモリプール上にハッシュテーブルを作成する */
  ht = apr_hash_make(mp);

  /* キー(文字列)のメモリ割当と文字列のコピー */
  key = apr_pstrdup(mp, "りんご");
  /* 値(int)のメモリ割当 */
  val = apr_palloc(mp, sizeof(int));
  *val = 100;
  /* key と val を ht に登録する */
  apr_hash_set(ht, key, APR_HASH_KEY_STRING, val);

  key = apr_pstrdup(mp, "いちご");
  val = apr_palloc(mp, sizeof(int));
  *val = 300;
  apr_hash_set(ht, key, APR_HASH_KEY_STRING, val);

  printf("要素削除前\n");
  /* いわゆる for each */
  apr_hash_do(print_hash, NULL, ht);

  /* 要素を削除するには、値に NULL をセットする */
  apr_hash_set(ht, "いちご", APR_HASH_KEY_STRING, NULL);
  printf("\n要素削除後\n");
  apr_hash_do(print_hash, NULL, ht);

  /* メモリプール領域を解放する。全てのキー、バリュー、テーブルが破壊される */
  apr_pool_destroy(mp);
  return 0;
}

int print_hash(void *rec, const void *key, apr_ssize_t klen, const void *value)
{
  printf("%s: %d 円\n", (char*)key, *(int*)value);
  return 1; /* Iteration continues while this callback function returns non-zero. */
}

以下実行例です:

me@kozu-mba-> gcc -Wall -pedantic hash_table.c `pkg-config --cflags --libs apr-1`
me@kozu-mba-> ./a.out 
要素削除前
いちご: 300 円
りんご: 100 円

要素削除後
りんご: 100 円

便利ですね!

(コウヅ)

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中