generated from ipfs/ipfs-repository-template
-
Notifications
You must be signed in to change notification settings - Fork 77
/
taskmerger.go
87 lines (74 loc) · 2.43 KB
/
taskmerger.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
package decision
import (
"github.com/ipfs/go-peertaskqueue/peertask"
)
// taskData is extra data associated with each task in the request queue
type taskData struct {
// Tasks can be want-have or want-block
IsWantBlock bool
// Whether to immediately send a response if the block is not found
SendDontHave bool
// The size of the block corresponding to the task
BlockSize int
// Whether the block was found
HaveBlock bool
}
type taskMerger struct{}
func newTaskMerger() *taskMerger {
return &taskMerger{}
}
// The request queue uses this Method to decide if a newly pushed task has any
// new information beyond the tasks with the same Topic (CID) in the queue.
func (*taskMerger) HasNewInfo(task peertask.Task, existing []*peertask.Task) bool {
haveSize := false
isWantBlock := false
for _, et := range existing {
etd := et.Data.(*taskData)
if etd.HaveBlock {
haveSize = true
}
if etd.IsWantBlock {
isWantBlock = true
}
}
// If there is no active want-block and the new task is a want-block,
// the new task is better
newTaskData := task.Data.(*taskData)
if !isWantBlock && newTaskData.IsWantBlock {
return true
}
// If there is no size information for the CID and the new task has
// size information, the new task is better
if !haveSize && newTaskData.HaveBlock {
return true
}
return false
}
// The request queue uses Merge to merge a newly pushed task with an existing
// task with the same Topic (CID)
func (*taskMerger) Merge(task peertask.Task, existing *peertask.Task) {
newTask := task.Data.(*taskData)
existingTask := existing.Data.(*taskData)
// If we now have block size information, update the task with
// the new block size
if !existingTask.HaveBlock && newTask.HaveBlock {
existingTask.HaveBlock = newTask.HaveBlock
existingTask.BlockSize = newTask.BlockSize
}
// If replacing a want-have with a want-block
if !existingTask.IsWantBlock && newTask.IsWantBlock {
// Change the type from want-have to want-block
existingTask.IsWantBlock = true
// If the want-have was a DONT_HAVE, or the want-block has a size
if !existingTask.HaveBlock || newTask.HaveBlock {
// Update the entry size
existingTask.HaveBlock = newTask.HaveBlock
existing.Work = task.Work
}
}
// If the task is a want-block, make sure the entry size is equal
// to the block size (because we will send the whole block)
if existingTask.IsWantBlock && existingTask.HaveBlock {
existing.Work = existingTask.BlockSize
}
}