sqlite-3.5.5リリース - リリース悲喜こもごも -
過去、結構sqliteのネタを書いていますが、だいぶ長い間、アップグレードしていませんでした。v3.5.4は安定していそうな気配だったので、そろそろいいかなと思っていたら、v3.5.5がリリースされました。
そして驚きの次のリリース文です。
Convert the underlying virtual machine to be a register-based machine rather than a stack-based machine.
ヴァージョン番号を0.0.1上げるリリースでやることですか...
メーリングリストのリリースメール(http://www.mail-archive.com/sqlite-users%40sqlite.org/msg31111.html)では、2週間しっかりテストしたから安定しているはずだ、とあります。 しかし、さっそくGNU/Linux以外ではテストに失敗するというリプライがついています。
更に、配布されている sqlite-3.5.5.tar.gz を展開すると、CVSディレクトリがそのまま入っているし、次のようにゴミファイルもそのままtar.gzに入っています(tar展開結果を一部抜粋)。
-rw-r--r-- drh/users 18034 2008-01-23 11:12 sqlite-3.5.5/src/utf.c -rw------- drh/users 167339 2008-01-04 02:05 sqlite-3.5.5/src/.#vdbe.c.1.669 -rw------- drh/users 168220 2008-01-04 03:36 sqlite-3.5.5/src/.#vdbe.c.1.671
全然、信用できません。
autoconfを使っているようなのでautomakeも合わせて使ってくれればこういうミスは防げます(make distで配布に含まれるべきファイルだけパッケージングしてくれます)。
対照的なのはapacheのリリースです。例えば、直近では、11月中旬(http://mail-archives.apache.org/mod_mbox/httpd-dev/200711.mbox/browser)にv2.2.7リリース準備が始まり、色々あった挙げ句、v2.2.7は流れてv2.2.8がリリースされたのが2008/1/19です。約2ヵ月のリリース作業です。v2.2.8は例外的に難産だった気もしますが、それでもリリースはいつも慎重です。各種環境でのテストパスを確認してからリリースしています。今でも、NetWareの動作確認(http://mail-archives.apache.org/mod_mbox/httpd-dev/200801.mbox/%3c477E63C9.6720.00AC.0@novell.com%3e)も流れます。良くも悪くもapacheは老成した開発プロジェクトだと感じます。
これに比べるとdrh(Dr. Richard Hipp)はお茶目さんです。Googleでの講演の時も、始まってすぐにお茶目さんぶりを発揮しています。
- Category(s)
- カテゴリなし
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/inoue/sqlite3-5-5/tbping
コミッタ制度
3年以上前ですが(http://dev.ariel-networks.com/blog/inoue.php?blogid=2&archive=2004-5-14)、Linusの驚異的作業量の記事を書いたことがあります。余談ながら、この時代、まだBitKeeperとLinusの蜜月時代でした。
一般的に、オープンソースでは、コミット権限を持った人(コミッタ)とそうでない開発者を厳密に区別します。インターネットには、スキル的にも人間的にも信用できない人がいるので、当然の仕組みです。もちろん、(ほとんどの場合)ソースを手元でいじるのは自由ですし、自分ブランチを作るのだって自由です。しかし、何が本家かはよく分からない部分もありますが、まあ本家と呼ばれるソースツリーがあるなら、そこへのコミット権は限定した開発者だけに与えるのが普通です。
アリエルでは、伝統的に、入社した開発者には最初からコミット権限を与えています。インターネットと違って、スキル的にも人間的にも信用できるだろう、と思われる人を採用しているので、ある意味では普通の仕組み、とも言えます。ただ、何か信念を持ってそうしているかと言えば、そうでもなく、どちらかと言えば惰性でこうなっています。
試験的に、これから入社する開発者に対して、コミッタとそうでない人を分けてみようと考えています。
これによって開発者間にヒエラルキーを作りたいわけではなく、どちらかと言うと、新しく入ってきた人の救済のためです。入社して最初のうちはコミッタにパッチを送って、コミッタがコミットするシステムです。
コミッタがもういいだろうと思えば、あるいは嫌になれば、その人にコミット権を与えます。多くのオープンソースでは、この敷居は結構高いですが、アリエルではここをそんなに高くする気はありません。予想ですが、せいぜい一ヶ月後には与えることになると思います。
ソフトウェアが歴史を持って規模が大きくなると、途中から参加した開発者は最初まごつきます。ある規模感になれば、能力は関係なく誰でもそうです。却って能力の低い開発者の方が、副作用があることに気をまわさないので、一見、作業の立ち上がりが早くみえることもあるぐらいです。
最初にコミット権が無ければ、多少、心理的負担が減ると思います。事情を知らない新参者のコードによる品質低下も防げます。
試験的なので、うまくいかなければやめます。
- Category(s)
- カテゴリなし
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/inoue/committer/tbping
sqlite-3.5.5のOpcode
で、驚きのリリース文と書きましたが、どれほどの変化か調べてみました。簡単なSQLではあまり変わりません(当り前?)。
今まで
pushを暗黙に行う命令 pushを暗黙に行う命令 pop,popを暗黙に行う命令
だったのが、
命令。結果をレジスタ1に格納 命令。結果をレジスタ2に格納 命令。レジスタ1とレジスタ2を引数
になるだけです。
以下、sqlite-3.4.2とsqlite-3.5.5の比較です。
sqlite-3.4.2で、単純なselectをした結果は次のようになりました。単純化するために、カラムは全部文字列にしています。
sqlite> CREATE TABLE my (title text, author text, body text); sqlite> .explain sqlite> EXPLAIN SELECT title FROM my WHERE author = 'foo'; addr opcode p1 p2 p3 ---- -------------- ---------- ---------- --------------------------------- 0 Goto 0 13 1 Integer 0 0 2 OpenRead 0 6 3 SetNumColumns 0 2 4 Rewind 0 11 5 Column 0 1 6 String8 0 0 foo 7 Ne 353 10 collseq(BINARY) 8 Column 0 0 9 Callback 1 0 10 Next 0 5 11 Close 0 0 12 Halt 0 0 13 Transaction 0 0 14 VerifyCookie 0 10 15 Goto 0 1 16 Noop 0 0
以下、addrカラム値がnの行をn行目と呼びます。
初期化の部分を無視すると、ループを形成しているのは、5行目から10行目です。10行目のNextは、レコードがあれば5行目にジャンプ、無ければ次の行(Close)に進みます。 5行目は1番目のカラムの値をスタックに積みます。カラムは0ベースなので、この場合、authorカラムです。6行目は文字列"foo"をスタックに積みます。7行目のNeは、勘が良ければ分かると思いますが、not equalの略で、スタックからふたつの値をポップして比較します。not equalが成立すると、10行目に飛びます。10行目はNextなので、このジャンプはcontinue相当です。8行目のColumnは0番目のカラム(titleカラム)の値をスタックに積みます。9行目のCallback命令は、スタックから値をポップして、ユーザアプリのコールバック関数を呼びます。sqliteの結果セットは、レコード単位でコールバック関数が呼ばれます。
同じことをsqlite-3.5.5ですると次のようになりました。
sqlite> EXPLAIN SELECT title FROM my WHERE author = 'foo'; addr opcode p1 p2 p3 p4 p5 comment ---- ------------- ---- ---- ---- ------------- -- ------------- 0 Trace 0 0 0 explain select title from my where author = 'foo'; 00 1 Goto 0 13 0 00 2 OpenRead 0 6 0 00 3 SetNumColumns 0 2 0 00 4 Rewind 0 11 0 00 5 Column 0 1 1 00 6 String8 0 2 0 foo 00 7 Ne 2 10 1 collseq(BINARY) 69 8 Column 0 0 3 00 9 ResultRow 3 1 0 00 10 Next 0 5 0 00 11 Close 0 0 0 00 12 Halt 0 0 0 00 13 Transaction 0 0 0 00 14 VerifyCookie 0 10 0 00 15 TableLock 0 6 0 my 00 16 Goto 0 2 0 00
ループも含めてほとんど変わりません(Callbackの代わりにResultRowになった程度)。5行目と6行目は、それぞれスタックに積まずに、レジスタ1とレジスタ2(それぞれp2で指定されています)に値をセットします。そして、7行目のNeはp1とp3で指定されたレジスタ(つまり1と2)の値を比較して、(not equalが)成立すると(p2で指定された)10行目に飛びます。
インデックスが使われる場合も見てみます。
以下はsqlite-3.4.2の結果です。
sqlite> CREATE INDEX idx_my ON my(author); sqlite> EXPLAIN SELECT title FROM my WHERE author = 'foo'; addr opcode p1 p2 p3 ---- -------------- ---------- ---------- --------------------------------- 0 Goto 0 21 1 Integer 0 0 2 OpenRead 0 6 3 SetNumColumns 0 2 4 Integer 0 0 5 OpenRead 1 7 keyinfo(1,BINARY) 6 String8 0 0 foo 7 IsNull -1 18 8 MakeRecord 1 0 a 9 MemStore 0 0 10 MoveGe 1 18 11 MemLoad 0 0 12 IdxGE 1 18 + 13 IdxRowid 1 0 14 MoveGe 0 0 15 Column 0 0 16 Callback 1 0 17 Next 1 11 18 Close 0 0 19 Close 1 0 20 Halt 0 0 21 Transaction 0 0 22 VerifyCookie 0 11 23 Goto 0 1 24 Noop 0 0
OpenReadが2つ(2行目と4行目)あります。4行目のOpenReadはインデックスのオープンです。それぞれp1の値が、それぞれの識別子です(Unixのシステムコール風に言えば、ファイルディスクリプタ相当です)。
ループは11行目から17行目です。
10行目のMoveGeで、インデックス上の"foo"の最初の位置を指します。12行目のIdxGEはインデックス上の値と"foo"を比較して、一致しなければ(正確には名前から推測できるようにgreater than or equalの演算)、18行目に飛んでループを抜けます。14行目のMoveGeはrowid(レコードを一意に識別するid)を使って、テーブル内のポインタ(カーソル)を動かします。
以下はsqlite-3.5.5の結果です。
sqlite> EXPLAIN SELECT title FROM my WHERE author = 'foo'; addr opcode p1 p2 p3 p4 p5 commeaddr opcode p1 p2 p3 p4 p5 comment ---- ------------- ---- ---- ---- ------------- -- ------------- 0 Trace 0 0 0 explain select title from my where author = 'foo'; 00 1 Goto 0 19 0 00 2 OpenRead 0 6 0 00 3 SetNumColumns 0 2 0 00 4 OpenRead 1 7 0 keyinfo(1,BINARY) 00 5 SetNumColumns 1 2 0 00 6 String8 0 2 0 foo 00 7 IsNull 2 16 0 00 8 MakeRecord 2 1 1 ab 00 9 MoveGe 1 16 1 00 10 IdxGE 1 16 1 01 11 IdxRowid 1 5 0 00 12 MoveGe 0 0 5 00 13 Column 0 0 6 00 14 ResultRow 6 1 0 00 15 Next 1 10 0 00 16 Close 0 0 0 00 17 Close 1 0 0 00 18 Halt 0 0 0 00 19 Transaction 0 0 0 00 20 VerifyCookie 0 11 0 00 21 TableLock 0 6 0 my 00 22 Goto 0 2 0 00
ループは10行目から15行目です。
9行目のMoveGeで、インデックス上の"foo"の位置を指します。10行目のIdxGEはインデックス上の値と"foo"を比較して、一致しなければ、16行目に飛んでループを抜けます。12行目のMoveGeはrowidを使って、テーブル内のポインタ(カーソル)を動かします。
ほとんど変わりませんが、少し命令が減っています。sqlite-3.4.2にあったMemStoreとMemLoadが無くなっていますが、これらは元々レジスタを扱うような命令だったので、無くなっているようです。
参考URL
- Category(s)
- カテゴリなし
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/inoue/sqlite-opcode/tbping
コントロールキーパッチ登場(モニター募集)
ここを読む人の多くは知っていると思いますが、最近のキーボードにはハードウェア的に重大なバグがあります。 コントロールキーの位置のバグです。 OSをインストールして最初に行うことが、コントロールキーの位置の修正、という人も多いと思います。実に不毛な話です。
ソフトウェア的にコントロールキーとCapsLockキーを入れ換える方法が現在の主流です。 実用上はこれでバグは修正されますが、キートップの刻印は間違ったままです。
アリエルの某開発者が、刻印のバグにもパッチが必要です、と主張しました。
こうしてコントロールキーパッチが誕生しました。
少し写真の写りが悪いですが、次のようにキートップに貼るだけでキーボードのバグが修正できます。刻印に微妙な凹凸もあります。

社内でベータテストをしてきましたが、見た目からは想像できない驚きの効用が報告されています。
- S氏「コントロールキーパッチを使い始めてから、遅刻しなくなりました」
- A氏「コントロールキーパッチを使い始めてから、Lispのカッコが気にならなくなりました」
- T氏「コントロールキーパッチを使い始めてから、痩せました」
あまりの反響の大きさに、広くモニター利用者を募ることにしました。 モニター利用に応募したい人は以下にメールを送ってください。
- ctrl-p あっと ariel-networks.com
モニター利用の条件は、利用した感想をWebで公開すること、です。
物の受け渡しは、中目黒に来るか、返信用封筒を封書で送ってもらうことになります。
こちらの都合で、適度な人数で締め切ります(メールでの先着順)。
- Category(s)
- カテゴリなし
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/inoue/ctrl-p/tbping
Re:コントロールキーパッチ登場(モニター募集)
Google Mapplets開発
Google Mapplets開発の勉強会資料を公開しました。
英語で発表しなければいけません。辛いです。
資料にも書いていますが、prototype.jsのbind()を使わないとJavaScriptを書ける気がしません。bind()を書く部分が冗長ですが、メソッド内のthisは一貫してオブジェクトを参照、という状態になっていないと、頭が混乱します。まあ、すべてクラス変数相当に持たせてしまえばbind()不要になりますが、それをやるなら、そもそもクラスを使いません。
- Category(s)
- カテゴリなし
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/inoue/google-mapplets/tbping
Re:Google Mapplets開発
http://dev.ariel-networks.com/articles/workshop/google-mapplets-ja/
縦置きモニター
家のメインマシンにつないでいた22インチCRTが突然壊れました。 なんの予兆もなく、何も映らなくなりました。
購入したのは6年近く前で、PCより高い買い物でした。その後、大きいLCDがそれなりの値段で手に入るようになると、重さと容積でCRTは邪魔な存在になりつつありましたが、使えているので、そのまま使い続けてきました
暫定的に、サブマシンにつないでいた20インチLCDをメインマシンにつなげることにしました。 この20インチLCDは回転して縦にできるので、試してみました。
Debian etchで必要な作業は次のふたつだけです。
- /etc/X11/xorg.conf の "Device" セクションに Option "RandRRotation" を追加
- xrandr -o left を実行
これで縦表示になります。
証拠1(最後に注目)
~ $ xdpyinfo
name of display: :0.0
version number: 11.0
vendor string: The X.Org Foundation
vendor release number: 70101000
X.Org version: 7.1.1
maximum request size: 16777212 bytes
motion buffer size: 256
bitmap unit, bit order, padding: 32, LSBFirst, 32
image byte order: LSBFirst
number of supported pixmap formats: 7
supported pixmap formats:
depth 1, bits_per_pixel 1, scanline_pad 32
depth 4, bits_per_pixel 8, scanline_pad 32
depth 8, bits_per_pixel 8, scanline_pad 32
depth 15, bits_per_pixel 16, scanline_pad 32
depth 16, bits_per_pixel 16, scanline_pad 32
depth 24, bits_per_pixel 32, scanline_pad 32
depth 32, bits_per_pixel 32, scanline_pad 32
keycode range: minimum 8, maximum 255
focus: window 0x24000c6, revert to PointerRoot
number of extensions: 28
BIG-REQUESTS
DAMAGE
DPMS
Extended-Visual-Information
GLX
MIT-SCREEN-SAVER
MIT-SHM
MIT-SUNDRY-NONSTANDARD
RANDR
RENDER
SECURITY
SGI-GLX
SHAPE
SYNC
TOG-CUP
X-Resource
XC-APPGROUP
XC-MISC
XFIXES
XFree86-Bigfont
XFree86-DGA
XFree86-DRI
XFree86-Misc
XFree86-VidModeExtension
XInputExtension
XKEYBOARD
XTEST
XVideo
default screen number: 0
number of screens: 1
screen #0:
dimensions: 1200x1600 pixels (318x423 millimeters)
resolution: 96x96 dots per inch
証拠2
emacsの基本分割がこうなりました。

毎回、コマンドラインで打つのは面倒なので、起動スクリプトに仕込みます。 gdmの画面も縦状態にしたいので、結局、次のファイルの最後に xrandr の実行処理を書きました。
- /etc/gdm/Init/Default
Xが起動するまで、文字が左から右にスクロールするのがシュールです。
- Category(s)
- カテゴリなし
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/inoue/xrandr/tbping
iGoogle Themes APIの微妙なXML
iGoogle Themes APIは、Googleが公開しているAPI(http://code.google.com)の中では、最もアプリを作るのが簡単なもののひとつだと思います。センスの良いテーマを作るのは容易ではありませんが。
最近のGoogleプレゼンツらしく、XMLファイルを書くだけでテーマが作れるようになっています。 しかし、このXMLに違和感があります。 テーマを記述するXMLは次のような構造のXMLです。
<?xml version="1.0" encoding="UTF-8" ?>
<ConfigMaps>
<ConfigMap type="Skin">
<Meta name="title">Simple Theme</Meta>
<Meta name="description">Simple theme example.</Meta>
<Meta name="author">Ariel</Meta>
</ConfigMap>
<ConfigMap type="Skin">
<Trait name="TimeOfDay">12am-1am</Trait>
<Attribute name="header.background_color">teal</Attribute>
<Attribute name="header.logo">white</Attribute>
<Attribute name="header.text_color">#ffffff</Attribute>
attributes...
</ConfigMap>
<ConfigMap type="Skin">
<Trait name="TimeOfDay">1am-2am</Trait>
attributes...
</ConfigMap>
</ConfigMaps>
テーマ記述の肝はAttribute要素です。上の例の最初のAttribute要素はCSSに翻訳すると次に対応するイメージです(あくまで概念上の対応です)。
XML;
<Attribute name="header.background_color">teal</Attribute>
CSS;
.header { background-color: teal }
Attribute要素はまあこんなものか、と思いますが、気持ち悪いのがConfigMap要素です。上の例で言えば、Meta要素を子に持つConfigMapとAttribute要素を子に持つConfigMapは概念レベルが異なると思います。にも関わらず同じConfigMapです。
Trait要素もなんか変です。動的テーマが作れると書いてありながら、できるのは時刻による振り分けだけという中途半端さです。できたから入れました的な雰囲気を感じます。そもそもTrait要素が親のConfigMap要素の選択基準になっている構造も微妙な気がします。
- Category(s)
- カテゴリなし
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/inoue/igoogle-themes/tbping
SSO、facebook、OAuth、Google AuthSub、OpenSocial、OpenID
タイトルに雑多な(しかも普通名詞と固有名詞が混在、かつサービス名と規格名も混在)名詞を並べました。この辺が微妙にしっくり来ません。なんと言うか、相互の関係にまだ見えない部分があります。一番の原因はOpenSocialのgadgetsへの入れ込みです。と言うか、最近のGoogleのgadgetsへの入れ込み方が理解できません。見えた時はまとめて勉強会のネタにしようかと思います。まずは雑記的に書いてみました。
「Webのユーザ認証とSSO (featuring facebook)」
ちなみに、話の前半のアイディアはほとんど徳力さんからもらいました。
facebookはPHP文化です(サンプル実装なども基本はPHP)。RESTを標榜しながら、なんでもかんでもPOSTメソッドです。アナーキーです。しかし、このアナーキーさが革新を生む要因な気もします。
余談ながら、facebookでは32bit signed intでユーザIDに足りなくなるとのことで、64bitに拡張するようです。
- Category(s)
- カテゴリなし
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/inoue/web-auth/tbping