-
Notifications
You must be signed in to change notification settings - Fork 0
/
yi2.v
106 lines (93 loc) · 2.34 KB
/
yi2.v
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
98
99
100
101
102
103
104
105
106
import io { new_buffered_reader }
import math { min, max }
import os
import runtime { nr_cpus }
import time { now }
const t_start = now()
const worker = nr_cpus()
const fname = '/tmp/measurements.txt'
struct Station {
min f64
max f64
sum f64
count i64
}
fn main() {
if !os.exists(fname) { panic('file not exists!') }
fsize := i64(os.file_size(fname))
chunk_size := (fsize + worker - 1) / worker
// println( '$fsize : $chunk_size' )
mut i := 1
mut chunks := [ i64(0) ]
mut fp := os.open_file(fname, 'r')!
for {
len := chunk_size * i
mut br := io.new_buffered_reader(reader: fp)
fp.seek(len, .start)!
line := br.read_line()!
// println('i=$i, $line')
chunks << len + line.len + 1
i++
if i == worker { break }
}
chunks << fsize
fp.close()
// println(chunks.str())
i = 0
mut threads := []thread map[string]Station{}
for {
threads << spawn process_chunk(chunks[i], chunks[i+1])
i++
if worker == i { break }
}
mut res := threads.wait()
mut stations := map[string]Station{}
for re in res {
for city, val in re {
entry := stations[city] or {
stations[city] = val
continue
}
stations[city] = Station{
min(val.min, entry.min),
max(val.max, entry.max),
val.sum + entry.sum,
val.count + entry.count }
}
}
mut sorted_keys := stations.keys()
sorted_keys.sort_ignore_case()
for city in sorted_keys {
re := stations[city]
println('${city} : ${re.min} , ${re.max} , ${re.sum / re.count} , ${re.count}')
}
println('city number : ${sorted_keys.len}')
println( now() - t_start )
}
fn process_chunk(begin i64, end i64) map[string]Station {
mut stations := map[string]Station{}
mut fp := os.open_file(fname, 'r') or { return stations }
fp.seek(begin, .start) or { return stations }
mut current := begin
mut br := io.new_buffered_reader(reader: fp)
for {
if current >= end { break }
line := br.read_line() or { break }
data := line.split(';')
city := data[0]
temp := data[1].f64()
current += line.len + 1
re := stations[city] or {
stations[city] = Station{temp, temp, temp, 1}
continue
}
stations[city] = Station{
min(temp, re.min),
max(temp, re.max),
re.sum + temp,
re.count + 1}
}
fp.close()
println( now() - t_start )
return stations
}