Comment detail

アクセスログのIPアドレスを逆引き (Nested Flatten)
並びをそのまま保つことに悩みました。。 今回の回答では、chanはブロックされることを利用してのq: array[4] of chan of chan of (string, string)がたぶん中心です。ブロックされるので順番になっているし、ブロック中にスレッドが動いているので並列化も。 最悪のケース(同じIPが4つ並んだ状態)では並列化の意味がなくなるのが悩みどころ。。
 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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
implement Resolv;

include "sys.m";
    sys: Sys;
    FD, print: import sys;
include "draw.m";
include "srv.m";
    srv: Srv;
include "hash.m";
    hash: Hash;
    HashTable, HashVal: import hash;
include "bufio.m";
    bufio: Bufio;
    Iobuf: import bufio;
include "string.m";
    str: String;

Resolv: module
{
    init: fn(ctxt: ref Draw->Context, argv: list of string);
};

dnsin: chan of (string, string);
q := array[4] of chan of chan of (string, string);    # DNS que
cache: ref HashTable;

init(nil: ref Draw->Context, nil: list of string)
{
    sys = load Sys Sys->PATH;
    srv = load Srv Srv->PATH;
    srv->init();
    hash = load Hash Hash->PATH;
    bufio = load Bufio Bufio->PATH;
    str = load String String->PATH;

    dnsin = chan of (string, string);
    for(i := 0; i < len q; i++)
        q[i] = chan of chan of (string, string);
    cache = hash->new(500);
    spawn dnstask();
    spawn readtask(sys->fildes(0));

    n := 0;
    for(;;){
        (addr, opt) := <- (<- q[n++ % len q]);
        if(addr == nil)
            break;
        print("%s%s\n", addr, opt);
    }
}

readtask(fd: ref FD)
{
    fin := bufio->fopen(fd, bufio->OREAD);
    if(fin == nil)
        raise "fopen";
    while((s := fin.gets('\n')) != nil){
        if(s[len s-1] == '\n')
            s = s[0:len s -1];
        dnsin <- = str->splitl(s, " ");
    }
    dnsin <- = (nil, nil);        # term
}

dnstask()
{
    n := 0;
    for(;;){
        (addr, opt) := <- dnsin;
        c := chan of (string, string);
        spawn dnsquery(c, addr, opt);
        q[n++ % len q] <- = c;
        if(addr == nil)
            break;
    }
}

dnsquery(c: chan of (string, string), addr, opt: string)
{
    if(addr == nil){
        c <- = (nil, nil);
        return;
    }

    v := cache.find(addr);
    if(v == nil){
        #sys->sleep(1000);
        v = ref HashVal;
        hosts := srv->ipa2h(addr);
        if(hosts == nil)
            v.s = addr;
        else
            v.s = hd hosts;
        cache.insert(addr, *v);
    }
    c <- = (v.s, opt);
}

Index

Feed

Other

Link

Pathtraq

loading...