Firefoxからアルクを検索する
WEB上で英語を読む時は前からアルクを使っているのですが、どうにかしてFirefoxの右クリックから検索できないものかと思っていました。
と、思ったらすでにいくつか方法があるみたいです。
ということで、今回は違う方法を。
コードリーディング
引き続き今更WEB+DB Press Vol.35を読んで。
予備知識
- 見るべきところ
- モジュールの構成と役割
- アルゴリズムとその意図
- データ構造の意味
- 解析の種類
- 静的解析
- 動的解析
- 実際に動かす
- 心得
- 「メモ」をとりつづけること
- わかったことをどんどんメモって残す、不要になったメモはどんどん捨てる
- 「メモ」をとりつづけること
Eclipseの便利技
- F3
- 宣言ジャンプ
- F4
- 型階層を開く(実装コードを開く)
- Ctrl + Alt + h
- 呼び出し階層を開く
Javascriptの高速化
こちらも今更ですが、WEB + DB Press Vol.35 を読んだメモ。
今日、jQueryとかのライブラリの躍進が目覚ましいので、それほどイベントハンドラをごちゃごちゃ書く機会もなくなっているのかなーとも思いますので、使いそうなところのみ。
(というか自分の能力がしょぼいから書く必要性を感じていないということかも...orz)
DOMへのアクセスを少なくする
DOMへのアクセスをできるだけ少なくする = できるだけ.(ドット)を使わないようにする
.(ドット)へのアクセス回数を減らす
var nameList = document.getElementById('name'); nameList.style.height = '100px'; nameList.style.weight = '100px'; nameList.style.top = '100px';
↓↓↓
var nameList = document.getElementById('name'); var style = nameList.style; style.height = '100px'; style.weight = '100px'; style.top = '100px';
上に同じく。forでlengthを使うとき
var nameList = document.getElementById('name'); for (var i = 0; i < nameList.length; i++) { // 繰り返し処理 }
↓↓↓
var nameList = document.getElementById('name'); for (var i = 0, var len = nameList.length; i < len; i++) { // 繰り返し処理 }
innerHTMLはコストが高いので、できるだけ参照しない
var nameList = document.getElementById('name'); name.innerHTML += '<div>\n'; name.innerHTML += 'div要素が追加されます.\n'; name.innerHTML += '</div>\n'
↓↓↓
var nameList = document.getElementById('name'); var html = nameList.innerHTML; html += '<div>\n'; html += 'div要素が追加されます.\n'; html += '</div>\n' nameList.innerHTML = html;
Postgresのレプリケーション
WEB+DB Press vol.35を今更読んで、前から気になっていたPostgresのレプリケーションについてメモ。
ただし、文章中にPostgres8.1.4とか出てくるので情報が古い、アンド、全然調べていないので未確認情報もあると思うので、本当にメモ程度ですね...
pg-pool II
PostgresForest
PGCluster
- レプリケーション
- PGCluster II
- 三谷さん
- 聞く限り三谷さんほぼ一人で開発されてる??
- ちょっとそれは怖いかも...笑
- でもサポートとかは、かなり誠意を以って対応してもらえるとも
- いつ寝てるんだという噂も...笑
Slony-I
- シングルマスタ/マルチスレーブ構成
- マスタとスレーブは非同期で同期
- 非同期なので、復旧手順を詰める必要がありそう
- 各ノードにSlonデーモンというのが動いている
- これが落ちたらどうするんやろう??
一度色々試してみたいですねー。
(function() {})()とかnew function() {}とか
一昔前に (function(){})() とか new function() {} とか function() {}() とかは何やねんという記事が流行った??時期がありました。
あの時は、いくつか記事を読んでも正直もう何が何だかわからなかったのですが、久しぶりに紐解いてみるとちょっとはわかったような気がしたのでメモ。
まず、(function() {})()とかnew function() {}の違い
つまり、
- (function(){})()
- 無名関数を今すぐ実行
- 最後の () が今すぐ実行するということ
- ロード後1度だけ実行
// 無名関数をすぐに実行 (function(){ // 初期化処理などを行う alert('test1'); })();
new function() { // 初期化処理などを行う alert('test2'); }
function(){} () は何者か??
例えば、よくみかける
var test3 = function() { return 'test3'; };
というのは、
var test3 = function() { return 'test3'; }; alert(test3)
だと、
function() { return 'test3'; };
というように、関数の文字列自体がalertされます。
なので、
var test3 = function() { return 'test3'; }; alert(test3()) // test3 じゃなくて test3()とする
とtest3が関数として見做され、「test3」 という文字列がalertされます。
つまり、変数test3は、関数自身を参照している?ことになる・・・のかな??
では、本題の下記はどうかと言うと
var test4 = function() { return 'test4'; }(); alert(test4);
は、「test4」という文字列が表示されます。
つまり変数test4は実行結果が代入されていることになります。
で、
var test4 = function() { return 'test4'; }(); alert(test4());
は、firebugだと、「test4 is not a function」とエラーになります。
つまり、上記の変数test4は、実行結果なので関数じゃないよ、って怒られているようです。
となると、単に関数宣言の後に () があると今すぐ実行になるよ、ってだけの話のようです。
という結論が、もっと詳しくココに書いてあります。
Javaにおけるファイルロックについて
いわゆるファイルロック
File lockFile = new File("pid.lock"); lockFile.deleteOnExit(); while (lockFile.createNewFile()) { try { // ロックを取得している場合の処理 ... } finally { lockFile.delete(); } } else { throw new RuntimeException("ロックを取得できませんでした."); }
上記はいわゆるファイルロックと言われるものです。
マルチスレッド環境の際に同じ処理が並列に実行されるとマズい場合、ファイルロックにより同じ処理が並列に実行され内容に制御します。
File#createNewFile() は、ファイルが存在しなければ新規にファイルを作成しTrueを返し、既にファイルが存在すればFalseを返します。
ただし、上記はうまく動かない場合があります。
詳しくはこちらを見ていただくといいかと思いますが、要はJavaVMが異常終了したときなどにロックファイルが残り続けてしまうのが問題となります。
ちなみに、
- File#deleteOnExit()
- JavaVMが「正常終了」した時にファイルを削除
- 「正常終了」の定義は、Java言語仕様に書いてあるそうですが、プロセスをkillするとかディスクがぶっ飛ぶとかしない限りは正常終了に当たるっぽいです。(未確認)
FileLockオブジェクト
ということで紹介されている通り、FileLockオブジェクトを使用します。
ちなみにFile#createNewFile()のJavaDocにも、File#createNewFile()はファイルロックに使用すべきでなく、FileLockを使用するよう書いてあります。
FileLockを使用すると、下記のようになります。
try { File lockFile = new File("pid.lock"); lockFile.deleteOnExit(); fs = new FileInputStream(lockFile); FileChannel fc = fs.getChannel(); FileLock lock = fc.tryLock(); if (lock == null) { new RuntimeException("ロック中"); } try { // ロックを獲得している場合の処理 ... } finally { // ロックの開放 lock.release(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { fs.close(); } catch (IOException e) { e.printStackTrace(); } }
FileLockオブジェクトは、FileChannelを通して取得します。
FileLockは、ここに詳しい説明が書いてありますが、
基本となるオペレーティングシステムのネイティブのロック機能に直接マッピングされます。
このため、ファイルにアクセスできるあらゆるプログラムが、作成に使用された言語とは関係なく、このファイル上に保持されたロックを認識します。
だそうです。
FileLockオブジェクトは、たぶんJavaVMが正常終了・異常終了に関わらず、終了すれば消えてくれる??ので、File#createNewFile()みたいにロックが残りつづけることがないんでしょうかね。(未確認)
(File#createNewFile()は、ファイルの有無=ロックの有無なので。ということでFileLockオブジェクトを使用してもファイルは残る、でもロックは解除される??)
- FileChannel
- FileChannel#tryLock()
- ロックを取得します。ただし、ロックを獲得できなかった場合は、すぐにメソッドを終了し、nullを返します。
- 逆にFileChannel#lock()は、ロックを獲得するまでの間処理をブロックして待機します。
- FileLock#release();
- ロックを開放します。
- FileChannelを先に閉じてしまうと、ClosedChannelExceptionが発生するので注意。
- FileInputStream#close();
- ファイル入力ストリームを閉じます。
- ここにあるように、FileChannelは作成元となったストリームと密接に関係しているため、FileChannelも同時に閉じられます。
気になったこと
FileChannel#tryLock()の仕様
JavaDocによると、
オーバーラップしたロックが別のプログラムによって保持されていたためロックに失敗した場合、null が返されます。その他の原因でロックに失敗した場合は、適切な例外がスローされます。
とあります。
ですが、どうもnullが返されず、いつもOverlappingFileLockExceptionがスローされます。
nullっていつ返ってくるんでしょうかね。
ロックの種類
ここの余談にもありますが、Linuxはアドバイザリ・ロック、Windowsは強制ロックでJavaが実装されているようです。
- アドバイザリ・ロック
- あるプロセスのロックは異なるプロセスへ影響を与えない。
- つまり異なるプロセス間のロックによる管理は行えない。
- 強制ロック
- あるプロセスのロックは異なるプロセスへも影響を与える。
- つまり異なるプロセス間のロックも行える。
ということで、LinuxとWindowsの挙動が違います。
Javaのプロセスの定義とスレッドの定義がイマイチまだよくわかっておらず、どうしたらマルチスレッドでどうしたらマルチプロセスなのか。
つまり、例えば java コマンドで複数実行すればマルチプロセスになるのかどうかとか。(←それくらいすぐ調べられるから調べろよ。。。)
FileLockの仕様
ここに下記のような文章があります。
ファイルロックは Java 仮想マシン全体のために保持されます。これらは、同一仮想マシン内の複数スレッドによるファイルへのアクセスを制御するには適していません。
ファイルロックオブジェクトは、複数の並行スレッドで安全に使用できます。
これがまた曲者で、読み手の読み方次第でいろんな解釈の仕方がありそうなんですが。。。
「複数スレッド」と「複数の並行スレッド」ってそんなに意味が変わらないような。
つまるところ、「ファイルアクセス制御」には使うな、でも「ロック」としては使えるってこと??
UbuntuのJDK
Ubuntuを使用しているので、apt-getよりJDK1.6.10をインストールしています。
で、何が問題なのかと言うと、Ubuntuのコマンドには「fcntl(2)」コマンドがありません。。。
ここの余談では、LinuxのJDKは「fcntl」で実装されているそうなんですが。
で、調べてみると「fcntl」はシステムコールだそうです。(システムコールとは)
システムコールの種類は unistd.h というファイルで一覧が確認できるみたいなので、調べてみました。
使ってるPCはcore2quad(アーキテクチャはx86)なので、/usr/src/linux-headers-2.6.27-14-generic/include/asm-x86/unistd_32.h を見ると、
#define __NR_fcntl 55
って書いてあるので、システムコールとしては存在するみたいですね。
まあUbuntuもLinuxという大きな枠組みの中の一つのカーネルですので、まああるとは思っていたのですがコマンドから使えないシステムコールもあるんですね。(まあそりゃそうか)
「55」っていう番号の意味はこことかがわかりやすいです。
Ubuntuのvimでfuzzyfinder3.1を使う
fuzzyfinderというvimスクリプトがあるのは前から知っていたのですが、3系がリリースされたのでこれを機に使うことにしました。
使い方は、ここからダウンロードして、docを見てください。(でも個人的には少しわかりにくかったので、時間があればまとめたいです)
作業ログ
$ mkdir ~/.vim/fuzzyfinder $ unzip vim-fuzzyfinder.zip -d ~/.vim/fuzzyfinder $ vi .vimrc ---------------------------------------------------- " fuzzyfinder set runtimepath+=~/.vim/fuzzyfinder ----------------------------------------------------
doc/fuf.jaxのインストール方法はこれだけなんですが、なぜかこれだけでは:FufBufferとかのコマンドが出てきませんでした。
2系列のfuzzyfinderはうまく動いたので、2から3に変わるときに何か変更が入ったんかなーと思って見てみると、各vimファイルの下記がだめなようです。
たとえば、plugin/fuf.vimであれば、
if exists('g:loaded_fuf') || v:version < 702 finish endif let g:loaded_fuf = 1
というように、全てのvimファイルに上記のようにv:version < 702と書いてあり、Ubuntuのパッケージの最新のgvimは701なのでスクリプトの読み込みがされていないようでした。
ということで動くかどうかわからんけど、やってみようということで少しif条件を変更してみました。
gvimを起動して、cdで~/.vim/fuzzyfinderに移動 で、コマンドラインモードより下記をタイプ :vimgrep /v:version/ **/*.vim | cwin
んでもって、702の部分を全て701に変更しました。
まあ、sedとかでもいいんですが、せっかくなのでvimgrepを使用しての変更にしてみました。笑
今のところこれでも普通に使えてるので、問題ないのかなーという感じです。
うーん、こりゃ便利。今までなんで使ってなかったんやろうと後悔しますねー。