Comment detail

アクセスログのIPアドレスを逆引き (Nested Flatten)
ScalaといえばActorです。というわけでActor使ってます。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import java.net.{InetAddress, UnknownHostException}
import scala.collection.mutable.{HashMap, Queue}
import scala.io._
import java.io._
import scala.actors._
import scala.actors.Actor._

class Log(in:String, out:String, n:int){
  val outio = new BufferedWriter(new FileWriter(out))
  val inio  = new BufferedReader(new FileReader(in))
  var resolved = new HashMap[int, String]
  var writeQueue  = new Queue[int]
  val readers = (for(i <- 0 to n-1) yield new reader(i)).toArray
  var done = false

  val lookupCahce = new HashMap[String, String]
  def lookup(ip:String) = lookupCahce.getOrElseUpdate(ip, (try {
    InetAddress.getByName(ip).getHostName
  }catch {
    case _ => ip
  }))

  def process() = {
    done = false
    readers.foreach(x => {
      x.link(writer)
      x.trapExit = true
      x.start
      x ! 'resolve
    })
  }

  val writer:Actor = actor {
    loop {
      react {
        case 'write =>
          if(writeQueue.size > 0) {
            if(resolved.contains(writeQueue.front)) {
              val i = writeQueue.dequeue
              val line = resolved(i)
              resolved -= i 
              readers(i) ! 'resolve
              outio.write(line+"\n")
            }
            writer ! 'write
          }
          if(done && writeQueue.size == 1){
            outio.close; 
            exit
          }
      }
    }
  }

  class reader(i:int) extends Actor {
    def act() = loop {
      react {
        case 'resolve => 
          if(!done) {
            writeQueue += i
            val line = inio.readLine
            if(line != null) {
              val (ip::rest) = line.split(" ").toList
              resolved(i) = (lookup(ip)::rest).mkString(" ")
            }else {
              done = true
            }
            writer ! 'write
          }
        case Exit(_, _) => exit
      }
    }
  }
}

new Log("test.log", "testout.log", 20) process

Index

Feed

Other

Link

Pathtraq

loading...