treerack/results.go

177 lines
3.1 KiB
Go
Raw Normal View History

2017-07-15 21:49:08 +02:00
package treerack
2017-06-25 17:51:08 +02:00
2017-11-02 20:49:49 +01:00
type results struct {
2017-07-17 23:59:26 +02:00
noMatch []*idSet
match [][]int
2017-07-17 21:58:03 +02:00
}
func (r *results) ensureOffset(offset int) {
if len(r.match) > offset {
return
2017-06-25 17:51:08 +02:00
}
if cap(r.match) > offset {
r.match = r.match[:offset+1]
return
2017-07-15 23:00:43 +02:00
}
r.match = r.match[:cap(r.match)]
for i := len(r.match); i <= offset; i++ {
r.match = append(r.match, nil)
}
}
2017-07-17 23:59:26 +02:00
func (r *results) setMatch(offset, id, to int) {
r.ensureOffset(offset)
2017-11-06 11:14:28 +01:00
for i := 0; i < len(r.match[offset]); i += 2 {
if r.match[offset][i] != id || r.match[offset][i+1] != to {
2017-07-17 23:59:26 +02:00
continue
}
return
2017-06-25 17:51:08 +02:00
}
r.match[offset] = append(r.match[offset], id, to)
2017-07-29 18:40:22 +02:00
}
func (r *results) setNoMatch(offset, id int) {
if len(r.match) > offset {
for i := 0; i < len(r.match[offset]); i += 2 {
if r.match[offset][i] != id {
continue
}
return
}
}
if len(r.noMatch) <= offset {
if cap(r.noMatch) > offset {
r.noMatch = r.noMatch[:offset+1]
} else {
r.noMatch = r.noMatch[:cap(r.noMatch)]
for i := cap(r.noMatch); i <= offset; i++ {
r.noMatch = append(r.noMatch, nil)
}
}
}
if r.noMatch[offset] == nil {
r.noMatch[offset] = &idSet{}
2017-07-30 02:35:51 +02:00
}
r.noMatch[offset].set(id)
}
func (r *results) hasMatchTo(offset, id, to int) bool {
if len(r.match) <= offset {
2017-07-30 02:35:51 +02:00
return false
}
for i := 0; i < len(r.match[offset]); i += 2 {
if r.match[offset][i] != id {
2017-07-30 02:35:51 +02:00
continue
}
if r.match[offset][i+1] == to {
2017-07-30 02:35:51 +02:00
return true
}
2017-07-29 18:40:22 +02:00
}
2017-07-30 02:35:51 +02:00
return false
}
func (r *results) longestMatch(offset, id int) (int, bool) {
if len(r.match) <= offset {
2017-07-29 18:40:22 +02:00
return 0, false
}
var found bool
to := -1
for i := 0; i < len(r.match[offset]); i += 2 {
if r.match[offset][i] != id {
2017-07-29 18:40:22 +02:00
continue
}
if r.match[offset][i+1] > to {
to = r.match[offset][i+1]
2017-07-29 18:40:22 +02:00
}
2017-10-28 16:54:06 +02:00
found = true
2017-07-29 18:40:22 +02:00
}
return to, found
2017-06-25 17:51:08 +02:00
}
func (r *results) longestResult(offset, id int) (int, bool, bool) {
if len(r.noMatch) > offset && r.noMatch[offset] != nil && r.noMatch[offset].has(id) {
return 0, false, true
2017-07-16 23:15:42 +02:00
}
to, ok := r.longestMatch(offset, id)
return to, ok, ok
2017-07-16 23:15:42 +02:00
}
func (r *results) dropMatchTo(offset, id, to int) {
for i := 0; i < len(r.match[offset]); i += 2 {
if r.match[offset][i] != id {
2017-07-30 02:35:51 +02:00
continue
}
if r.match[offset][i+1] == to {
r.match[offset][i] = -1
2017-07-30 02:35:51 +02:00
return
}
}
2017-07-16 23:15:42 +02:00
}
2017-11-06 11:14:28 +01:00
func (c *context) resetPending() {
c.isPending = nil
}
func (c *context) pending(offset, id int) bool {
if len(c.isPending) <= id {
return false
}
for i := range c.isPending[id] {
if c.isPending[id][i] == offset {
return true
}
}
return false
}
func (c *context) markPending(offset, id int) {
if len(c.isPending) <= id {
if cap(c.isPending) > id {
c.isPending = c.isPending[:id+1]
} else {
c.isPending = c.isPending[:cap(c.isPending)]
for i := cap(c.isPending); i <= id; i++ {
c.isPending = append(c.isPending, nil)
}
}
}
for i := range c.isPending[id] {
if c.isPending[id][i] == -1 {
c.isPending[id][i] = offset
return
}
}
c.isPending[id] = append(c.isPending[id], offset)
}
func (c *context) unmarkPending(offset, id int) {
for i := range c.isPending[id] {
if c.isPending[id][i] == offset {
c.isPending[id][i] = -1
break
}
}
}