[DFって何?][日記][コマンド一覧][関連リンク][予定表][他のファイラー][逃げ帰る]
API | \\server\share\ | \\server\share | |
---|---|---|---|
SetCurDirectory() | OK | OK | |
GetDiskFreeSpace() | OK | OK | |
GetDiskFreeSpaceEx() | OK | OK | |
WNetAddConnection2() | NG | OK | |
WNetCancelConnection2() | OK | OK |
という感じ。とりあえず末尾の\はない方がいいらしい。
ネットワーク検索時、何も無いドメインにたいして検索した時にメモリリークしていた。
Win2k において CD-ROM 上では FindFirst/Next が最後まで検索されない事がある?
だとするとDFも引っかかります。うーん、気になる気になる。
ドライバとCD-ROMドライブも同じなんでしょうか。
Windows 98からWindows 95に対して接続テスト。
API | \\server | \\server\ | \\server\share | \\server\share\ |
---|---|---|---|---|
SetCurDirectory() | NG(161) | NG(67) | OK | OK |
GetDiskFreeSpace() | NG(123) | NG(123) | NG(123) | NG(50) |
GetDiskFreeSpaceEx() | NG(123) | NG(123) | OK | OK |
WNetAddConnection2() | OK | NG(67) | OK | OK |
WNetCancelConnection2() | OK | NG | OK | NG(1208) |
という感じ。とりあえず末尾の\はない方がいいらしいけど、GetDiskFreeSpace()の結果が気になる。末尾に\がついている時にはエラーコードが50。接続先によってはうまく動くのかもしれない。その代わり、末尾に\があるとネットワークの切断ができない諸刃の剣。
Windows 95からNT系に接続するテストが必要か。そんな環境ねーぞ、コンチクショウ。
/* コマンドラインの解析 ドライブがドライブ文字で、UNC パスではない場合、 ドライブ文字とコロンの後にバックスラッシュを不可する。 これは Windows 95 と 98 の制限である。 */
SDK32:GetDiskFreeSpace と GetDiskFreeSpaceEx についてより
まるでUNCでなければバックスラッシュは要らないような書き方だ。でも、バックスラッシュがあるかないかでエラーコードが違うのは何故だ。
誤字が気になるけど(最初、逆の意味に解釈した)、それよりも混乱したのがこれ。
これは Windows 2000 がディスク制限管理機構によって、管理者がユーザー単くらいのディスク容量の制限を行えるからである
SDK32:GetDiskFreeSpace と GetDiskFreeSpaceEx についてより
単位の位をくらいと読んだのだろうか。どういう手順で文書を作成しているのか気になる。
って悩んでいたらそのものズバリを発見。
UNC 名を指定する場合、最後に円記号(\)を付けてください。たとえば、\\MyServer\MyShare を調べたい場合、\\MyServer\MyShare\ という文字列を指定してください。一方、"C:" のようなドライブ指定の最後に円記号を付けることはできません。
解決したよ、ママン!
でもWindows 95ってGetDiskFreeSpace()にC:とか突っ込んで動いたっけ。誰か試せー。今家にある無印Windows 95マシンって起動しないLibretto 30だけだ。
なんにしろ、\\server\share\でないと動かないAPIは何だったか、という謎は解けたのでよし。
つーか、
Drive and UNC Name Parameter
GetDiskFreeSpace on Windows 95 and Windows 98 requires a trailing backslash for both drive letters and UNC names. Although Windows NT does not require the trailing backslash, you should add one if your program can run on both platforms.
INFO: Understanding and Using GetDiskFreeSpace and GetDiskFreeSpaceEx (Q231497) より
と矛盾しているような。
どっちだー。やっぱり誰か試せー。
気になったから英語版読んだんだけど、
If this parameter is a UNC name, you must follow it with a trailing backslash. For example, you would specify \\MyServer\MyShare as \\MyServer\MyShare\. However, a drive specification such as "C:" must have a trailing backslash.
must have
をどう訳したら付けることはできない
になるのだ。howeverに引きずられたか?
NTFSでは文字コード順に並び替えられてしまうのでいくら頑張ってもムダ。
つーことでDFには載せません。よろしく。
Windows 95OSR2で試してもらったらGetDiskFreeSpace("C:", ...)では失敗してエラーコードは123。
GetDiskFreeSpace("C:\", ...)ならうまく動く。
元の作りがよろしくない。
マクロ展開部分を作り替える方向で考え直そう。
おおむね作り直ったような気がする。
後はチューンチューン、チューンチューン。私の彼は…。
おい!あふを語ろうぜ! Part3 >>101より、[Delphi-ml:36460] [report] FindFirst problem。
予想通りFindNextFileがERROR_MORE_DATAを返してもそこでファイル名の列挙を止めなければうまくすべてのファイル名が取得できるようです。
[Delphi-ml:36460] [report] FindFirst problemより
あぁん!?
つまり、
If the function fails, the return value is zero. To get extended error information, call GetLastError. If no matching files can be found, the GetLastError function returns ERROR_NO_MORE_FILES.
ってこと? ってどういうことっていうか、GetLastError()がERROR_NO_MORE_FILESを返すまで回せってこと?
途中でこけた時が恐いけどなあ。
DFでCTRL+左クリックでファイルの選択をするとマークが見えない(画面が更新されない?)のは仕様でしょうか? >作者様
仕様なわけ無いだろコンチクショウ。
バグだよバグ、直すよ、直せばいいんだろコンチクショウ。
しかたないなあ。
これでどうだッ!
Ctrl+Tで背景を透過。
次はツリーか。transparentにtreeで同じTだしなあ、どのキーにしようか。
一発ネタで終わり、というのもアレなので背景に画像ファイルを指定できるようにしてみた。
みにくい。
あと、スクロールした時とか背景画像もスクロールさせてしまうのでアレだ。
他にもマーク付け背景が透過しているので反転しないとか。
[OPT]のBMP=で画像ファイル名。Susieプラグインが入ってればBMP以外もOk。ただし、反転表示とかができないので常用はできない。まあ、雰囲気だけ。
ちょっと直そうと思ったけど、結構根が深いね、これ。
描画部分のコードは大変なことになっているので大変だ。読みたくない。
どうしよ。
DOSの頃からパスの区切り文字として/は使えました。command.comはオプション指定文字として/を使用していたので、command.com経由では/はパス区切りと認識してくれませんでした。DOS バージョン3あたりまではcommand.comのオプション指定文字を変更することができたのでオプション指定文字を変更すると/も\もパス区切り文字として認識します。
command.comを経由しなければまったく問題なく/をパス区切り文字として使えるので、#include<sys/stat.h>とかfopen("c:/autoexec.bat", "r+");なんてのもOk。
MS-DOSのシステムコールを使って、command.comのパス区切り文字を変更してもアプリのほとんどがソコを参照せずにcommand.comのオプション指定文字列は/だと決めつけて書かれていたのでDOSバージョン5あたりでこの機能は削除されたと記憶している。
DFは/はディレクトリ区切りだと認識してない。まずー。
DFβ47でコームソートを使ってみた。結局クイックソートよりも遅かったのだけども、この辺りはチューニングが足りないのかもしれない。クイックソートは先人たちのノウハウがあるのでかなり極められている。今のところ最強に強まったソートアルゴリズムといえる。
WATCOMのプロファイラ出力から。
アルゴリズム | 消費クロック | 呼出回数 | 関数名 |
---|---|---|---|
コームソート | 38617358 | 1 | DoSort |
クイックソート | 23128651 | 1 | DoSort |
これはSRX3のWindows XP、システムディレクトリ(system32)にある2171個のファイル一覧をソートしたもの。
中で複数の関数を呼び出しているのでそちらの出力も。
関数名 | コームソート | クイックソート | ||
---|---|---|---|---|
消費クロック | 呼出回数 | 消費クロック | 呼出回数 | |
DoSort | 38617358 | 1 | 23128651 | 1 |
bsort | 36443974 | 1 | 20769090 | 1 |
insertsort | N/A | N/A | 3736779 | 317 |
xcomp | 31074886 | 55756 | 17498708 | 30622 |
DotDirComp | 3441577 | 55756 | 1920314 | 30622 |
NameComp | 17307192 | 54959 | 9440889 | 29785 |
x_strcmpi | 9521172 | 54959 | 5309624 | 29785 |
swap | 913743 | 5461 | 714127 | 4274 |
DoSort()はソートするための準備をしてからbsort()を呼び出す。DotDirComp()は"."とか".."と特別扱いする。xcomp()はディレクトリを特別扱いしたうえで比較関数を呼ぶ。
クイックソート版では、途中からインサートソートに切り替えている。insertsort()がそれ。
コレを見る限り、何が遅いってxcomp()。ソートの際の比較関数。80%のクロックはここで食いつぶしてる。しかもコームソートの時には50万回呼び出している。この関数を1クロック削るだけで全体で50万クロック、0.1%速くなる。逆にswap()を1クロック速くしても5461クロックしか速くならない。
DotDirComp()は一回辺り60クロックしか消費していない。もしかすると関数呼出しのオーバーヘッドが無視できないかも。インライン展開してみる価値はある。
それがダメなら関数呼出しを少なくするしかない。クイックソートは、コームソートに比べればそもそも比較回数が少ない。
コームソートは今のところ馬鹿正直に実装してあるだけなので、途中からシェーカーソートに切り替えるようなトリックを入れるといいかもしれない。
つーか、コレを見ているとxcomp()が異様に時間を食ってる。
static int xcomp(SORTINFO *a, SORTINFO *b, int (*comp)(const void*, const void*)){
int ret;
ret = DotDirComp(a, b);
if(ret){
return ret;
}
ret = (*comp)(a, b);
if(ret){
return ret;
}
ret = b->rank - a->rank;
return ret ? ret : x_strcmpi(a->fd->cFileName, b->fd->cFileName);
}
こんだけの処理。compはNameComp()をポイントしている。xcomp - DotDirCop - NameComp で求まるクロック数、10326117がこの関数で消費されていることになる。1回あたり185クロック。異様。
00A3 xcomp_:
00A3 FF 05 1C 00 00 00 inc dword ptr L$42
00A9 FF 05 20 00 00 00 inc dword ptr L$43
00AF 75 12 jne L$11
00B1 52 push edx
00B2 50 push eax
00B3 0F 31 rdtsc
00B5 29 05 24 00 00 00 sub L$44,eax
00BB 58 pop eax
00BC 19 15 28 00 00 00 sbb L$45,edx
00C2 5A pop edx
00C3 L$11:
00C3 51 push ecx
00C4 56 push esi
00C5 89 C1 mov ecx,eax
00C7 89 D6 mov esi,edx
00C9 E8 00 00 00 00 call DotDirComp_
00CE 85 C0 test eax,eax
00D0 75 1F jne L$12
00D2 89 F2 mov edx,esi
00D4 89 C8 mov eax,ecx
00D6 FF D3 call ebx
00D8 85 C0 test eax,eax
00DA 75 15 jne L$12
00DC 8B 46 04 mov eax,0x4[esi]
00DF 2B 41 04 sub eax,0x4[ecx]
00E2 75 0D jne L$12
00E4 8B 06 mov eax,[esi]
00E6 8B 10 mov edx,[eax]
00E8 8B 01 mov eax,[ecx]
00EA 8B 00 mov eax,[eax]
00EC E8 00 00 00 00 call x_strcmpi_
00F1 L$12:
00F1 5E pop esi
00F2 59 pop ecx
00F3 FF 0D 20 00 00 00 dec dword ptr L$43
00F9 7D 12 jge L$13
00FB 52 push edx
00FC 50 push eax
00FD 0F 31 rdtsc
00FF 01 05 24 00 00 00 add L$44,eax
0105 58 pop eax
0106 11 15 28 00 00 00 adc L$45,edx
010C 5A pop edx
010D L$13:
010D C3 ret
00B3のRDTSCから00FDのRDTSCまでのクロックを集計しているハズ。74バイトのルーチンに180クロックもかかるか? っていうか分岐でパイプラインストールしまくりっぽい。P6なら遅延分岐するから大丈夫かと思っていたのに。
仕方がない、-ob(パイプラインを考慮する最適化オプション)つけてコンパイルしてみる。これ使うとサイズが増えるんだよなあ。
関数名 | 使用前 | 使用後 | ||
---|---|---|---|---|
消費クロック | 呼出回数 | 消費クロック | 呼出回数 | |
bsort | 20769090 | 1 | 21561269 | 1 |
xcomp | 17498708 | 30622 | 18324121 | 30622 |
遅くなっとるがな。
誰か、Visual C++6.0とか、Intel C/C++とかもっとイカスコンパイラください。
勤務先マシンにインストールしてみたらカーソル位置の色指定が効いていないことが判明。
気になって仕方がないが、たばこを吸いまくる環境で冷却ファンのあるSRX3を取り出す気にもなれず放置。
[OPT]にLINK=1を付けるとディレクトリのショートカットをDF内で解決する。
結構前から。記憶だとβ39から。
ディレクトリだけ解決してファイルに付いて解決しないのは気に入らなかったのだけど、ファイルに付いても解決してしまうとショートカットをコピーするという芸ができないことに気づいたのでこのままにしよう。
仮想キーコードと文字コードを取り違えてる。
/* VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39) */
/* VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A) */
とあるので、この範囲外を文字コードとして設定するようにしたい。
私の書き方だと
if(!( ('0' <= key && key <= '9') || ('A' <= key && key <= 'Z')) ){
という感じで範囲内かを求めてから反転させるんだけども、コレもスマートじゃないような気がして、範囲外かどうかを求めるつもりで
if((key <'0' || '9' < key) || (key < 'A' || 'Z' < key)){
と書いてみる。key < 'A' と書いたところで動かないことを悟る。
こういうのってどう書くのが定石?
あ、
if((key <'0' || '9' < key) && (key < 'A' || 'Z' < key)){
だ。これもスマートな感じはしないなあ。でもこっちの方がマシか。
カーソル移動時の再描画にバグがあった。
スクロールする必要が無いのにスクロールしてしまう。FIVAに残っていたβ19では発生しないので、最近埋めこんだものだろう。
意図せずスクロール処理が動くバグを直したら、今度はスクロールした時にカーソルが残るバグが。
くそっ。
コピー先に相対ディレクトリを突っ込むとNULLを参照する。
ルートディレクトリを探してコピー先ディレクトリを作る、という処理でルートディレクトリが解らない。
で、この時のエラーチェックを忘れていた。というか、しなくてもいいような気がしていた。
NTFSのマウントボリュームを使用していると、空き容量などがマウント元の値を表示していたのを修正。
このために使うのか。なるほど。
β56として公開。
メールはこちらCopyrigiht © 2002 びい(@nifty ID:RXA01732)