use id based cache
This commit is contained in:
parent
50592ed83f
commit
baa2ceede8
8
char.go
8
char.go
@ -28,7 +28,7 @@ func newChar(
|
|||||||
|
|
||||||
func (p *charParser) nodeName() string { return p.name }
|
func (p *charParser) nodeName() string { return p.name }
|
||||||
func (p *charParser) nodeID() int { return p.id }
|
func (p *charParser) nodeID() int { return p.id }
|
||||||
func (p *charParser) setID(id int) { p.id = p.id }
|
func (p *charParser) setID(id int) { p.id = id }
|
||||||
|
|
||||||
func (p *charParser) parser(r *registry, parsers *idSet) (parser, error) {
|
func (p *charParser) parser(r *registry, parsers *idSet) (parser, error) {
|
||||||
if parsers.has(p.id) {
|
if parsers.has(p.id) {
|
||||||
@ -85,7 +85,7 @@ func (p *charParser) parse(t Trace, c *context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := c.fromStore(p.name); ok {
|
if _, ok := c.fromStore(p.id); ok {
|
||||||
// t.Out1("found in store, match:", m)
|
// t.Out1("found in store, match:", m)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -93,7 +93,7 @@ func (p *charParser) parse(t Trace, c *context) {
|
|||||||
if tok, ok := c.token(); ok && p.match(tok) {
|
if tok, ok := c.token(); ok && p.match(tok) {
|
||||||
// t.Out1("success", string(tok))
|
// t.Out1("success", string(tok))
|
||||||
n := newNode(p.name, p.id, c.offset, c.offset+1, p.commit)
|
n := newNode(p.name, p.id, c.offset, c.offset+1, p.commit)
|
||||||
c.store.set(c.offset, p.name, n)
|
c.store.set(c.offset, p.id, n)
|
||||||
for _, includedBy := range p.includedBy {
|
for _, includedBy := range p.includedBy {
|
||||||
includedBy.storeIncluded(c, n)
|
includedBy.storeIncluded(c, n)
|
||||||
}
|
}
|
||||||
@ -102,7 +102,7 @@ func (p *charParser) parse(t Trace, c *context) {
|
|||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
// t.Out1("fail", string(tok))
|
// t.Out1("fail", string(tok))
|
||||||
c.store.set(c.offset, p.name, nil)
|
c.store.set(c.offset, p.id, nil)
|
||||||
c.fail(c.offset)
|
c.fail(c.offset)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,7 @@ func (p *choiceParser) storeIncluded(c *context, n *Node) {
|
|||||||
|
|
||||||
nc := newNode(p.name, p.id, n.From, n.To, p.commit)
|
nc := newNode(p.name, p.id, n.From, n.To, p.commit)
|
||||||
nc.append(n)
|
nc.append(n)
|
||||||
c.store.set(nc.From, p.name, nc)
|
c.store.set(nc.From, p.id, nc)
|
||||||
|
|
||||||
for _, includedBy := range p.includedBy {
|
for _, includedBy := range p.includedBy {
|
||||||
includedBy.storeIncluded(c, nc)
|
includedBy.storeIncluded(c, nc)
|
||||||
@ -109,7 +109,7 @@ func (p *choiceParser) parse(t Trace, c *context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := c.fromStore(p.name); ok {
|
if _, ok := c.fromStore(p.id); ok {
|
||||||
// t.Out1("found in store, match:", m)
|
// t.Out1("found in store, match:", m)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -144,7 +144,7 @@ func (p *choiceParser) parse(t Trace, c *context) {
|
|||||||
node = newNode(p.name, p.id, c.offset, c.offset, p.commit)
|
node = newNode(p.name, p.id, c.offset, c.offset, p.commit)
|
||||||
node.append(c.node)
|
node.append(c.node)
|
||||||
|
|
||||||
c.store.set(node.From, p.name, node)
|
c.store.set(node.From, p.id, node)
|
||||||
for _, includedBy := range p.includedBy {
|
for _, includedBy := range p.includedBy {
|
||||||
includedBy.storeIncluded(c, node)
|
includedBy.storeIncluded(c, node)
|
||||||
}
|
}
|
||||||
@ -163,7 +163,7 @@ func (p *choiceParser) parse(t Trace, c *context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// t.Out1("fail")
|
// t.Out1("fail")
|
||||||
c.store.set(node.From, p.name, nil)
|
c.store.set(node.From, p.id, nil)
|
||||||
c.fail(node.From)
|
c.fail(node.From)
|
||||||
c.include(initialOffset, p.id) // TODO: test if can be optimized
|
c.include(initialOffset, p.id) // TODO: test if can be optimized
|
||||||
}
|
}
|
||||||
|
@ -104,8 +104,8 @@ func (c *context) include(offset int, id int) {
|
|||||||
c.isExcluded[offset].unset(id)
|
c.isExcluded[offset].unset(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) fromStore(name string) (bool, bool) {
|
func (c *context) fromStore(id int) (bool, bool) {
|
||||||
n, m, ok := c.store.get(c.offset, name)
|
n, m, ok := c.store.get(c.offset, id)
|
||||||
if !ok {
|
if !ok {
|
||||||
return false, false
|
return false, false
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ func (p *sequenceParser) storeIncluded(c *context, n *Node) {
|
|||||||
|
|
||||||
nc := newNode(p.name, p.id, n.From, n.To, p.commit)
|
nc := newNode(p.name, p.id, n.From, n.To, p.commit)
|
||||||
nc.append(n)
|
nc.append(n)
|
||||||
c.store.set(nc.From, p.name, nc)
|
c.store.set(nc.From, p.id, nc)
|
||||||
|
|
||||||
for _, includedBy := range p.includedBy {
|
for _, includedBy := range p.includedBy {
|
||||||
includedBy.storeIncluded(c, nc)
|
includedBy.storeIncluded(c, nc)
|
||||||
@ -145,7 +145,7 @@ func (p *sequenceParser) parse(t Trace, c *context) {
|
|||||||
node := newNode(p.name, p.id, c.offset, c.offset, p.commit)
|
node := newNode(p.name, p.id, c.offset, c.offset, p.commit)
|
||||||
|
|
||||||
for len(items) > 0 {
|
for len(items) > 0 {
|
||||||
m, ok := c.fromStore(items[0].nodeName())
|
m, ok := c.fromStore(items[0].nodeID())
|
||||||
if ok {
|
if ok {
|
||||||
// t.Out1("sequence item found in store, match:", m, items[0].nodeName(), c.offset)
|
// t.Out1("sequence item found in store, match:", m, items[0].nodeName(), c.offset)
|
||||||
} else {
|
} else {
|
||||||
@ -156,7 +156,7 @@ func (p *sequenceParser) parse(t Trace, c *context) {
|
|||||||
if !m {
|
if !m {
|
||||||
if currentCount < ranges[0][0] {
|
if currentCount < ranges[0][0] {
|
||||||
// t.Out1("fail, item failed")
|
// t.Out1("fail, item failed")
|
||||||
c.store.set(node.From, p.name, nil)
|
c.store.set(node.From, p.id, nil)
|
||||||
c.fail(node.From)
|
c.fail(node.From)
|
||||||
c.include(initialOffset, p.id)
|
c.include(initialOffset, p.id)
|
||||||
return
|
return
|
||||||
@ -182,7 +182,7 @@ func (p *sequenceParser) parse(t Trace, c *context) {
|
|||||||
|
|
||||||
// t.Out1("success, items parsed")
|
// t.Out1("success, items parsed")
|
||||||
|
|
||||||
c.store.set(node.From, p.name, node)
|
c.store.set(node.From, p.id, node)
|
||||||
for _, includedBy := range p.includedBy {
|
for _, includedBy := range p.includedBy {
|
||||||
includedBy.storeIncluded(c, node)
|
includedBy.storeIncluded(c, node)
|
||||||
}
|
}
|
||||||
|
86
store.go
86
store.go
@ -1,91 +1,83 @@
|
|||||||
package treerack
|
package treerack
|
||||||
|
|
||||||
type storedItem struct {
|
|
||||||
name string
|
|
||||||
node *Node
|
|
||||||
}
|
|
||||||
|
|
||||||
type storeEntry struct {
|
type storeEntry struct {
|
||||||
match []*storedItem
|
match *idSet
|
||||||
noMatch []string
|
noMatch *idSet
|
||||||
|
nodes []*Node
|
||||||
}
|
}
|
||||||
|
|
||||||
type store struct {
|
type store struct {
|
||||||
tokens []*storeEntry
|
entries []*storeEntry
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *store) get(offset int, name string) (*Node, bool, bool) {
|
func (c *store) get(offset int, id int) (*Node, bool, bool) {
|
||||||
if len(c.tokens) <= offset {
|
if len(c.entries) <= offset {
|
||||||
return nil, false, false
|
return nil, false, false
|
||||||
}
|
}
|
||||||
|
|
||||||
tc := c.tokens[offset]
|
tc := c.entries[offset]
|
||||||
if tc == nil {
|
if tc == nil {
|
||||||
return nil, false, false
|
return nil, false, false
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, i := range tc.noMatch {
|
if tc.noMatch.has(id) {
|
||||||
if i == name {
|
return nil, false, true
|
||||||
return nil, false, true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, i := range tc.match {
|
if !tc.match.has(id) {
|
||||||
if i.name == name {
|
return nil, false, false
|
||||||
return i.node, true, true
|
}
|
||||||
|
|
||||||
|
for _, n := range tc.nodes {
|
||||||
|
if n.id == id {
|
||||||
|
return n, true, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, false, false
|
return nil, false, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *store) set(offset int, name string, n *Node) {
|
func (c *store) set(offset int, id int, n *Node) {
|
||||||
var tc *storeEntry
|
var tc *storeEntry
|
||||||
if len(c.tokens) > offset {
|
if len(c.entries) > offset {
|
||||||
tc = c.tokens[offset]
|
tc = c.entries[offset]
|
||||||
} else {
|
} else {
|
||||||
if cap(c.tokens) > offset {
|
if cap(c.entries) > offset {
|
||||||
c.tokens = c.tokens[:offset+1]
|
c.entries = c.entries[:offset+1]
|
||||||
} else {
|
} else {
|
||||||
c.tokens = c.tokens[:cap(c.tokens)]
|
c.entries = c.entries[:cap(c.entries)]
|
||||||
for len(c.tokens) <= offset {
|
for len(c.entries) <= offset {
|
||||||
c.tokens = append(c.tokens, nil)
|
c.entries = append(c.entries, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tc = &storeEntry{}
|
tc = &storeEntry{
|
||||||
c.tokens[offset] = tc
|
match: &idSet{},
|
||||||
|
noMatch: &idSet{},
|
||||||
|
}
|
||||||
|
|
||||||
|
c.entries[offset] = tc
|
||||||
}
|
}
|
||||||
|
|
||||||
if n == nil {
|
if n == nil {
|
||||||
for _, i := range tc.match {
|
if tc.match.has(id) {
|
||||||
if i.name == name {
|
return
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, i := range tc.noMatch {
|
tc.noMatch.set(id)
|
||||||
if i == name {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tc.noMatch = append(tc.noMatch, name)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, i := range tc.match {
|
tc.match.set(id)
|
||||||
if i.name == name {
|
for i, ni := range tc.nodes {
|
||||||
if n.tokenLength() > i.node.tokenLength() {
|
if ni.id == id {
|
||||||
i.node = n
|
if n.tokenLength() > ni.tokenLength() {
|
||||||
|
tc.nodes[i] = n
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tc.match = append(tc.match, &storedItem{
|
tc.nodes = append(tc.nodes, n)
|
||||||
name: name,
|
|
||||||
node: n,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user