Upgrade to Pro — share decks privately, control downloads, hide ads and more …

architecture-of-highway

けんご
December 02, 2015

 architecture-of-highway

けんご

December 02, 2015
Tweet

More Decks by けんご

Other Decks in Technology

Transcript

  1. 2015.11.18
    @tkengo
    highway

    View Slide

  2. • ソースコード検索ツール。
    • マルチスレッドで動作。
    • たぶんだいぶ速い。
    • 詳しくはこちら

    http://tkengo.github.io/blog/2015/10/19/release-highway/
    highwayとは

    View Slide

  3. highwayの
    アーキテクチャ

    View Slide

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

    View Slide

  5. 文字列探索
    アルゴリズム

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  11. 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

    View Slide

  12. 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

    View Slide

  13. 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

    View Slide

  14. 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

    View Slide

  15. 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

    View Slide

  16. 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

    View Slide

  17. 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

    View Slide

  18. 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

    View Slide

  19. 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

    View Slide

  20. 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

    View Slide

  21. 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

    View Slide

  22. 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

    View Slide

  23. 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

    View Slide

  24. 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

    View Slide

  25. 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

    View Slide

  26. 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

    View Slide

  27. 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

    View Slide

  28. 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

    View Slide

  29. 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

    View Slide

  30. 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

    View Slide

  31. 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

    View Slide

  32. 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

    View Slide

  33. 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

    View Slide

  34. 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

    View Slide

  35. 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

    View Slide

  36. 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

    View Slide

  37. 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

    View Slide

  38. 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文字目から照合を繰り返します...

    View Slide

  39. 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文字目から照合を繰り返します...

    View Slide

  40. 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

    View Slide

  41. 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

    View Slide

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

    View Slide

  43. 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

    View Slide

  44. 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

    View Slide

  45. 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

    View Slide

  46. 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

    View Slide

  47. 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

    View Slide

  48. 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

    View Slide

  49. 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

    View Slide

  50. 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

    View Slide

  51. 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

    View Slide

  52. 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

    View Slide

  53. 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

    View Slide

  54. 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

    View Slide

  55. 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

    View Slide

  56. 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

    View Slide

  57. 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

    View Slide

  58. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  62. マルチスレッド

    View Slide

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

    View Slide

  64. main thread

    View Slide

  65. worker
    worker
    worker
    main thread

    View Slide

  66. main thread
    worker
    worker
    worker
    print

    View Slide

  67. main thread
    worker
    worker
    worker
    print
    File Queue

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  81. ɾ
    ɾ
    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
    の結果を表示
    同じように検索済みファイルの結果を出力します。これをファ
    イルキューがなくなるまで繰り返します。

    View Slide

  82. ファイルの
    スキップ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  103. ディスクI/O

    View Slide

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

    View Slide

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

    View Slide

  106. まとめ

    View Slide

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

    View Slide

  108. おわり

    View Slide