simplify storage
This commit is contained in:
parent
ea01f81ef0
commit
b9f05bed7d
2
parse.go
2
parse.go
@ -15,7 +15,7 @@ type parser interface {
|
||||
nodeName() string
|
||||
nodeID() int
|
||||
setIncludedBy(parser, *idSet)
|
||||
storeIncluded(*context, int, int)
|
||||
storeIncluded(*context, int, int) // can be just an id set, taking what's excluded from the context
|
||||
parse(Trace, *context)
|
||||
}
|
||||
|
||||
|
118
store.go
118
store.go
@ -1,120 +1,82 @@
|
||||
package treerack
|
||||
|
||||
type storeEntry struct {
|
||||
match *idSet
|
||||
noMatch *idSet
|
||||
matches []int
|
||||
all []int
|
||||
}
|
||||
|
||||
type store struct {
|
||||
entries []*storeEntry
|
||||
}
|
||||
|
||||
func (s *store) getEntry(offset int) *storeEntry {
|
||||
if len(s.entries) <= offset {
|
||||
return nil
|
||||
}
|
||||
|
||||
return s.entries[offset]
|
||||
noMatch []*idSet
|
||||
match [][]int
|
||||
}
|
||||
|
||||
func (s *store) hasNoMatch(offset, id int) bool {
|
||||
e := s.getEntry(offset)
|
||||
if e == nil {
|
||||
if len(s.noMatch) <= offset || s.noMatch[offset] == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return e.noMatch.has(id)
|
||||
return s.noMatch[offset].has(id)
|
||||
}
|
||||
|
||||
func (s *store) getMatch(offset, id int) (int, bool, bool) {
|
||||
e := s.getEntry(offset)
|
||||
if e == nil {
|
||||
return 0, false, false
|
||||
}
|
||||
|
||||
if e.noMatch.has(id) {
|
||||
if s.hasNoMatch(offset, id) {
|
||||
return 0, false, true
|
||||
}
|
||||
|
||||
if !e.match.has(id) {
|
||||
if len(s.match) <= offset {
|
||||
return 0, false, false
|
||||
}
|
||||
|
||||
for i := 0; i < len(e.matches); i += 2 {
|
||||
if e.matches[i] == id {
|
||||
return e.matches[i + 1], true, true
|
||||
var (
|
||||
found bool
|
||||
length int
|
||||
)
|
||||
|
||||
for i := 0; i < len(s.match[offset]); i++ {
|
||||
if s.match[offset][i] != id {
|
||||
continue
|
||||
}
|
||||
|
||||
found = true
|
||||
if s.match[offset][i + 1] > length {
|
||||
length = s.match[offset][i + 1]
|
||||
}
|
||||
}
|
||||
|
||||
return 0, false, false
|
||||
return length, found, found
|
||||
}
|
||||
|
||||
func (s *store) ensureOffset(offset int) {
|
||||
if len(s.entries) > offset {
|
||||
if len(s.match) > offset {
|
||||
return
|
||||
}
|
||||
|
||||
if cap(s.entries) > offset {
|
||||
s.entries = s.entries[:offset+1]
|
||||
if cap(s.match) > offset {
|
||||
s.match = s.match[:offset+1]
|
||||
return
|
||||
}
|
||||
|
||||
s.entries = s.entries[:cap(s.entries)]
|
||||
for len(s.entries) <= offset {
|
||||
s.entries = append(s.entries, nil)
|
||||
s.match = s.match[:cap(s.match)]
|
||||
for i := len(s.match); i <= offset; i++ {
|
||||
s.match = append(s.match, nil)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *store) ensureEntry(offset int) *storeEntry {
|
||||
s.ensureOffset(offset)
|
||||
e := s.entries[offset]
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
e = &storeEntry{
|
||||
match: &idSet{},
|
||||
noMatch: &idSet{},
|
||||
}
|
||||
|
||||
s.entries[offset] = e
|
||||
return e
|
||||
}
|
||||
|
||||
func (s *store) setMatch(offset, id, to int) {
|
||||
e := s.ensureEntry(offset)
|
||||
|
||||
e.match.set(id)
|
||||
for i := 0; i < len(e.matches); i += 2 {
|
||||
if e.matches[i] == id {
|
||||
if to > e.matches[i + 1] {
|
||||
e.matches[i + 1] = to
|
||||
}
|
||||
|
||||
if to != e.matches[i + 1] {
|
||||
e.all = append(e.all, id, to)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
e.matches = append(e.matches, id, to)
|
||||
s.ensureOffset(offset)
|
||||
s.match[offset] = append(s.match[offset], id, to)
|
||||
}
|
||||
|
||||
func (s *store) setNoMatch(offset, id int) {
|
||||
e := s.ensureEntry(offset)
|
||||
|
||||
if e.match.has(id) {
|
||||
return
|
||||
if len(s.noMatch) <= offset {
|
||||
if cap(s.noMatch) > offset {
|
||||
s.noMatch = s.noMatch[:offset + 1]
|
||||
} else {
|
||||
s.noMatch = s.noMatch[:cap(s.noMatch)]
|
||||
for i := len(s.noMatch); i <= offset; i++ {
|
||||
s.noMatch = append(s.noMatch, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
e.noMatch.set(id)
|
||||
if s.noMatch[offset] == nil {
|
||||
s.noMatch[offset] = &idSet{}
|
||||
}
|
||||
|
||||
func (s *store) add(offset, id, to int) {
|
||||
e := s.ensureEntry(offset)
|
||||
e.all = append(e.all, id, to)
|
||||
s.noMatch[offset].set(id)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user