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
|
nodeName() string
|
||||||
nodeID() int
|
nodeID() int
|
||||||
setIncludedBy(parser, *idSet)
|
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)
|
parse(Trace, *context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
118
store.go
118
store.go
@ -1,120 +1,82 @@
|
|||||||
package treerack
|
package treerack
|
||||||
|
|
||||||
type storeEntry struct {
|
|
||||||
match *idSet
|
|
||||||
noMatch *idSet
|
|
||||||
matches []int
|
|
||||||
all []int
|
|
||||||
}
|
|
||||||
|
|
||||||
type store struct {
|
type store struct {
|
||||||
entries []*storeEntry
|
noMatch []*idSet
|
||||||
}
|
match [][]int
|
||||||
|
|
||||||
func (s *store) getEntry(offset int) *storeEntry {
|
|
||||||
if len(s.entries) <= offset {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.entries[offset]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *store) hasNoMatch(offset, id int) bool {
|
func (s *store) hasNoMatch(offset, id int) bool {
|
||||||
e := s.getEntry(offset)
|
if len(s.noMatch) <= offset || s.noMatch[offset] == nil {
|
||||||
if e == nil {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return e.noMatch.has(id)
|
return s.noMatch[offset].has(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *store) getMatch(offset, id int) (int, bool, bool) {
|
func (s *store) getMatch(offset, id int) (int, bool, bool) {
|
||||||
e := s.getEntry(offset)
|
if s.hasNoMatch(offset, id) {
|
||||||
if e == nil {
|
|
||||||
return 0, false, false
|
|
||||||
}
|
|
||||||
|
|
||||||
if e.noMatch.has(id) {
|
|
||||||
return 0, false, true
|
return 0, false, true
|
||||||
}
|
}
|
||||||
|
|
||||||
if !e.match.has(id) {
|
if len(s.match) <= offset {
|
||||||
return 0, false, false
|
return 0, false, false
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(e.matches); i += 2 {
|
var (
|
||||||
if e.matches[i] == id {
|
found bool
|
||||||
return e.matches[i + 1], true, true
|
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) {
|
func (s *store) ensureOffset(offset int) {
|
||||||
if len(s.entries) > offset {
|
if len(s.match) > offset {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if cap(s.entries) > offset {
|
if cap(s.match) > offset {
|
||||||
s.entries = s.entries[:offset+1]
|
s.match = s.match[:offset+1]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
s.entries = s.entries[:cap(s.entries)]
|
s.match = s.match[:cap(s.match)]
|
||||||
for len(s.entries) <= offset {
|
for i := len(s.match); i <= offset; i++ {
|
||||||
s.entries = append(s.entries, nil)
|
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) {
|
func (s *store) setMatch(offset, id, to int) {
|
||||||
e := s.ensureEntry(offset)
|
s.ensureOffset(offset)
|
||||||
|
s.match[offset] = append(s.match[offset], id, to)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *store) setNoMatch(offset, id int) {
|
func (s *store) setNoMatch(offset, id int) {
|
||||||
e := s.ensureEntry(offset)
|
if len(s.noMatch) <= offset {
|
||||||
|
if cap(s.noMatch) > offset {
|
||||||
if e.match.has(id) {
|
s.noMatch = s.noMatch[:offset + 1]
|
||||||
return
|
} 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) {
|
s.noMatch[offset].set(id)
|
||||||
e := s.ensureEntry(offset)
|
|
||||||
e.all = append(e.all, id, to)
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user