MapReduce

セミナーでそれなりに気持ちが盛り上がったので、dRuby版をなんとなく動くようにしてみました。

ruby examples/word_count.rb -ts # TupleSpace
ruby examples/word_count.rb -m # Map
ruby examples/word_count.rb -m # Map
ruby examples/word_count.rb -r # Reduce
ruby examples/word_count.rb -r # Reduce
ruby examples/word_count.rb -r # Reduce

って感じでいっぱい立ち上げておいて

ruby examples/word_count.rb -d # Driver

と実行すると、結果が

[ ["", 3], ["But", 1], ["GET", 3], ["HTTP", 2], ["POST", 3], ["RESTful", 1], ["Rails", 1], ["a", 2], ["almost", 1], ["and", 3], ["are", 2], ["be", 1], ["browsers", 1], ["by", 1], ["can", 1], ["consider", 1], ["days", 1], ["developers", 1], ["do", 1], ["fact", 1], ["forgotten", 1], ["from", 1], ["if", 1], ["is", 1], ["many", 1], ["maybe", 1], ["more", 1], ["of", 2], ["often", 1], ["only", 1], ["requests", 2], ["shouldn\201ft", 1], ["support", 1], ["surprise", 1], ["that", 3], ["the", 1], ["then", 1], ["these", 1], ["this", 1], ["transmitted", 1], ["two", 1], ["types", 1], ["web", 1], ["you", 1] ]

こんな感じに。
なんとなくちゃんと動いてる気がする。


ユーザーコードは

require 'lib/rmapreduce'

module WordCount
  class Mapper < RMapReduce::Mapper
    def map(lines)
      result = Hash.new {0}
      lines.each do |line|
        line.split(/[\s.,:;]/).each do |word|
          result[word] += 1
        end
      end
      result.to_pair
    end
  end

  class Reducer < RMapReduce::Reducer
    def reduce(pairs)
      result = Hash.new {0}
      pairs.each do |pair|
        result[pair.key] += pair.value
      end
      result.to_pair
    end
  end
end

大体こんな感じ。(一部省略)


どうなんだろ。これMapReduceなんだろうか・・・。
元論文読まずにセミナー資料だけで適当に実装してるからよく分からん・・・。


もう少し確認用のexampleを追加して、ソースを整理したらRubyForgeかどっかで恥を晒そう。そのあとはSawzallっぽいDSLもつくってみようかな・・・。