Slide 1

Slide 1 text

2015.11.18 @tkengo highway

Slide 2

Slide 2 text

• ソースコード検索ツール。 • マルチスレッドで動作。 • たぶんだいぶ速い。 • 詳しくはこちら
 http://tkengo.github.io/blog/2015/10/19/release-highway/ highwayとは

Slide 3

Slide 3 text

highwayの アーキテクチャ

Slide 4

Slide 4 text

1. 文字列探索アルゴリズム 2. マルチスレッド 3. ファイルのスキップ 4. ディスクI/O highwayのアーキテクチャ

Slide 5

Slide 5 text

文字列探索 アルゴリズム

Slide 6

Slide 6 text

文字列探索アルゴリズム • highwayが開発されたきっかけ • 世の中にはいろんなアルゴリズムがあります

Slide 7

Slide 7 text

文字列探索アルゴリズム • brute-force (総当り法) • Knuth-Morris-Pratt • Boyer-Moore (他にも派生アルゴリズムが沢山) • Aho-Corasick (占いで使ってたような?) • Rabin-Karp (Goのstring.Indexの実装) • Franek-Jennings-Smyth (highwayの実装)

Slide 8

Slide 8 text

FJSアルゴリズム • 考案者3人 Franek Jennings Smyth の頭文字 • KMPとBMのイイトコ取り • プリプロセスはO(m+α) • 検索は最良時O(n/m) 最悪時O(n+m) ※ m: パターン文字列の長さ n: 検索対象文字列の長さ α: アルファベット数

Slide 9

Slide 9 text

FJSアルゴリズム • FJSはKMPとBMの組み合わせ • KMPとBMを理解すればFJSも理解できる

Slide 10

Slide 10 text

KMPアルゴリズム • 考案者 Knuth-Morris-Pratt 3人の頭文字 • 「何文字目で不一致になったら何文字目から照合 を再開するか」というテーブルを事前に生成 • そのテーブルを参照しながらなるべく文字比較の 回数を少なくする • 一致しないとわかっている分は一気にスキップす る

Slide 11

Slide 11 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D A B C D A B D 0 1 2 3 4 5 6 X P

Slide 12

Slide 12 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D A B C D A B D 0 1 2 3 4 5 6 検索対象のテキスト X P

Slide 13

Slide 13 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D A B C D A B D 0 1 2 3 4 5 6 パターン X P

Slide 14

Slide 14 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D A B C D A B D 0 1 2 3 4 5 6 X P まずパターンから事前にテーブルを作っておきます。 テーブル生成の詳細は割愛しますが、次のようなテー ブルになります。 A B C D A B D 0 0 0 0 0 1 2

Slide 15

Slide 15 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D A B C D A B D 0 1 2 3 4 5 6 X P 先頭から順に照合していきます。 A B C D A B D 0 0 0 0 0 1 2

Slide 16

Slide 16 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D A B C D A B D 0 1 2 3 4 5 6 X P 先頭から順に照合していきます。 A B C D A B D 0 0 0 0 0 1 2

Slide 17

Slide 17 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D A B C D A B D 0 1 2 3 4 5 6 X P 先頭から順に照合していきます。 A B C D A B D 0 0 0 0 0 1 2

Slide 18

Slide 18 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D A B C D A B D 0 1 2 3 4 5 6 ここでX[3] != P[3]になりました。 X P A B C D A B D 0 0 0 0 0 1 2

Slide 19

Slide 19 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D A B C D A B D 0 1 2 3 4 5 6 これまでの文字比較でX[1]〜X[3]の間に’A’がないこと はわかっているので、次に’A’が現れる位置まで一気に 4文字スキップできることがわかります。 X P A B C D A B D 0 0 0 0 0 1 2

Slide 20

Slide 20 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D A B C D A B D 0 1 2 3 4 5 6 また、ここで不一致文字のDに注目して、テーブルを確 認してみるとその値は0となっています。 X P A B C D A B D 0 0 0 0 0 1 2

Slide 21

Slide 21 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D A B C D A B D 0 1 2 3 4 5 6 つまり4文字だけ右にスライドして、次の照合位置は 0文字目から、ということになります。 X P A B C D A B D 0 0 0 0 0 1 2

Slide 22

Slide 22 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D ということで、4文字ずらすとこうなります。 X P A B C D A B D 0 1 2 3 4 5 6 A B C D A B D 0 0 0 0 0 1 2

Slide 23

Slide 23 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D そしてまたPの0番目から照合を繰り返していきます。 X P A B C D A B D 0 1 2 3 4 5 6 A B C D A B D 0 0 0 0 0 1 2

Slide 24

Slide 24 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D そしてまたPの0番目から照合を繰り返していきます。 X P A B C D A B D 0 1 2 3 4 5 6 A B C D A B D 0 0 0 0 0 1 2

Slide 25

Slide 25 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D そしてまたPの0番目から照合を繰り返していきます。 X P A B C D A B D 0 1 2 3 4 5 6 A B C D A B D 0 0 0 0 0 1 2

Slide 26

Slide 26 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D そしてまたPの0番目から照合を繰り返していきます。 今度はDの位置でも一致しました。 X P A B C D A B D 0 1 2 3 4 5 6 A B C D A B D 0 0 0 0 0 1 2

Slide 27

Slide 27 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D X P A B C D A B D 0 1 2 3 4 5 6 そしてまたPの0番目から照合を繰り返していきます。 今度はDの位置でも一致しました。まだ先に進みます。 A B C D A B D 0 0 0 0 0 1 2

Slide 28

Slide 28 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D X P A B C D A B D 0 1 2 3 4 5 6 そしてまたPの0番目から照合を繰り返していきます。 今度はDの位置でも一致しました。まだ先に進みます。 A B C D A B D 0 0 0 0 0 1 2

Slide 29

Slide 29 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D ここでX[10] != P[6]が不一致になりました。 X P A B C D A B D 0 1 2 3 4 5 6 A B C D A B D 0 0 0 0 0 1 2

Slide 30

Slide 30 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D これまでの文字比較でX[8]に’A’が出てきているので、 そこまで一気にスキップできることがわかります。 X P A B C D A B D 0 1 2 3 4 5 6 A B C D A B D 0 0 0 0 0 1 2

Slide 31

Slide 31 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D また、ここでも不一致となった文字列Dに注目してテー ブルの値を確認すると2となっています。 X P A B C D A B D 0 1 2 3 4 5 6 A B C D A B D 0 0 0 0 0 1 2

Slide 32

Slide 32 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D ということで今回も一気に4文字スキップします。かつ 今度は2文字目からのチェックとなります。 X P A B C D A B D 0 1 2 3 4 5 6 A B C D A B D 0 0 0 0 0 1 2

Slide 33

Slide 33 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D X[10] != P[2] となりました。 X P A B C D A B D 0 1 2 3 4 5 6 A B C D A B D 0 0 0 0 0 1 2

Slide 34

Slide 34 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D 今までと同じく次にAが出現する位置まで一気に3文字 スキップできることは明らかです。 X P A B C D A B D 0 1 2 3 4 5 6 A B C D A B D 0 0 0 0 0 1 2

Slide 35

Slide 35 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D また、同じく不一致文字Cに注目してテーブルを確認す ると今度は0です。 X P A B C D A B D 0 1 2 3 4 5 6 A B C D A B D 0 0 0 0 0 1 2

Slide 36

Slide 36 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D ということで3文字ずらします。そして次は0文字目か らの照合になります。 X P A B C D A B D 0 1 2 3 4 5 6 A B C D A B D 0 0 0 0 0 1 2

Slide 37

Slide 37 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D また0文字目から照合を繰り返します... X P A B C D A B D 0 1 2 3 4 5 6 A B C D A B D 0 0 0 0 0 1 2

Slide 38

Slide 38 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D X P A B C D A B D 0 1 2 3 4 5 6 A B C D A B D 0 0 0 0 0 1 2 また0文字目から照合を繰り返します...

Slide 39

Slide 39 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D X P A B C D A B D 0 1 2 3 4 5 6 A B C D A B D 0 0 0 0 0 1 2 また0文字目から照合を繰り返します...

Slide 40

Slide 40 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D X P A B C D A B D 0 1 2 3 4 5 6 という風にして、全文字が一致するまで繰り返します。 A B C D A B D 0 0 0 0 0 1 2

Slide 41

Slide 41 text

KMPアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A B C A B C D A B A B C D A B C D A B D X P A B C D A B D 0 1 2 3 4 5 6 文字ずらしテーブルの生成方法は割愛しましたが、 テーブル生成方法はインターネットにサンプルがたく さんあるので興味があれば調べてみると面白いかも。 A B C D A B D 0 0 0 0 0 1 2

Slide 42

Slide 42 text

BMアルゴリズム • 考案者 Boyer-Moore 2人の頭文字 • 「どの文字で不一致になったら何文字ずらすか」 というテーブルを事前に生成 • パターンの末尾から照合していく

Slide 43

Slide 43 text

BMアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 g r e a t g r e p t h e h i g h w a y h i g h w a y 0 1 2 3 4 5 6 X P

Slide 44

Slide 44 text

BMアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 g r e a t g r e p t h e h i g h w a y h i g h w a y 0 1 2 3 4 5 6 X P KMP法と同じくBM法でも事前にテーブルを生成しま す。詳細は割愛しますが、この場合は右の様なテーブ ルとなります。 h i g h w a y 6 5 4 3 2 1 0

Slide 45

Slide 45 text

BMアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 g r e a t g r e p t h e h i g h w a y h i g h w a y 0 1 2 3 4 5 6 X P BM法はパターンの末尾から照合していきます。さっそ く不一致になりました。 h i g h w a y 6 5 4 3 2 1 0

Slide 46

Slide 46 text

BMアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 g r e a t g r e p t h e h i g h w a y h i g h w a y 0 1 2 3 4 5 6 X P 今回は検索対象文字列のgで不一致が起こっているので ここに注目します。テーブルを確認すると値は4です。 h i g h w a y 6 5 4 3 2 1 0

Slide 47

Slide 47 text

BMアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 g r e a t g r e p t h e h i g h w a y h i g h w a y 0 1 2 3 4 5 6 X P ということで4文字ずらします。 h i g h w a y 6 5 4 3 2 1 0

Slide 48

Slide 48 text

BMアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 g r e a t g r e p t h e h i g h w a y h i g h w a y 0 1 2 3 4 5 6 X P そしてまた末尾から照合をしていきます。また不一致で す。 h i g h w a y 6 5 4 3 2 1 0

Slide 49

Slide 49 text

BMアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 g r e a t g r e p t h e h i g h w a y h i g h w a y 0 1 2 3 4 5 6 X P 今度は”スペース”で不一致が起こりました。スペースは このテーブルに含まれないためパターン文字列長の7文 字分一気にずらします。 h i g h w a y 6 5 4 3 2 1 0

Slide 50

Slide 50 text

BMアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 g r e a t g r e p t h e h i g h w a y h i g h w a y 0 1 2 3 4 5 6 X P ということで7文字ずらしました。 h i g h w a y 6 5 4 3 2 1 0

Slide 51

Slide 51 text

BMアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 g r e a t g r e p t h e h i g h w a y h i g h w a y 0 1 2 3 4 5 6 X P 同じように末尾から照合しますが、またgで不一致とな ります。 h i g h w a y 6 5 4 3 2 1 0

Slide 52

Slide 52 text

BMアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 g r e a t g r e p t h e h i g h w a y h i g h w a y 0 1 2 3 4 5 6 X P 前回と同じように4文字ずらします。 h i g h w a y 6 5 4 3 2 1 0

Slide 53

Slide 53 text

BMアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 g r e a t g r e p t h e h i g h w a y h i g h w a y 0 1 2 3 4 5 6 X P 同じように末尾から照合していきます。 h i g h w a y 6 5 4 3 2 1 0

Slide 54

Slide 54 text

BMアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 g r e a t g r e p t h e h i g h w a y h i g h w a y 0 1 2 3 4 5 6 X P 同じように末尾から照合していきます。 h i g h w a y 6 5 4 3 2 1 0

Slide 55

Slide 55 text

BMアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 g r e a t g r e p t h e h i g h w a y h i g h w a y 0 1 2 3 4 5 6 X P 同じように末尾から照合していきます。 h i g h w a y 6 5 4 3 2 1 0

Slide 56

Slide 56 text

BMアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 g r e a t g r e p t h e h i g h w a y h i g h w a y 0 1 2 3 4 5 6 X P 同じように末尾から照合していきます。 h i g h w a y 6 5 4 3 2 1 0

Slide 57

Slide 57 text

BMアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 g r e a t g r e p t h e h i g h w a y h i g h w a y 0 1 2 3 4 5 6 X P 同じように末尾から照合していきます。あとはもう一致 しそうです。 h i g h w a y 6 5 4 3 2 1 0

Slide 58

Slide 58 text

BMアルゴリズム 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 g r e a t g r e p t h e h i g h w a y h i g h w a y 0 1 2 3 4 5 6 X P KMP法よりBM法の方がスキップできる文字数が大き く、さらに文字列に比較回数も少なくいことがわかり ます。 h i g h w a y 6 5 4 3 2 1 0

Slide 59

Slide 59 text

KMPとBM KMP BM 照合 先頭から 末尾から 不一致の際に 注目する箇所 パターン文字列の 不一致位置 検索対象文字列の 不一致文字 テーブルサイズ パターン文字列長 文字種類数

Slide 60

Slide 60 text

FJSアルゴリズム • 最初の1文字はBM法で照合する(つまり末尾から) • 不一致であればBMのテーブルに従ってパターン をずらしていく • 一致していれば今度はKMP法で照合する(つまり 先頭から)

Slide 61

Slide 61 text

FJSアルゴリズム • FJS考案者の1人JenningsがFJSについての解説サ イトを用意 • JavaアプレットでFJSの動きを見れる! http://www.cgjennings.ca/fjs/

Slide 62

Slide 62 text

マルチスレッド

Slide 63

Slide 63 text

マルチスレッド • メインスレッド x 1 • 検索用ワーカースレッド x 有効なCPU数 • 結果出力用スレッド x 1

Slide 64

Slide 64 text

main thread

Slide 65

Slide 65 text

worker worker worker main thread

Slide 66

Slide 66 text

main thread worker worker worker print

Slide 67

Slide 67 text

main thread worker worker worker print File Queue

Slide 68

Slide 68 text

main thread worker worker worker print File Queue ɾ main.c メインスレッドがカレントディレクトリから再帰的に検索対象 のファイルを探して、ファイルキューに追加していきます。

Slide 69

Slide 69 text

main thread worker worker worker print File Queue ɾ main.c ɾ main.h メインスレッドがカレントディレクトリから再帰的に検索対象 のファイルを探して、ファイルキューに追加していきます。

Slide 70

Slide 70 text

main thread worker worker worker print File Queue ɾ main.c ɾ main.h ɾ search.c メインスレッドがカレントディレクトリから再帰的に検索対象 のファイルを探して、ファイルキューに追加していきます。

Slide 71

Slide 71 text

main thread worker worker worker print File Queue ɾ main.c ɾ main.h ɾ search.c ɾ search.h メインスレッドがカレントディレクトリから再帰的に検索対象 のファイルを探して、ファイルキューに追加していきます。

Slide 72

Slide 72 text

main thread worker worker worker print File Queue ɾ main.c ɾ main.h ɾ search.c ɾ search.h ɾ regex.c メインスレッドがカレントディレクトリから再帰的に検索対象 のファイルを探して、ファイルキューに追加していきます。

Slide 73

Slide 73 text

main thread worker worker worker print File Queue ɾ main.c ɾ main.h ɾ search.c ɾ search.h ɾ regex.c 起動して準備ができた結果出力用スレッドがファイルキューの 先頭を参照します。ここではまだmain.cの検索が終わっていな いので、検索が完了するまでスレッドは待ち状態に入ります。

Slide 74

Slide 74 text

ɾ main thread worker worker worker print File Queue main.c ɾ main.h ɾ search.c ɾ search.h ɾ regex.c 同じように準備ができた検索用スレッドが一斉にキューの先頭 から検索を初めます。

Slide 75

Slide 75 text

ɾ main thread worker worker worker print File Queue main.c ɾ main.h ɾ search.c ɾ search.h ɾ regex.c ɾ regex.h 検索している間にもメインスレッドからファイルキューに追加 されていきます。

Slide 76

Slide 76 text

ɾ main thread worker worker worker print File Queue main.c ɾ main.h ɾ search.c ɾ search.h ɾ regex.c ɾ regex.h 検索が終わったら検索済みフラグを付けて次のファイルの検索 を初めます。

Slide 77

Slide 77 text

ɾ main thread worker worker worker print File Queue main.c ɾ main.h ɾ search.c ɾ search.h ɾ regex.c ɾ regex.h 検索が終わったら検索済みフラグを付けて次のファイルの検索 を初めます。

Slide 78

Slide 78 text

ɾ main thread worker worker worker print File Queue main.c ɾ main.h ɾ search.c ɾ search.h ɾ regex.c ɾ regex.h main.c main.h の結果を表示 結果出力用スレッドが参照していたキューのアイテムが検索済 みになったので、検索済みのアイテムを画面に出力します。そ してまた待ち状態となります。

Slide 79

Slide 79 text

ɾ main thread worker worker worker print File Queue main.c ɾ main.h ɾ search.c ɾ search.h ɾ regex.c ɾ regex.h main.c main.h の結果を表示 同じように検索が終わったら検索済みフラグを付けて次のファ イルの検索に進みます。

Slide 80

Slide 80 text

ɾ ɾ main thread worker worker worker print File Queue main.c ɾ main.h search.c ɾ search.h ɾ regex.c ɾ regex.h main.c main.h の結果を表示 同じように検索が終わったら検索済みフラグを付けて次のファ イルの検索に進みます。

Slide 81

Slide 81 text

ɾ ɾ main thread worker worker worker print File Queue main.c ɾ main.h search.c ɾ search.h ɾ regex.c ɾ regex.h main.c main.h の結果を表示 search.c search.h の結果を表示 同じように検索済みファイルの結果を出力します。これをファ イルキューがなくなるまで繰り返します。

Slide 82

Slide 82 text

ファイルの スキップ

Slide 83

Slide 83 text

ファイルのスキップ • ドットで始まる隠しファイル/ディレクトリの無視 • バイナリファイルの無視 • .gitignore内に記述されているパターンの無視

Slide 84

Slide 84 text

バイナリ判定 • ファイルの先頭512バイトを先読み • ヌルバイト(0x00)があればバイナリ! • UTF-8 / EUC-JP / ShiftJISに存在しないバイト列 が1割以上存在すればバイナリ!

Slide 85

Slide 85 text

.gitignoreパターン無視 /hw /tmp /tags patches build *.o .gitignore 高速にパターンをチェックするためにハッシュテーブルを使います。

Slide 86

Slide 86 text

.gitignoreパターン無視 B C /hw /tmp /tags patches build *.o .gitignore まずは.gitignoreからハッシュテーブルを構築していきます。

Slide 87

Slide 87 text

.gitignoreパターン無視 hw B C I /hw /tmp /tags patches build *.o .gitignore パターンの先頭文字をハッシュ値としてノードを追加していきます。

Slide 88

Slide 88 text

.gitignoreパターン無視 B C I U hw tmp /hw /tmp /tags patches build *.o .gitignore パターンの先頭文字をハッシュ値としてノードを追加していきます。

Slide 89

Slide 89 text

.gitignoreパターン無視 B C I U hw tags tmp /hw /tmp /tags patches build *.o .gitignore もちろん衝突するのでノードは単方向連結リストにしておきます。

Slide 90

Slide 90 text

.gitignoreパターン無視 B C I U Q hw tags tmp patches /hw /tmp /tags patches build *.o .gitignore もちろん衝突するのでノードは単方向連結リストにしておきます。

Slide 91

Slide 91 text

.gitignoreパターン無視 B C I U Q build hw tags tmp patches /hw /tmp /tags patches build *.o .gitignore もちろん衝突するのでノードは単方向連結リストにしておきます。

Slide 92

Slide 92 text

.gitignoreパターン無視 B C I U Q build hw tags tmp patches aclocal.m4 検索対象 ハッシュテーブルができたら次は検索対象ファイル名とのマッチング。

Slide 93

Slide 93 text

.gitignoreパターン無視 B C I U Q build hw tags tmp patches aclocal.m4 検索対象 ファイル名の先頭をハッシュ値としてノードを辿ります。aは空。

Slide 94

Slide 94 text

.gitignoreパターン無視 B C I U Q build hw tags tmp patches aclocal.m4 batch/ 検索対象 次、batchというディレクトリがきました。

Slide 95

Slide 95 text

.gitignoreパターン無視 B C I U Q build hw tags tmp patches aclocal.m4 batch/ 検索対象 同じように先頭文字を取ってノードを辿ります。

Slide 96

Slide 96 text

.gitignoreパターン無視 B C I U Q build hw tags tmp patches aclocal.m4 batch/ build/ 検索対象 次、buildというディレクトリがきました。

Slide 97

Slide 97 text

.gitignoreパターン無視 B C I U Q build hw tags tmp patches aclocal.m4 batch/ build/ 検索対象 同じように先頭文字を取ってノードを辿ります。

Slide 98

Slide 98 text

.gitignoreパターン無視 B C I U Q build hw tags tmp patches aclocal.m4 batch/ build/ 検索対象 マッチするので無視! するとbuildが見つかったので、buildは検索対象から除外します。

Slide 99

Slide 99 text

.gitignoreパターン無視 B C I U Q build hw tags tmp patches aclocal.m4 batch/ build/ tags/ 検索対象 マッチするので無視! 次、tagsというディレクトリがきたのでtを辿ります。

Slide 100

Slide 100 text

.gitignoreパターン無視 B C I U Q build hw tags tmp patches aclocal.m4 batch/ build/ tags/ 検索対象 マッチするので無視! 次、tagsというディレクトリがきたのでtを辿ります。

Slide 101

Slide 101 text

.gitignoreパターン無視 B C I U Q build hw tags tmp patches aclocal.m4 batch/ build/ tags/ 検索対象 マッチするので無視! マッチするので無視! tagsというノードがあったのでtagsは検索対象から除外します。

Slide 102

Slide 102 text

.gitignoreパターン無視 • 1つずつ比較するとパターンがn個あった時にO(n) • ハッシュテーブルを使うとほぼO(1) • メモリ食うけど • でも実際はglobフォーマット(*.cとか)なんかも含 まれることがあるし、もう少し複雑

Slide 103

Slide 103 text

ディスクI/O

Slide 104

Slide 104 text

ディスクI/O • 基本的にディスクI/Oはとても遅い! • 何度も呼び出すととても遅くなる • 改行コード単位で読み込むのは実装が簡単 • でも遅い • 100行のファイルなら100回のreadが発生する

Slide 105

Slide 105 text

ディスクI/O • 改行コードなんか気にしない • たとえば65536バイト(64KB)ずつまとめて読む • 100行のファイルでもだいたい1回のreadで済む • 改行コードとか探すのはメモリに読み込んだ後 • 実装は面倒くさいけど速い!

Slide 106

Slide 106 text

まとめ

Slide 107

Slide 107 text

まとめ • たぶん速い! • でもたぶん不安定! • 今後に期待!

Slide 108

Slide 108 text

おわり