エンジニアが発信する【2007年02月】の記事です

エンジニアが作る最新ITブログ トップ>【2007年02月】

2007年02月28日

できなかったプログラムのコンパイルに成功

昨日はうまく休憩ができなくてとても疲れてしまいました。
適度に休まないとダメだとはわかっているんですが、
プログラムがコンパイルできずにいらいらしてしまい、
休む余裕がありませんでした。

で、そのプログラムはCellのプログラムなのですが、
makeでコンパイルしようとしてもできない。
make.footerが重要だとは調べてわかったのですが、
CELL_TOPを/opt/ibm/cell-sdk/prototype にしても
そんなところは存在しないとなってダメ。

そして、もしかしたら手動で開発環境を用意したのが
原因かなと思いIBM alphaWorksから、Cell SDK 2.0
ダウンロードしてきて、それで開発環境を準備したらあっさ
りコンパイルできてしまいました。

手動のはフルセットじゃなかったんですね。
調べない自分も悪いんですが、もうすこし詳しく書いといて欲しいな。
一日つぶれたよ。

2007年02月28日

java.util.UUID(JDK 5以降)

今までユニークID発行のために、org.w3c.util.UUIDを使っていましたが、JDK 5以降ではjava.util.UUIDが追加されました。

使い方は簡単で、

UUID id = UUID.randomUUID();
System.out.println(id.toString());

2007年02月28日

java.util.HashMapの実装の変化

javaでは気軽にjava.util.HashMapを使っていますが、JDKのバージョンが上がると実装が変わっていました。

・・・

Sun JDK 1.3

例えば、HashMap#getをソースの一部は以下の通り。

int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry e = tab[index]; e != null; e = e.next)

教科書的なコードです。

Sun JDK 1.4

同じくHashMap#getの一部。

int hash = hash(k);
int i = indexFor(hash, table.length);
Entry e = table[i];
while (true) {

これじゃ何やっているか分からないので、HashMap#hashとHashMap#indexForも探す。

static int hash(Object x) {
int h = x.hashCode();
h += ~(h << 9);
h ^= (h >>> 14);
h += (h << 4);
h ^= (h >>> 10);
return h;
}

static int indexFor(int h, int length) {
return h & (length-1);
}

どうやらkeyとして渡したhashCodeをビット操作している。さらにテーブルの要素数を2の累乗にして、剰余(%)ではなくビットマスク(&)でインデックスを計算している。

Sun JDK 5

型がジェネリクスになっているけど、HashMap#getはほぼ同じ。そこで、hashメソッドを探す。

static int hash(int h) {
return useNewHash ? newHash(h) : oldHash(h);
}

なんじゃ? newHashとoldHash

private static int oldHash(int h) {
h += ~(h << 9);
h ^= (h >>> 14);
h += (h << 4);
h ^= (h >>> 10);
return h;
}

private static int newHash(int h) {
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}

useNewHashフラグですが、デフォルトはfalseなので、oldHashが使われる。

Javadocコメントを見ると、-XX起動オプションで指定するらしい。#やったことないが・・

Set to true only by hotspot when invoked via
-XX:+UseNewHashFunction or -XX:+AggressiveOpts

Sun JDK 6

HashMap#getは同じようにhashを呼んでいる。hashの実装は以下の通り、JDK 5のnewHashとなった。

static int hash(int h) {
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}

IBM Java 1.3

引用しないが、Sun JDK 1.3と同じ。別の場所でIBMが修正を入れている(rehash)。

IBM Java 1.4

引用しないが、Sun JDK 1.4と同じ。IBMの修正を入れている。

IBM Java 5

型がジェネリクスになっているけど、ハッシュ値算出はSun JDK 1.4と同じ。つまりnewHashのロジックはなく、oldHashのロジック。

BEA Jrockit VM 5

型がジェネリクスになっているけど、ハッシュ値算出はSun JDK 1.4と同じ。つまりnewHashのロジックはなく、oldHashのロジック。

まとめ

oldHashとnewHashの違いはよく分からんが、IBMもBEAもV6くらいにnewHashに移行するのだろうか・・。

ダメなこと

自前のクラスでFoo#hashCodeが常に定数(例えば1)を返す実装にすると、常にハッシュ値が同じなので衝突します。

これはJDK 1.3のロジックだろうが、oldHashだろうが、newHashだろうが、同じです。



2007年02月28日

[javascript][Greasemonkey] 楽天ブックスに野洲市立野洲図書館の蔵書検索リンクを追加するGreasemonkeyスクリプト

[http://d.hatena.ne.jp/simh/20070228:title=前回]に続き、楽天ブックスに野洲市立野洲図書館の蔵書検索リンクを追加するGreasemonkeyスクリプトを作成しました。 使用するには、Firefox と Greasemonkey が必要です。(Firefox 1.5.0.10 と Greasemonkey 0.6.7.20070131.0 で動作確認) [http://untold.sakura.ne.jp/file/gm_script/rakutenboo ...

エンジニアが作る最新ITブログ トップ>【2007年02月】

メンバー紹介

タグパネル

ランキング

エンジニアが作る最新ITブログ DODA