simplify build time pending check

This commit is contained in:
Arpad Ryszka 2017-11-06 11:14:28 +01:00
parent 79fa303bed
commit 1ed65518e6
8 changed files with 66 additions and 106 deletions

View File

@ -52,9 +52,10 @@ precommit: fmt build check-full
clean: clean:
@rm -f *.test @rm -f *.test
@rm -f cpu.out @rm -f cpu.out
@rm -f .coverprofile
@go clean -i ./... @go clean -i ./...
ci-trigger: deps build check-full check-fmt ci-trigger: deps check-fmt build check-full
ifeq ($(TRAVIS_BRANCH)_$(TRAVIS_PULL_REQUEST), master_false) ifeq ($(TRAVIS_BRANCH)_$(TRAVIS_PULL_REQUEST), master_false)
make publish-coverage make publish-coverage
endif endif

View File

@ -204,11 +204,11 @@ func (b *choiceBuilder) build(c *context) ([]*Node, bool) {
if parsed { if parsed {
c.results.dropMatchTo(c.offset, b.id, to) c.results.dropMatchTo(c.offset, b.id, to)
} else { } else {
if c.buildPending(c.offset, b.id, to) { if c.pending(c.offset, b.id) {
return nil, false return nil, false
} }
c.markBuildPending(c.offset, b.id, to) c.markPending(c.offset, b.id)
} }
var option builder var option builder
@ -221,7 +221,7 @@ func (b *choiceBuilder) build(c *context) ([]*Node, bool) {
n, _ := option.build(c) n, _ := option.build(c)
if !parsed { if !parsed {
c.unmarkBuildPending(from, b.id, to) c.unmarkPending(from, b.id)
} }
if b.commit&Alias != 0 { if b.commit&Alias != 0 {

View File

@ -63,101 +63,6 @@ func (c *context) token() (rune, bool) {
return c.tokens[c.offset], true return c.tokens[c.offset], true
} }
func (c *context) pending(offset, id int) bool {
if len(c.isPending) <= id {
return false
}
for i := range c.isPending[id] {
if c.isPending[id][i] == offset {
return true
}
}
return false
}
func (c *context) markPending(offset, id int) {
if len(c.isPending) <= id {
if cap(c.isPending) > id {
c.isPending = c.isPending[:id+1]
} else {
c.isPending = c.isPending[:cap(c.isPending)]
for i := cap(c.isPending); i <= id; i++ {
c.isPending = append(c.isPending, nil)
}
}
}
for i := range c.isPending[id] {
if c.isPending[id][i] == -1 {
c.isPending[id][i] = offset
return
}
}
c.isPending[id] = append(c.isPending[id], offset)
}
func (c *context) unmarkPending(offset, id int) {
for i := range c.isPending[id] {
if c.isPending[id][i] == offset {
c.isPending[id][i] = -1
break
}
}
}
func (c *context) resetPending() {
c.isPending = nil
}
func (c *context) buildPending(offset, id, to int) bool {
if len(c.isPending) <= id {
return false
}
for i := 0; i < len(c.isPending[id]); i += 2 {
if c.isPending[id][i] == offset && c.isPending[id][i+1] == to {
return true
}
}
return false
}
func (c *context) markBuildPending(offset, id, to int) {
if len(c.isPending) <= id {
if cap(c.isPending) > id {
c.isPending = c.isPending[:id+1]
} else {
c.isPending = c.isPending[:cap(c.isPending)]
for i := cap(c.isPending); i <= id; i++ {
c.isPending = append(c.isPending, nil)
}
}
}
for i := 0; i < len(c.isPending[id]); i += 2 {
if c.isPending[id][i] == -1 {
c.isPending[id][i] = offset
c.isPending[id][i+1] = to
return
}
}
c.isPending[id] = append(c.isPending[id], offset, to)
}
func (c *context) unmarkBuildPending(offset, id, to int) {
for i := 0; i < len(c.isPending[id]); i += 2 {
if c.isPending[id][i] == offset && c.isPending[id][i+1] == to {
c.isPending[id][i] = -1
break
}
}
}
func (c *context) fromResults(id int) bool { func (c *context) fromResults(id int) bool {
to, m, ok := c.results.longestResult(c.offset, id) to, m, ok := c.results.longestResult(c.offset, id)
if !ok { if !ok {
@ -173,6 +78,11 @@ func (c *context) fromResults(id int) bool {
return true return true
} }
// TODO:
// - try to move this to the parsers
// - try to move more
// - if doens't help performance, try move more from there to here
func (c *context) success(to int) { func (c *context) success(to int) {
c.offset = to c.offset = to
c.matchLast = true c.matchLast = true

View File

@ -86,11 +86,11 @@ func TestPendingWithinCap(t *testing.T) {
t.Run("parse", func(t *testing.T) { t.Run("parse", func(t *testing.T) {
for i := 0; i < 16; i++ { for i := 0; i < 16; i++ {
c.markBuildPending(0, i, 0) c.markPending(0, i)
} }
for i := 0; i < 16; i++ { for i := 0; i < 16; i++ {
if !c.buildPending(0, i, 0) { if !c.pending(0, i) {
t.Error("failed to mark build pending") t.Error("failed to mark build pending")
} }
} }

View File

@ -4,6 +4,7 @@ error reporting
- print the line - print the line
- print the deepest non-alias node name - print the deepest non-alias node name
- print the documentation of the node name - print the documentation of the node name
- make it work with custom tokens
read, with error reporting read, with error reporting
what was the bug with the large json from eskip? what was the bug with the large json from eskip?

View File

@ -5,7 +5,6 @@ type registry struct {
ids map[string]int ids map[string]int
names map[int]string names map[int]string
definitions map[string]definition definitions map[string]definition
parsers map[string]parser
} }
func newRegistry(defs ...definition) *registry { func newRegistry(defs ...definition) *registry {
@ -13,7 +12,6 @@ func newRegistry(defs ...definition) *registry {
ids: make(map[string]int), ids: make(map[string]int),
names: make(map[int]string), names: make(map[int]string),
definitions: make(map[string]definition), definitions: make(map[string]definition),
parsers: make(map[string]parser),
} }
for _, def := range defs { for _, def := range defs {

View File

@ -23,6 +23,7 @@ func (r *results) ensureOffset(offset int) {
func (r *results) setMatch(offset, id, to int) { func (r *results) setMatch(offset, id, to int) {
r.ensureOffset(offset) r.ensureOffset(offset)
for i := 0; i < len(r.match[offset]); i += 2 { for i := 0; i < len(r.match[offset]); i += 2 {
if r.match[offset][i] != id || r.match[offset][i+1] != to { if r.match[offset][i] != id || r.match[offset][i+1] != to {
continue continue
@ -124,3 +125,52 @@ func (r *results) dropMatchTo(offset, id, to int) {
} }
} }
} }
func (c *context) resetPending() {
c.isPending = nil
}
func (c *context) pending(offset, id int) bool {
if len(c.isPending) <= id {
return false
}
for i := range c.isPending[id] {
if c.isPending[id][i] == offset {
return true
}
}
return false
}
func (c *context) markPending(offset, id int) {
if len(c.isPending) <= id {
if cap(c.isPending) > id {
c.isPending = c.isPending[:id+1]
} else {
c.isPending = c.isPending[:cap(c.isPending)]
for i := cap(c.isPending); i <= id; i++ {
c.isPending = append(c.isPending, nil)
}
}
}
for i := range c.isPending[id] {
if c.isPending[id][i] == -1 {
c.isPending[id][i] = offset
return
}
}
c.isPending[id] = append(c.isPending[id], offset)
}
func (c *context) unmarkPending(offset, id int) {
for i := range c.isPending[id] {
if c.isPending[id][i] == offset {
c.isPending[id][i] = -1
break
}
}
}

View File

@ -258,11 +258,11 @@ func (b *sequenceBuilder) build(c *context) ([]*Node, bool) {
} else if parsed { } else if parsed {
c.results.dropMatchTo(c.offset, b.id, to) c.results.dropMatchTo(c.offset, b.id, to)
} else { } else {
if c.buildPending(c.offset, b.id, to) { if c.pending(c.offset, b.id) {
return nil, false return nil, false
} }
c.markBuildPending(c.offset, b.id, to) c.markPending(c.offset, b.id)
} }
var ( var (
@ -303,7 +303,7 @@ func (b *sequenceBuilder) build(c *context) ([]*Node, bool) {
} }
if !parsed { if !parsed {
c.unmarkBuildPending(from, b.id, to) c.unmarkPending(from, b.id)
} }
if b.commit&Alias != 0 { if b.commit&Alias != 0 {