EclipseでSubversion(インストール編)

唐突ですが、EclipseでSubversionを使うための方法について書いていきたいと思います。

なぜSubversionか。

なんででしょうね。

すみません、よく知らないんです。なにやら、このごろ流行っているらしいということくらいしか。このごろ? だいぶ前からありますね。CVSよりも優れたバージョン管理システムという話を聞いており、最近はSubversionが使われることも多いらしいということで、使ってみようと思いました。

EclipseでSubversionを使うためには、いくつかのプラグインを導入する必要があります。プラグインそのものにもいくつかの種類があるようですけれども、EclipseプロジェクトのひとつになっているSubversiveを導入することにします。なお、使うEclipseは3.6(コードネームHelios)です。また、MergeDocにより日本語化がなされていることを前提とします。

ホームページのDownloadsにはHelios用のリリース版が用意されているので、これを使います。zipをダウンロードするのもよいですが、アップデートサイトを利用した方が簡単でしょう。プラグインを配布しているサイトはEclipseに組み込まれているので、特別な追加処理は必要ありません。「ヘルプ」→「新規ソフトウェアのインストール」でインストールというダイアログを開き、「作業対象」の横にあるコンボボックスで「Helios – http://download.eclipse.org/releases/helios」を選びます。すると、下のリストにプラグインのカテゴリが表示されるので、「コラボレーション」を開き、「Subversion SVN チーム・プロバイダー(インキュベーション)」の横をチェックします。あとは、そのまま決定をしてインストールしていけば完了です。

次に、SVNコネクタが必要となります。Subversiveのドキュメントによると、チーム・プロバイダーのプラグインをインストールしてEclipseを再起動するとSubversiveコネクタを導入するためのダイアログが表示されるとのことです。しかし、わたしの環境では表示されなかったので、自前でインストールすることにしました。

Polarionというサイトに書かれているとおり、「http://community.polarion.com/projects/subversive/download/eclipse/2.0/helios-site/」を更新サイトのリポジトリーに追加して(「ヘルプ」→「新規ソフトウェアのインストール」→「追加」)(リポジトリーの名前は適当、たとえばSubversive SVN Connectors)、「Subversion SVNコネクター」の下にある「Subversion SVNコネクター」と「SVNKit 1.3.5 実装」にチェックをして、インストールします。ほかにJavaHLというものもありますが、実装方法の違いにすぎないので、SVNKitと好きな方を選んで構いません。ちなみに、SVNKitはPure JavaなSubversionの実装です。

チーム・プロバイダーとコネクターをインストールすれば、EclipseでSVNが使えるようになります。具体的な使い方については、次回ということで。

Spiderの実装 (2)

Spiderを実装するうえで頭を悩ませたのは、細かな違いを吸収し、統一された方法でデータベースにアクセスするためのDatabaseインターフェイスです。

インターフェイスのメソッドを実行するたびにSQLをコンパイルしていたのでは動作が重くなって仕方ありませんので、Connection#prepareStatement()でプリコンパイルしておかなければなりません。このタイミングとして、(1) Databaseの実装オブジェクトを構築するときにプリコンパイルする、(2) 各メソッドを実行するときにプリコンパイルする、という方法が考えられます。効率の面を考えれば、(2)ではメソッドを実行するたびにPreparedStatementのフィールドが初期化されているかを調べなければならないので、(1)の方が優れています。(1)は初期化に時間を要しますが、すべてのメソッドが使われるのならば、総計では変わりありません。nullチェックが入る分、(2)の方が(若干ですが)重くなります。

ただ、効率よりも考えるべきなのは、コードの見やすさです。(1)はコンストラクタ、または初期化メソッドにすべてのSQLを書き込まなければならず、そのSQLを使う部分とは離れてしまうことになります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public Database1 implements Database
{
    public Database1 ()
    {
        this.prepared = connection.prepareStatement("SELECT ...");
        // 初期化するSQLが増えていけば、ここがどんどん伸びていく
    }
    public int getData (long id)
    {
        this.prepared.setLong(1, id);
        ResultSet rs = this.prepared.executeQuery();
        // ...
    }
}

もっとも、エディタの上下分割機能を使えば解決するという問題でもあります。しかし、個人的には、そのような機能を使わずとも、SQLと、そのSQLを利用するコードは近くに配置したいという気持ちです。

一方、(2)の方法を採るのならば、SQLと、そのSQLを利用するコードは近くに配置することができるようになります。

1
2
3
4
5
6
7
8
9
10
11
12
13
public Database2 implements Database
{
    private PreparedQuery prepared;
    public int getData (long id)
    {
        if (this.prepared == null) {
            this.prepared = connection.prepareQuery("SELECT ...");
        }
        this.prepared.setLong(1, id);
        ResultSet rs = this.prepared.executeQuery();
        // ...
    }
}

SQLが遠く離れていると、何番目のパラメータに何のデータを入れればよいのか分かりにくくなってしまいますが、このようなコーディング方法であれば必ず近くに配置されるので分かりやすさが向上します。しかし、この方法では、メソッドが実際に呼ばれるまでSQLがコンパイルされません。そのため、SQLに文法エラーがあるとき、発見が遅れることになります(先にコンパイルしておけばオブジェクト構築時にエラーが検出される)。もっとも、すべてのメソッドについてテストするようにしておけば、これは問題になりません。開発スタイルとしても、ちゃんとテストは行うべきです。次に、毎回nullチェックが入るため、動作速度が(きわめてわずかですが)遅くなります。フィールドは最初に初期化された以降nullになることがないので、このチェックは最初の一回以外すべて意味を持ちません。個人的には、このような無駄が気になって仕方ありません。

以上から、(1)のように、あらかじめSQLをプリコンパイルするようにしつつ、(2)のように、SQLと、そのSQLを使うコードを付近に配置するという方針を考えることにします。

Firefoxが大量にメモリを使用する現象への対策

しばらく前まで、Firefoxが異様にメモリを消費して困っていました(約600MB)。そのおかげで頻繁にスワップが発生し、Firefox自体はもちろんのこと、システム全体のパフォーマンスも低下してしまっていました。

どこに原因があるのかハッキリとは分からなかったのですが、最近、あまり使っていないアドオンを無効化することで劇的な改善がみられました。おそらく、停止したアドオンがメモリを浪費する原因になっていたものと思われます。

停止前は増えるばかりだったメモリ使用量が、停止後は増減を繰り返して一定の値を保つようになっています。アドオンにメモリリークがあって、確保したオブジェクトを解放していないのだと考えられます。

どのアドオンが原因かは確認していないのですが、確認が取れ次第、続報として書き込みたいと思います。

どうもFirefoxの動作が重いなと感じている方は、使っていないアドオンをいったん無効化してみることをオススメします。メモリ使用量はタスクマネージャを使うことで確認することができます(firefox.exeのプロセスのワーキングメモリ量をみればよい)。

Spiderの実装 (1)

インターフェイスだけ定義してもプログラムは動作しませんので、実装をしなければなりません。

Spiderシステムは情報を蓄積して扱いやすいインターフェイスを提供するためのものですから、情報を蓄積するストレージが必要になります。フリースタイル(自前でディスクへの保存などの機能を実装する)でもいいのですが、効率の良いものを構築する自信はありません。また、かなりの手間がかかるので、完成がいつになるのか分かりません。そこで、リレーショナルデータベースをストレージシステムとして利用することにします。幸いなことに、JavaにはJDBCという仕組みが用意されているので、データベースの操作は比較的に楽です。また、著名なデータベースのJDBCドライバも公開されています。

どのデータベースを利用するか悩むところですが、まだシステムが成熟しておらず、テスト段階であることを考えれば、手軽に使うことのできるものが望ましいといえます。とはいえ、いつまでも簡易なデータベースに頼っているようでは、システムやデータの規模が大きくなってきたときに対応できなくなるおそれがあります。そのため、特定のデータベースに依存しない設計を目指すことにし、最初は扱いやすいデータベース(SQLiteなど)で開発し、徐々に本格的なデータベース(MySQLなど)へ移行していくことにします。具体的には、NetworkやConceptはデータベースを抽象化したオブジェクトを介してデータベースと情報をやり取りします。そして、そのデータベースごとに仲介オブジェクトの実体を実装していきます。

簡略的に記述すれば、次のようになります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package jp.blacksoft.spider_jdbc;
public interface Database
{
    /**
     * @param id
     *            調べるオブジェクトの概念ID
     * @return オブジェクトの作成日時, オブジェクトが存在しなければ{@code null}
     */
    public Date getConceptCreateDate (long id);
    // etc...
}
public class JdbcNetwork implements Network
{
    private final Database objDatabase;
    // etc...
}
public abstract class JdbcConcept implements Concept
{
    // ...
    @Override
    public Date getCreateDate ()
    {
        return this.getDatabase().getConceptCreateDate(this.numConceptID);
    }
    // ...
}

各データベース用の実装クラスでは、Databaseで定義されたインターフェイスに合わせた情報を返すように、各データベースに応じたSQLを記述します。

Red Dead Redemption – 瞬殺

PSNが復活したので、オンラインで遊んでみました。

オンラインでゲームを始めると、マップのどこかから突然始まります。キャラクターは、どこの人なのかよく分からない、太ったヒゲのおじさんになっていました。すべてランダムで始まるのか…と思っていたら、突如死亡。

「なに? なに? なにが起こったの?」

どうやら、別のプレイヤーに、遠くからスナイパーライフルで狙い撃ちされたようです。少し待つと、近くの場所で生き返って再開。と、またもや狙撃されて死亡w

なにwwこのwwクソゲーwwww

何度も同じ手で殺されるのはしゃくなので、次は生き返った後すぐに岩陰に隠れ、馬を呼びました。これでジグザグに走りながら逃げれば大丈夫! 口笛に吹かれて来たのは、やせ細ったラバでした…。遅い! 小さい! プレイヤー乗せたら動けないんじゃないかと思うようなサイズです。ともかく、それに乗って逃げます。しばらくすると、スナイパーがログアウトしたとの表示。なんとか逃げ切れたらしい…。

なんというか、理不尽だけど、これはこれで楽しいw

Red Dead Redemption – 本編クリア!

メインミッションすべてを達成し、スタッフロールまでたどり着きました。けっこう長かった!

マーストンは念願の農場を手に入れ、妻アビゲイル、息子ジャック、謎の「おじさん」(作中で「Uncle」としか呼ばれないため名前不明…スタッフロールでも「Uncle」でしたw)と、四人で牛や馬を飼う生活が始まります。牛を仕入れたり、作物を届けるなどで、マクファーレン牧場がらみのイベントがあり、ボニーと再開することもできました。

これまでの銃撃戦しかなかったミッションとは異なり、牛を追い立てたり、息子と狩りに行ったりなど、牧場での日常が繰り広げられ、なんとも落ち着いた感じです。マーストンが意外と良い父親で驚きました。ジャックはダメ息子ですけどね…。ややツンデレ系。

しかし、最後のミッションで急転直下、とんでもない展開に…。これはちょっと内容を書くことができません。気になる方は、ぜひ自分の目で確かめてください。最後の最後は、ちょっとした演出の後、スタッフロールとなります。この流れが実に素晴らしい。このような終わり方に納得しない方もいるのでしょうけれど、これこそ西部劇の世界なのでしょう。個人的には、満点近いストーリーだと思います。グランド・オート・セフトのように自由度の高い(どっちも同じメーカーですが)、箱庭的なところだけが売りのゲームだと思っていましたけれど、良い意味で裏切られました。

Continue reading

Red Dead Redemption – 追跡の果てに

メキシコでかつての仲間を始末すると、これまで行けなかった北東部、ブラックウォーターへ行けるようになります。石畳で整備された、ちょっと近代的な町。実物大で作ってあるのかなあ、と思ったのですが、それにしてはちょっと小さすぎますね。規模に関しては、遊びやすいようデフォルメされているのだと思います。この町に入ると、馬の蹄の音が響くようになるので、ちょっと楽しい。

家族を人質に取られたマーストン、保安官の言いなりに、難破船へ行ったり、警察署の屋上から銀行をスナイプしてみたり、頭のおかしい教授に協力して雪山(の絶壁)を登る羽目になったり、多数のギャングに襲撃を受けたり、ひたすら尽くします。なんでここまでせにゃいかんのかと思うくらい、いろいろやります。ミッション内容が多彩で、また、それぞれで舞台がいろいろと変わるので、楽しいのですけれども。

敵の砦を探るため、雪山を登るというミッションがありました。階段状になっている断崖絶壁を登っていくという、ちょっと登山とは違うものですが…。途中、敵に襲撃されたわけでもないのに、レーダーに死体マークが表示されました。おかしいな、と思ってその地点に近づいてみると、そこにはシカの死体。なんで? と付近を見ると、すぐ近くにクマが佇んでいました…。クマがシカを狩ってる! クマもこっちに気付いた様子。これはヤバイ! すぐさまリボルバーを抜いてデッドアイ発動、ヘッドショットを連発し、5発ぐらい当てたところで倒すことができました。これはビックリしましたね…。ライフル持った敵がいるより、よっぽど恐いw

ミッションクリア後、まだ訪れていない場所を探検してみようということで、湖の近くにある小屋へ行ってみました。とくに何かあるというわけではなく、単に景色が美しいだけの場所か~…と横を見れば、木の陰に何かの影が。…クマがいる。こっち見てる。そっと逃げれば大丈夫なんじゃね? ということで、近寄らず、立ち去ろうとしたところ…拳銃を振り回した二人に追い回される人が。よく分かりませんが、泥棒か喧嘩か、そこら辺でしょう。こんなところにもいるのね…と思っていると、追いかけられていた人が撃ち殺されてしまいました。御愁傷様…と次の瞬間、撃った一人をクマが襲撃!w 一撃で倒されます。もう一人は驚いて逃げ出しますが、それを追いかけるクマ。またも一撃で粉砕。そして…あ、こっち向いた。こっち来た! ちょw やめてw 待ってw マーストンさんも、一撃で粉砕されてしまいました…。何このクソゲーw

INSPIRON zeno HD + HDMI + FullHDのワナ

相方が「PS2からPCに乗り換える!」というので、DellのINSPIRON zino HDを購入。標準的なパッケージを選択し、すでにHDMI接続可能なフルHDの液晶モニタを持っていたので本体のみの購入。

このINSPIRON zino HD、きわめてコンパクトなボディでありながら、パワフルなプロセッサと、RADEON HD 4200というそれなりなグラフィック性能を持っており、「ちょっとした」用途のPCとしては魅力的な製品です。

製品が届くということで、設定「させられて」いるのですが、起動すると画面の周囲に不審な黒枠が。なんとなく、画面全体がダウンスケーリングされているような感じです。何かおかしい、ドライバの問題かと思ったのですが、こちらのブログに原因が書かれていました。どうやら、Catalystの設定(ひいてはグラフィックボードの設定)に問題があるようです。なぜに、1:1スケーリングを標準としないのか…。

ドライバを新しいものにすればよいかと思って、ATI(いまはAMD)のページから最新のドライバをダウンロードしてインストールしたのですが、こんどは「項目が消えていて設定できない」という事態に陥り、アンインストールして付属のドライバに戻しました。

教訓! RADEONに関しては、そうそうドライバをアップデートする必要はありません。むしろ事態を悪化させる可能性があります。

Spiderの基本構造 (2)

Networkは、そのネットワークに属するオブジェクト(KnowledgeとLink)について、Java標準のコレクションであるSetによるアクセス方法を提供します。しかし、場面によっては特定の条件を満たすオブジェクトのみを取得したい場合もあるので(例えば特定のプロパティを有するオブジェクトのみを取得するなど)、常にSetを用いてアクセスするのでは、データすべてを読み出したうえでフィルタリングしなければならず、非効率的です。

そのため、NetworkとSpiderは、特定の条件(SearchOption)を指定して検索できるようなメソッドを提供します。SearchOptionは用途に応じたサブクラスを提供しており、NetworkやSpiderは、指定された検索条件が実装するインターフェイスを調べることによって検索方法を判別します。これにより、Networkが現実に使用するデータベースの機能を用いるなどすることができ、アクセスの効率化が期待されます。

もっとも、現段階ではどのような検索条件が必要になるか明確ではないので、今後、具体的なアプリケーションを構築していくうえで問題が発生すれば、この仕様は変更されるかもしれません。

当初は、それぞれのNetworkが使用するデータベースとの接続オブジェクト(Connection)にはアクセスできないようにし、Network経由で接続を閉じるようなこともできないようにしようと考えていました。Networkがデータベース接続をラッピングするような役割を果たしているからです。Networkから実装側にアクセスできてしまうと、間違って接続を切断してしまうことも生じるのではないか、という不安もありました。

しかし、そのような方針では、アプリケーション側でConnectionを管理しなければなりません。すると、SpiderはNetworkを管理し、アプリケーションはConnectionを管理し、それらが整合するように調整する必要があります。これは手間ですし、バグを作り込む要因になってしまうので、Networkから実装側にアクセスする手段を提供することにしました。

Networkはインターフェイスですから、インスタンスを生成するためには実装クラスのコンストラクタを使う必要があります。しかし、それではアプリケーションとクラスライブラリが実装レベルで結びつくことになってしまい、仕様変更に強い設計になりません。そこで、Networkを構築するための情報として、NetworkSourceというインターフェイスと、NetworkFactoryというファクトリクラスを導入することにしました。

NetworkSourceはSerializableを拡張しており、シリアライズで永続化(保存)できることを想定しています。NetworkSourceのファクトリクラスも作れば完全に実装クラスとの結びつきを切断できるのですが、現段階ではファクトリのインターフェイスが定まっていないので、保留してあります。Networkのストレージとなるデータベースによって初期化に用いるパラメータが変わってくるので(例えばSQLiteではファイル名のみ、MySQLなどではデータベースのURLとユーザー名など)、そう簡単にはインターフェイス化できないのではないかと思っています。

Red Dead Redemption – メキシコ編クリア

Red Dead Redemption、メキシコ編のメインストーリーをクリアしました。焼き討ちをしたり、鉄道強盗をしたり、ガトリングガンをぶっ放したり、アメリカ編に負けず劣らず多彩なミッションを楽しめましたね。

メキシコ編の登場人物は、アメリカ編のように変人揃いではなく、(一見)まともな人が多く登場します。しかし、本当にまともな人だったのは革命軍の女性だけで(アメリカ編でもまともなのは牧場主の娘だけだったなあ…)、あとはクズ揃いでしたw

政府軍の大尉さんは、初めは気さくにマーストンを受け入れて「いい人なのかな?」と思いきや、利用済みになると敵の真っ直中にわずかな戦力で飛び込ませるし(そこから生還するマーストンも驚異的ですが…)、嘘を言って処刑しようとするし、どうしようもないクズでした。最終的には、マーストンたちに追い詰められて、処刑されます。

このとき、単純にリボルバーで撃つだけでは面白くないので、スナイパーライフルで頭を撃ち抜いてみました(至近距離なのにw)。ところが、確かに眉間を撃ち抜いたのに、次の瞬間には大尉は立ち上がってオロオロとし始めてしまいました。こ、これは一体なにが起こったのか!?w リボルバーを取り出して眉間を撃つと、今度は地面に倒れ伏しました。これはどういうバグだったのか…。リボルバーかライフルで撃たなければならなかったのかなあ。

革命軍のリーダーは、民衆から圧倒的に支持されている、金持ちのボンボンです。最初は政府側に「金持ちの道楽にすぎない、民衆を言葉で煽動しているだけだ」という風に言われていたので、「実はマトモな人なんだろう」と思っていたのですが、実際に会ってみると…絵に描いたようなボンボンでしたw

マーストンはメキシコを去るとき、このリーダーに「権力を得ても、自分がなぜ権力を得ようとしたのか忘れるな」と言い残しているのですが、おそらく、次の日には言われたことすら忘れているでしょう…。マーストンは皮肉と冷めた発言しかしませんが、その内容は客観的かつ現実的なものばかりで、個人的には支持できるものです。代替案を示さないので、単に皮肉っているだけのように聞こえてしまうのですが。本人は政治に興味がないようなので、まあ、それでもいいのでしょう。対して、革命軍の方々は、情熱に基づいて考え、発言しているようで、熱意があればどうにでもなるというような、精神論的な発言が多くみられます。リーダーに至っては、実は民衆のことなんか考えておらず、自分が権力を握って思い通りに国を作っていきたいだけなのだ、という利己的な考えすら見られます。これには参りました。渦中にいる方々は、熱くなってしまって、そういう風に考えてしまうのかもしれませんが…。

アメリカ編は、ちょっと喜劇的なところもあったのですが、メキシコ編は、人間的でビターなストーリーになっており、なかなか楽しめました。こういう、人間のドロドロした部分を描き出すストーリーは好きですね。いわゆる勧善懲悪モノの、敵を懲らしめてめでたしめでたし、という単純な話を楽しむような歳ではなくなったようです。

戦闘はアメリカ編より激しくなってきており、何度も撃ち殺されてしまいました。馬車に乗せられた囚人を奪還するというミッションでは、ちょっと先に走りすぎてしまい、先制攻撃を仕掛けるも集中砲火を浴びて即死、ということを何度も何度も…。後ろから、リピーターやライフルで一人ずつ確実に仕留めていくのがいいようです。前後から攻撃を受ける状況を作ってしまうと、あっという間に死にます。また、最後のミッションで、クリア後は敵本陣前に移動させられるのですが、そこでぼーっとしていると、なぜかメキシコ軍の兵士に撃たれます。けっこう激しく撃たれるので、あっという間に死にますw あれはなぜなんだろうか…。かなり理不尽に感じましたw