Skip to content

Latest commit

 

History

History
106 lines (83 loc) · 3.6 KB

19.3.md

File metadata and controls

106 lines (83 loc) · 3.6 KB

19.3 大きめの例

アナグラムのコードをタスクとエージェントを使って書き直す

Kernel.to_char_list/1 が非推奨だったので Kernel.to_charlist/1 に変更した String.strip/1 が非推奨だったので String.trim/1 に変更した

goh@goh% iex tasks/anagrams.exs
Erlang/OTP 21 [erts-10.1.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe] [dtrace]

Interactive Elixir (1.7.4) - press Ctrl+C to exit (type h() ENTER for help)
> Dictionary.start_link
{:ok, #PID<0.108.0>}
> Enum.map(1..4, &"tasks/words/list#{&1}") |> WordlistLoader.load_from_files
[:ok, :ok, :ok, :ok]
> Dictionary.anagrams_of "organ"
["ronga", "rogan", "orang", "nagor", "groan", "grano", "goran", "argon",
 "angor"]

Dictionary.start_link/0 空のマップを初期値にしてプロセスを開始する

Dictionary.add_words(words)

  • words: 単語のリスト 単語を登録する 内部では do_add_words/2 を呼び出している

Dictionary.anagrams_of(word)

  • word: アナグラムの対象 指定した単語のアナグラムを取得する 内部では Map.get/2 を呼び出している Map.get/2 に第2引数は signature_of/1 の戻り値

Dictionary.do_add_words(map, words)

  • map: 辞書
  • words: 単語のリスト 単語のリストの要素を使って以下の関数を呼び出す
  • add_one_word(word, map)

Dictionary.add_one_word(word, map)

  • word: 単語リストの要素
  • map: 辞書 辞書(マップ)に以下の要素を追加する
  • key: signature_of(word) の戻り値
  • value: signature_of/1 の戻り値が同じ単語のリスト

Dictionary.signature_of(word) word に使われている文字を文字のリストに変換、ソート、連結して文字列化する


WordlistLoader.load_from_files(file_names)

  • file_names: ファイル名のリスト 各ファイルから単語を読み込む 内部では WordlistLoader.load_task/1 を呼び出している load_task/1 の引数は file_names の各ファイル名 Task.async/1load_task/1 を呼び出すことで、複数プロセスで処理させ、 Task.await/1 で回収している

`WordlistLoader.load_task(file_name)

  • file_name: ファイルの名前 指定されたファイルから単語を読み込み、辞書に登録する 1行ごとに読み込み、トリムし、 Dictionari.add_words/1 に渡している

分散させる

エージェントにグローバルでアクセスできる名前を付けるだけで、分散実行可能になる

ノード one

goh@goh% iex --sname one tasks/anagrams_dist.exs
Erlang/OTP 21 [erts-10.1.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe] [dtrace]

Interactive Elixir (1.7.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(one@goh)1> Node.list
[:two@goh]
iex(one@goh)2> Dictionary.start_link
{:ok, #PID<0.118.0>}
iex(one@goh)3> WordlistLoader.load_from_files(~w{tasks/words/list1 tasks/words/list2})
[:ok, :ok]
iex(one@goh)4> Dictionary.anagrams_of "argon"
["ronga", "rogan", "orang", "nagor", "groan", "grano", "goran", "argon",
 "angor"]

ノード two

goh@goh% iex --sname two tasks/anagrams_dist.exs
Erlang/OTP 21 [erts-10.1.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe] [dtrace]

Interactive Elixir (1.7.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(two@goh)1> Node.connect :one@goh
true
iex(two@goh)2> Node.list
[:one@goh]
iex(two@goh)3> WordlistLoader.load_from_files(~w{tasks/words/list3 tasks/words/list4})
[:ok, :ok]
iex(two@goh)4> Dictionary.anagrams_of "crate"
["recta", "react", "creta", "creat", "crate", "cater", "carte", "caret"]