simplify storage

This commit is contained in:
Arpad Ryszka 2017-07-17 23:59:26 +02:00
parent ea01f81ef0
commit b9f05bed7d
2 changed files with 42 additions and 80 deletions

View File

@ -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)
}

120
store.go
View File

@ -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)
}