Skip to content

Commit

Permalink
Only track contexts if needed
Browse files Browse the repository at this point in the history
This turns out to be relatively expensive, only allocate memory and
test all conditions if needed.
  • Loading branch information
hahnjo committed Jul 21, 2019
1 parent 7463087 commit c6fe99c
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 26 deletions.
58 changes: 32 additions & 26 deletions pkg/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,18 @@ func applyAppend(r Recipe, modified []byte) []byte {
func ApplyToInput(r Recipe, input []byte) []byte {
inLen := len(input)

// A rule is active iff there is no begin pattern for a context.
deleteActive := make([]bool, len(r.Delete))
replaceActive := make([]bool, len(r.Replace))
for idx, d := range r.Delete {
deleteActive[idx] = (d.Context.BeginRegexp == nil)
}
for idx, r := range r.Replace {
replaceActive[idx] = (r.Context.BeginRegexp == nil)
deleteActive := []bool(nil)
replaceActive := []bool(nil)
if r.hasContext {
// A rule is active iff there is no begin pattern for a context.
deleteActive = make([]bool, len(r.Delete))
replaceActive = make([]bool, len(r.Replace))
for idx, d := range r.Delete {
deleteActive[idx] = (d.Context.BeginRegexp == nil)
}
for idx, r := range r.Replace {
replaceActive[idx] = (r.Context.BeginRegexp == nil)
}
}

modified := make([]byte, 0)
Expand All @@ -87,36 +91,38 @@ func ApplyToInput(r Recipe, input []byte) []byte {
next++
}

// For each delete and replace, check if the context begins or ends.
for idx, d := range r.Delete {
c := d.Context
if !deleteActive[idx] && c.BeginRegexp != nil && c.BeginRegexp.Match(line) {
deleteActive[idx] = true
}
if deleteActive[idx] && c.EndRegexp != nil && c.EndRegexp.Match(line) {
deleteActive[idx] = false
}
}
for idx, sr := range r.Replace {
c := sr.Context
if !replaceActive[idx] && c.BeginRegexp != nil && c.BeginRegexp.Match(line) {
replaceActive[idx] = true
if r.hasContext {
// For each delete and replace, check if the context begins or ends.
for idx, d := range r.Delete {
c := d.Context
if !deleteActive[idx] && c.BeginRegexp != nil && c.BeginRegexp.Match(line) {
deleteActive[idx] = true
}
if deleteActive[idx] && c.EndRegexp != nil && c.EndRegexp.Match(line) {
deleteActive[idx] = false
}
}
if replaceActive[idx] && c.EndRegexp != nil && c.EndRegexp.Match(line) {
replaceActive[idx] = false
for idx, sr := range r.Replace {
c := sr.Context
if !replaceActive[idx] && c.BeginRegexp != nil && c.BeginRegexp.Match(line) {
replaceActive[idx] = true
}
if replaceActive[idx] && c.EndRegexp != nil && c.EndRegexp.Match(line) {
replaceActive[idx] = false
}
}
}

// Skip line if it matches a pattern that shall be deleted.
for idx, d := range r.Delete {
if deleteActive[idx] && d.SearchRegexp.Match(line) {
if (!r.hasContext || deleteActive[idx]) && d.SearchRegexp.Match(line) {
goto next
}
}

// Check if line matches a pattern that shall be replaced.
for idx, sr := range r.Replace {
if replaceActive[idx] {
if !r.hasContext || replaceActive[idx] {
line = sr.SearchRegexp.ReplaceAll(line, sr.ReplaceBytes)
}
}
Expand Down
6 changes: 6 additions & 0 deletions pkg/recipe.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ type Recipe struct {
Delete []DeleteEntry
Replace []ReplaceEntry
Append string

hasContext bool
}

func (r *Recipe) Read(filename string) error {
Expand Down Expand Up @@ -67,12 +69,14 @@ func (r *Recipe) Compile() error {
}

if d.Context.Begin != "" {
r.hasContext = true
r.Delete[idx].Context.BeginRegexp, err = regexp.Compile(d.Context.Begin)
if err != nil {
return err
}
}
if d.Context.End != "" {
r.hasContext = true
r.Delete[idx].Context.EndRegexp, err = regexp.Compile(d.Context.End)
if err != nil {
return err
Expand All @@ -88,12 +92,14 @@ func (r *Recipe) Compile() error {
r.Replace[idx].ReplaceBytes = []byte(sr.Replace)

if sr.Context.Begin != "" {
r.hasContext = true
r.Replace[idx].Context.BeginRegexp, err = regexp.Compile(sr.Context.Begin)
if err != nil {
return err
}
}
if sr.Context.End != "" {
r.hasContext = true
r.Replace[idx].Context.EndRegexp, err = regexp.Compile(sr.Context.End)
if err != nil {
return err
Expand Down

0 comments on commit c6fe99c

Please sign in to comment.