mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-12-13 03:56:39 +00:00
c28f7cb29f
Initial part of #435
98 lines
1.7 KiB
Go
98 lines
1.7 KiB
Go
package suffixtree
|
|
|
|
import "sort"
|
|
|
|
type Match struct {
|
|
Ps []Pos
|
|
Len Pos
|
|
}
|
|
|
|
type posList struct {
|
|
positions []Pos
|
|
}
|
|
|
|
func newPosList() *posList {
|
|
return &posList{make([]Pos, 0)}
|
|
}
|
|
|
|
func (p *posList) append(p2 *posList) {
|
|
p.positions = append(p.positions, p2.positions...)
|
|
}
|
|
|
|
func (p *posList) add(pos Pos) {
|
|
p.positions = append(p.positions, pos)
|
|
}
|
|
|
|
type contextList struct {
|
|
lists map[int]*posList
|
|
}
|
|
|
|
func newContextList() *contextList {
|
|
return &contextList{make(map[int]*posList)}
|
|
}
|
|
|
|
func (c *contextList) getAll() []Pos {
|
|
keys := make([]int, 0, len(c.lists))
|
|
for k := range c.lists {
|
|
keys = append(keys, k)
|
|
}
|
|
sort.Ints(keys)
|
|
var ps []Pos
|
|
for _, k := range keys {
|
|
ps = append(ps, c.lists[k].positions...)
|
|
}
|
|
return ps
|
|
}
|
|
|
|
func (c *contextList) append(c2 *contextList) {
|
|
for lc, pl := range c2.lists {
|
|
if _, ok := c.lists[lc]; ok {
|
|
c.lists[lc].append(pl)
|
|
} else {
|
|
c.lists[lc] = pl
|
|
}
|
|
}
|
|
}
|
|
|
|
// FindDuplOver find pairs of maximal duplicities over a threshold
|
|
// length.
|
|
func (t *STree) FindDuplOver(threshold int) <-chan Match {
|
|
auxTran := newTran(0, 0, t.root)
|
|
ch := make(chan Match)
|
|
go func() {
|
|
walkTrans(auxTran, 0, threshold, ch)
|
|
close(ch)
|
|
}()
|
|
return ch
|
|
}
|
|
|
|
func walkTrans(parent *tran, length, threshold int, ch chan<- Match) *contextList {
|
|
s := parent.state
|
|
|
|
cl := newContextList()
|
|
|
|
if len(s.trans) == 0 {
|
|
pl := newPosList()
|
|
start := parent.end + 1 - Pos(length)
|
|
pl.add(start)
|
|
ch := 0
|
|
if start > 0 {
|
|
ch = s.tree.data[start-1].Val()
|
|
}
|
|
cl.lists[ch] = pl
|
|
return cl
|
|
}
|
|
|
|
for _, t := range s.trans {
|
|
ln := length + t.len()
|
|
cl2 := walkTrans(t, ln, threshold, ch)
|
|
if ln >= threshold {
|
|
cl.append(cl2)
|
|
}
|
|
}
|
|
if length >= threshold && len(cl.lists) > 1 {
|
|
m := Match{cl.getAll(), Pos(length)}
|
|
ch <- m
|
|
}
|
|
return cl
|
|
}
|