差分FTPを考える(6 – スピードアップ

十数個のファイルであれば問題ないのですが、数百もある場合cksumが結構負荷が高いので時間もかかります。
なんとか早くする方法を考えてみました。

findでファイル情報を取得できないだろうか

findでcksumをするオプションがあれば一番良いですが、そのようなオプションはないようでです。

-lsを使うとファイル情報も出してくれるようです。

-ls

結果をファイル詳細付きで表示する。"ls -dils"と同様な形式を指定する

試してみます。

$ find test -type f -ls
1979221 4 -rw-r--r-- 1 mlin mlin 2 9月 22 10:31 test/3/5/6/b.txt
1979223 4 -rw-r--r-- 1 mlin mlin 2 9月 22 10:33 test/3/5/d.txt
1979222 4 -rw-r--r-- 1 mlin mlin 2 9月 22 10:32 test/2/4/c.txt
1979220 4 -rw-r--r-- 1 mlin mlin 2 9月 22 10:31 test/a.txt
1979219 4 -rw-r--r-- 1 mlin mlin 2 9月 22 14:31 test/1/e.txt

一番左にチェックサムっぽい数値が出ています。これ実はiノードと言うものらしいです。

http://kazmax.zpp.jp/linux_beginner/inode.html

ノード(inode)番号とは、ファイルやディレクトリに割り振られる、重複しない番号の事をいいます。

全てのファイル、ディレクトリに対しiノード番号が割り振られます。

iノードは、iノード番号、UID、GID、パーミッション、ファイルサイズ、ファイル作成時間、更新日時、実際のデータの位置(ディスク上の物理的な場所)、そのファイル自身への参照数をデータとして管理しています。

ということで、ファイルが変化した?、というフラグに使うには十分そうです。

 

テストしてみます。

#!/usr/bin/perl
use strict;
use Storable qw(nstore retrieve);
use Cwd;
my $cwd = getcwd();

#----- conf --------
my $hdata='hdata.dat';
#-------------------
#### Read ###########################
my %htmp;
if ( -f $hdata ){
%htmp=%{ retrieve(${hdata}) };
}
#####################################

# testディレクトリに移る
chdir "test";

open (FNAME,qq(find . -type f -ls|));
while (<FNAME>){
    chomp;
    my $inode=(split(" ",$_))[0];
    my $filepath=(split(" ",$_))[10];

    my $dn=`dirname $filepath`;
    my $fn=`basename $filepath`;
    chomp($dn);
    chomp($fn);
    $htmp{$filepath} = qq($inode);
}
#### Write ##########################
chdir $cwd;
nstore \%htmp , $hdata;
#####################################

inodeが0番目、パスが10番目、であるので、splitで切り出しています。

いちいちチェックサムするよりもかなりの高速化が期待できそうです。