woodpecker/vendor/github.com/golangci/dupl/suffixtree/dupl.go
Lukas c28f7cb29f
Add golangci-lint (#502)
Initial part of #435
2021-11-14 21:01:54 +01:00

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
}