ETS テーブルの存在有無を調べる
Erlang の処理系である ERTS には手軽に利用可能なデータストアが複数用意されていて,ETS/DETS テーブルがその内の一つに当たるわけですが,プロセスとは異なり whereis/1 関数で存在の有無を確認することはできないわけです.というのは,例えば
-module(test). -export([test/0]). test() -> ets:new(test, [set, public, named_table]), ets:insert(test, {hoge, foo}), case get_test(test, hoge) of [{hoge, Value}] -> io:format("~p~n", [Value]); [] -> io:format("Pair Not Found~n"); {error, undefined} -> io:format("Table Not Found~n") end.
というようなコードがあったとして,
get_test(TableName, Key) -> case whereis(TableName) of undefined -> {error, undefined}; Tid -> ets:lookup(Tid, Key) end.
上記の関数で何とかしようとしても,whereis/1 関数は常に undefined を返してしまいます.ではどうすれば良いのかと言うと,以下の通り,
get_test(TableName, Key) -> case catch ets:lookup(TableName, Key) of {'EXIT', {badarg, _}} -> {error, undefined}; Any -> Any end.
直接エラーを catch して,badarg エラーの場合にテーブルが定義されていないと解釈すれば正常に動作させることができます.多少汚い感じもしますが ets:lookup/2 関数が badarg エラーを返すのはたぶんテーブルの未定義時のみだと思うので問題無いです.まあ気になって仕方がない方は,適当なガード文で引数の間違い等を弾けば良いのではないでしょうか.
大量プロセスが動作する際のプロファイリング
関数の呼び出し回数を調べたいのだけど,eprof や fprof だとプロセス毎の呼び出し回数しか得ることができない….というような場合に使えるのが cprof.いくら大量のプロセスを生成してもモジュール毎の呼び出し回数だけを表示してくれるのでとても都合が良い.
http://ftp.sunet.se/pub/lang/erlang/doc/man/cprof.html
prof() -> cprof:start(), %% %% 適当な処理を実行 %% cprof:pause(), io:format("~p~n", [cprof:analyse()]), cprof:stop().
whereis/1 関数を使用する上での注意
ちょっと考えてみると当たり前のことなんだけど,whereis/1 関数は呼び出される頻度が多い割に若干遅い感じがするので,無闇に呼び出さないほうが良い.もしくは何らかの形でキャッシュしておくとか.
自分のプログラムではかなり多用していて,これを削るだけで 1.5 倍くらい高速化された.
2009年度下期未踏ユースに採択されました
http://www.ipa.go.jp/jinzai/mitou/2009/2009_2/youth/gaiyou/kk-1.html
採択通知は一ヶ月以上も前に届いていたのだけど,外部に知らせるのは禁止されていました.開発は github に用意したレポジトリで行っているので,誰でも自由に見ることが可能です.ただ,プロジェクトの名称 (= レポジトリ名) は今のところ暫定的なものなので URL の掲載は避けておきます.
http://github.com/daiki41ti/kyeeva
追記: URL を採択案件概要のページに変更.また,github の開発リポジトリへのリンクも張った.
メッセージフロー
BitTorrent クライアントの実装メモ.頭が混乱してきたのでまとめてみた.なお,ダウンロード側はコネクション開始直後は choked 状態.
Tracker Client Peers Tracker <- GET request Client Peers Tracker peers list -> Client Peers Tracker Client Handshake -> Peers Tracker Client <- <bitfield> message Peers Tracker Client <request> message -> Peers Tracker Client <interested> message -> Peers Tracker Client <- <unchoke> message Peers Tracker Client <- <piece> message Peers downloaded Tracker Client <not interested> message -> Peers Tracker Client <- <choke> message Peers Tracker Client <have> message -> Peers
実際には choke/unchoke/interested/not interested メッセージは非同期的に送信されるので,ここでのタイミングは適当.
追記: メッセージフローを図に表したWebサイトを発見した.
http://alexmohr.com/bittorrent/btworking.html
2009年を振り返る
- 1月
- C with lambdaというトランスレータを実装した.
- 2月
- とくになし
- 3月
- 4月
- Erlangの勉強を始める.
- SIPropの皆さんに出会う.
- 高校に入学.
- 5月
- 6月
- クラウドコンピューティングコンペティションに参加.
- このイベントのおかげで,ErlangでSkip Graphを実装することができた.
- クラウドコンピューティングコンペティションに参加.
- 7月
- ErlangでConsistent Hashingを実装した.
- 8月
- セキュリティ&プログラミングキャンプに参加した.
- 九工大で分散処理の勉強会を行った.
- 9月
- 体育祭など.
- プログラミング関係はとくに無かった気がする.
- 10月
- 11月
- 12月
- VIOPSで招待講演をさせてもらった.
- 色んな人の話を聞くことができて良かった.
- Concurrent Joinを実装した.
- Cでスレッドプールを書いた.
- VIOPSで招待講演をさせてもらった.
最近Cで書いたプログラム
このブログでは Erlang と Python で書いたプログラムしか公開してないということに気づいたので,一気に晒すことにする.
- スレッドプール
- http://gist.github.com/262457
- 「スレッドプールって格好良い」と思って実装した.
- 思ったより簡単で,30分弱で出来上がった.
- ロックフリーなキューも実装できたので勉強になった気がする.
- JIT Brainfuck
- http://gist.github.com/118559
- 名前の通り,Brainfuck用のJITコンパイラ.
- 今年の5月頃に実装した.
- ストリームからの入力と出力は,アセンブリでどう書けばいいのか分からなかったので実装しなかった.
- スキップリストアルゴリズム
- http://gist.github.com/223449
- templateの習作として作った.
- 一応完成したところで飽きた.