-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathneed.go
104 lines (92 loc) · 2.35 KB
/
need.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
package main
import (
"fmt"
"sort"
)
// This file implements a map[Mark]*Need that's easily clonable.
// Need must be immutable.
type Need struct {
tier int
mark Mark
entry *Entry // nil until the need is satisfied
}
type NeedMap struct {
indices []int
needs []*Need
}
func (this NeedMap) Get(key Mark) (val Need, ok bool) {
i := sort.SearchInts(this.indices, key.Index)
if i < len(this.indices) && this.indices[i] == key.Index {
return *(this.needs[i]), true
}
return Need{}, false
}
func (this *NeedMap) Put(key Mark, val Need) { // TODO: key == val.mark?
i := sort.SearchInts(this.indices, key.Index)
if i < len(this.indices) && this.indices[i] == key.Index {
this.needs[i] = &val
return
}
l := len(this.indices) + 1
newIndices := make([]int, l)
newNeeds := make([]*Need, l)
copy(newIndices, this.indices[0:i])
copy(newNeeds, this.needs[0:i])
newIndices[i] = key.Index
newNeeds[i] = &val
copy(newIndices[i+1:], this.indices[i:])
copy(newNeeds[i+1:], this.needs[i:])
this.indices = newIndices
this.needs = newNeeds
}
func (this NeedMap) SetTier(key Mark, tier int) {
val, ok := this.Get(key)
if !ok {
panic("Can't set tier")
}
val.tier = tier
this.Put(key, val)
}
func (this NeedMap) SetEntry(key Mark, entry *Entry) (ok bool) {
i := sort.SearchInts(this.indices, key.Index)
if i >= len(this.indices) && this.indices[i] != key.Index {
panic(fmt.Sprintf("Can't set entry %d:%s", key.Index, key.String()))
return false
}
old := this.needs[i]
this.needs[i] = &Need{old.tier, old.mark, entry}
return true
}
func (this NeedMap) Copy() NeedMap {
var that NeedMap
that.indices = make([]int, len(this.indices))
copy(that.indices, this.indices)
that.needs = make([]*Need, len(this.needs))
copy(that.needs, this.needs)
return that
}
func (this *NeedMap) All() []*Need {
return this.needs
}
func (this NeedMap) Len() int {
return len(this.needs)
}
// Returns a mark whose need has no entry
func (this NeedMap) TopMark() (Mark, bool) {
for _, n := range this.needs {
if n.entry == nil {
return n.mark, true
}
}
return Mark{}, false
}
func (this NeedMap) Rewrite(bind Bind) NeedMap {
var that NeedMap
that.indices = make([]int, 0, len(this.indices))
that.needs = make([]*Need, 0, len(this.needs))
for _, n := range this.needs {
newN := Need{n.tier, bind.Rewrite(n.mark), n.entry}
that.Put(newN.mark, newN)
}
return that
}