-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
120 lines (83 loc) · 2.24 KB
/
main.go
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package main
import (
"bufio"
"crypto/sha256"
"fmt"
"os"
"sync"
)
const parallelism = 8
type input struct {
Hash string
Word string
}
func main() {
theMap := &map[string]string{}
mapperChannel, mapperWaitGroup := startMapper(theMap)
hasherChannel, hashWaitGroup := startHashers(mapperChannel)
readerWaitGroup := startReaders(hasherChannel)
readerWaitGroup.Wait()
close(hasherChannel)
hashWaitGroup.Wait()
close(mapperChannel)
mapperWaitGroup.Wait()
for hash, word := range *theMap {
fmt.Println(hash, ":", word)
}
}
func startMapper(theMap *map[string]string) (chan *input, *sync.WaitGroup) {
mapperWaitGroup := &sync.WaitGroup{}
mapperChannel := make(chan *input)
mapperWaitGroup.Add(1)
go mapper(theMap, mapperChannel, mapperWaitGroup)
return mapperChannel, mapperWaitGroup
}
func mapper(theMap *map[string]string, mapperChannel chan *input, mapperWaitGroup *sync.WaitGroup) {
for input := range mapperChannel {
(*theMap)[input.Hash] = input.Word
}
mapperWaitGroup.Done()
}
func startHashers(mapperChannel chan *input) (chan string, *sync.WaitGroup) {
hasherWaitGroup := &sync.WaitGroup{}
hasherChannel := make(chan string)
for i := 0; i < parallelism; i++ {
hasherWaitGroup.Add(1)
go hasher(mapperChannel, hasherChannel, hasherWaitGroup)
}
return hasherChannel, hasherWaitGroup
}
func hasher(mapperChannel chan *input, hasherChannel chan string, hasherWaitGroup *sync.WaitGroup) {
for word := range hasherChannel {
hash := sha256.Sum256([]byte(word))
mapperChannel <- &input{
Hash: fmt.Sprintf("%x", hash),
Word: word,
}
}
hasherWaitGroup.Done()
}
func startReaders(hasherChannel chan string) *sync.WaitGroup {
readerWaitGroup := &sync.WaitGroup{}
// this would iterate over the files to be processed
for i := 0; i < parallelism; i++ {
readerWaitGroup.Add(1)
go reader(hasherChannel, readerWaitGroup, "/usr/share/dict/words")
}
return readerWaitGroup
}
func reader(hasherChannel chan string, readerWaitGroup *sync.WaitGroup, pathname string) {
reader, err := os.Open(pathname)
if err != nil {
panic(err)
}
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
err := scanner.Err()
if err != nil {
panic(err)
}
hasherChannel <- scanner.Text()
}
readerWaitGroup.Done()
}