/
batch_hasher.go
89 lines (70 loc) · 2.11 KB
/
batch_hasher.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
package batchhasher
import (
"runtime"
"strconv"
"github.com/loveandpeople/hive.go/batchworkerpool"
"github.com/loveandpeople/hive.go/ternary_mux"
"github.com/loveandpeople/lp.go/trinary"
)
const (
BatchedHasherQueueSize = 500
)
var (
BatchedHasherCount = runtime.NumCPU() * 2
)
type BatchHasher struct {
hashLength int
rounds int
workerPool *batchworkerpool.BatchWorkerPool
}
func NewBatchHasher(hashLength int, rounds int) (result *BatchHasher) {
result = &BatchHasher{
hashLength: hashLength,
rounds: rounds,
}
result.workerPool = batchworkerpool.New(result.processHashes, batchworkerpool.BatchSize(strconv.IntSize), batchworkerpool.WorkerCount(BatchedHasherCount), batchworkerpool.QueueSize(BatchedHasherQueueSize))
result.workerPool.Start()
return
}
func (this *BatchHasher) GetWorkerCount() int {
return this.workerPool.GetWorkerCount()
}
func (this *BatchHasher) GetBatchSize() int {
return this.workerPool.GetBatchSize()
}
func (this *BatchHasher) GetPendingQueueSize() int {
return this.workerPool.GetPendingQueueSize()
}
func (this *BatchHasher) Hash(trits trinary.Trits) trinary.Trits {
result, _ := this.workerPool.Submit(trits)
return (<-result).(trinary.Trits)
}
func (this *BatchHasher) processHashes(tasks []batchworkerpool.Task) {
if len(tasks) > 1 {
// multiplex the requests
multiplexer := ternary_mux.NewBCTernaryMultiplexer()
for _, hashRequest := range tasks {
multiplexer.Add(hashRequest.Param(0).(trinary.Trits))
}
bcTrits, err := multiplexer.Extract()
if err != nil {
panic(err)
}
// calculate the hash
bctCurl := NewBCTCurl(this.hashLength, this.rounds, strconv.IntSize)
bctCurl.Reset()
bctCurl.Absorb(bcTrits)
// extract the results from the demultiplexer
demux := ternary_mux.NewBCTernaryDemultiplexer(bctCurl.Squeeze(243))
for i, task := range tasks {
task.Return(demux.Get(i))
}
} else {
var resp = make(trinary.Trits, this.hashLength)
trits := tasks[0].Param(0).(trinary.Trits)
curl := NewCurl(this.hashLength, this.rounds)
curl.Absorb(trits, 0, len(trits))
curl.Squeeze(resp, 0, this.hashLength)
tasks[0].Return(resp)
}
}