バイナリ用の差分生成・適用コマンド xdelta を試してみた。
バイナリファイルとしては手元に入っていた TokyoCabinet の hdb ファイルを使った。
インストール
CentOS 6.5 では yum
で 1.1.4 が入った。
# yum install -y xdelta
# xdelta -v
xdelta: version 1.1.4
使ってみる
取り敢えず TokyoCabinet のデータベースで試してみる。
適当なデータベースを作成しデータを入れる。
$ tchmgr create ./example.hdb
$ tchmgr put ./example.hdb foo bar
データを入れた hdb ファイルをコピーし、片方にだけ追加でデータを入れる。
$ cp ./example.hdb ./example_old.hdb
$ tchmgr put ./example.hdb baz qux
以下のような状態になった。
$ tchmgr list ./example.hdb
foo
baz
$ tchmgr list ./example_old.hdb
foo
パッチを作成。
$ xdelta delta example_old.hdb example.hdb hdb.xdelta
差分ファイルが作成された。
$ ll
合計 1044
-rw-r--r-- 1 akishin akishin 528768 10月 5 00:20 2015 example.hdb
-rw-r--r-- 1 akishin akishin 528736 10月 5 00:20 2015 example_old.hdb
-rw-r--r-- 1 akishin akishin 266 10月 5 00:21 2015 hdb.xdelta
差分ファイルの情報は以下で確認できる。
$ xdelta info hdb.xdelta
xdelta: version 1.1.4 found patch version 1.1 in hdb.xdelta (compressed)
xdelta: output name: example.hdb
xdelta: output length: 528768
xdelta: output md5: e8678368af4cf3f4401998c2aafe2bda
xdelta: patch from segments: 2
xdelta: MD5 Length Copies Used Seq? Name
xdelta: 7ffda015e0093a3ec3e33f1752b068d0 43 3 43 yes (patch data)
xdelta: 09c2b02ab2b4c1c0a5ec2c344a2095e9 528736 14 528725 no example_old.hdb
パッチを適用する。
以下で example_old.hdb にパッチが適用され、example_patched.hdb というファイルが出力される。
$ xdelta patch hdb.xdelta example_old.hdb example_patched.hdb
パッチ適用後のファイルサイズがオリジナルと同じになっている。
$ ll
合計 1564
-rw-r--r-- 1 akishin akishin 528768 10月 5 00:20 2015 example.hdb
-rw-r--r-- 1 akishin akishin 528736 10月 5 00:20 2015 example_old.hdb
-rw-r--r-- 1 akishin akishin 528768 10月 5 00:24 2015 example_patched.hdb
-rw-r--r-- 1 akishin akishin 266 10月 5 00:21 2015 hdb.xdelta
内容も同じになっている事が確認できる。
$ tchmgr list ./example_patched.hdb
foo
baz
使った事無かったけどなかなか便利そう。
圧縮したファイルで試してみる
今度は
- hdb ファイルを gzip 圧縮
-
- の hdb ファイルに更に値を追加してから圧縮
とした場合に、gzip ファイルに差分を適用して正常に展開・動作するかを試してみる。
まずは hdb ファイルを gzip 圧縮。
$ gzip -c example.hdb > example_old.hdb.gz
hdb ファイルに値を追加。
$ tchmgr put ./example.hdb hoge fuga
$ tchmgr list ./example.hdb
foo
baz
hoge
値を追加した hdb ファイルを圧縮。
$ gzip -c example.hdb > example.hdb.gz
ファイルサイズは以下のようになった。
$ ll
合計 528
-rw-r--r-- 1 akishin akishin 528800 10月 8 21:55 2015 example.hdb
-rw-r--r-- 1 akishin akishin 695 10月 8 21:56 2015 example.hdb.gz
-rw-r--r-- 1 akishin akishin 693 10月 8 21:55 2015 example_old.hdb.gz
差分ファイルを作成。
$ xdelta delta example_old.hdb.gz example.hdb.gz hdb.gz.xdelta
$ ll hdb.gz.xdelta
-rw-r--r-- 1 akishin akishin 271 10月 8 22:02 2015 hdb.gz.xdelta
特に問題などは無さそう。
$ xdelta info hdb.gz.xdelta
xdelta: version 1.1.4 found patch version 1.1 in hdb.gz.xdelta (compressed)
xdelta: generated with a gzipped FROM file
xdelta: generated with a gzipped TO file
xdelta: output name: example.hdb.gz
xdelta: output length: 528800
xdelta: output md5: bacb0158f881a451804bf9894b08f265
xdelta: patch from segments: 2
xdelta: MD5 Length Copies Used Seq? Name
xdelta: 65f18a14b640468f88080d650e7b3ebb 45 4 45 yes (patch data)
xdelta: e8678368af4cf3f4401998c2aafe2bda 528768 21 528755 no example_old.hdb.gz
パッチを適用してみる。
$ xdelta patch hdb.gz.xdelta example_old.hdb.gz example_patched.hdb.gz
ファイルサイズはこんな感じ。
パッチ適用後のサイズがオリジナルと異なるのが若干気になるが・・・。
$ ll
合計 536
-rw-r--r-- 1 akishin akishin 528800 10月 8 21:55 2015 example.hdb
-rw-r--r-- 1 akishin akishin 695 10月 8 21:56 2015 example.hdb.gz
-rw-r--r-- 1 akishin akishin 693 10月 8 21:55 2015 example_old.hdb.gz
-rw-r--r-- 1 akishin akishin 683 10月 8 22:03 2015 example_patched.hdb.gz
-rw-r--r-- 1 akishin akishin 271 10月 8 22:02 2015 hdb.gz.xdelta
展開してみると問題なく展開された。
展開後の hdb ファイルのサイズは同じになっている。
$ gunzip example_patched.hdb.gz
$ ll
合計 1052
-rw-r--r-- 1 akishin akishin 528800 10月 8 21:55 2015 example.hdb
-rw-r--r-- 1 akishin akishin 695 10月 8 21:56 2015 example.hdb.gz
-rw-r--r-- 1 akishin akishin 693 10月 8 21:55 2015 example_old.hdb.gz
-rw-r--r-- 1 akishin akishin 528800 10月 8 22:03 2015 example_patched.hdb
-rw-r--r-- 1 akishin akishin 271 10月 8 22:02 2015 hdb.gz.xdelta
中身のデータも問題なく参照できる模様。
$ tchmgr list ./example_patched.hdb
foo
baz
hoge
$ tchmgr get ./example_patched.hdb hoge
fuga
参考サイト
xdelta - Wikipedia
https://ja.wikipedia.org/wiki/Xdelta
UNIXの部屋 コマンド検索:xdelta (*BSD/Linux)
http://x68000.q-e-d.net/~68user/unix/pickup?xdelta