Use simple scanner instead of regexp for etchosts.Delete

Benchmark results:
benchmark           old ns/op     new ns/op     delta
BenchmarkDelete     4315186       2245829       -47.96%

benchmark           old allocs     new allocs     delta
BenchmarkDelete     4645           10             -99.78%

benchmark           old bytes     new bytes     delta
BenchmarkDelete     1590011       4832          -99.70%

Signed-off-by: Alexander Morozov <lk4d4@docker.com>
This commit is contained in:
Alexander Morozov 2015-10-19 09:22:29 -07:00
parent de7607f509
commit 36a8f5822c
1 changed files with 26 additions and 8 deletions

View File

@ -1,6 +1,7 @@
package etchosts package etchosts
import ( import (
"bufio"
"bytes" "bytes"
"fmt" "fmt"
"io" "io"
@ -138,19 +139,36 @@ func Delete(path string, recs []Record) error {
if len(recs) == 0 { if len(recs) == 0 {
return nil return nil
} }
old, err := os.Open(path)
old, err := ioutil.ReadFile(path)
if err != nil { if err != nil {
return err return err
} }
regexpStr := fmt.Sprintf("\\S*\\t%s\\n", regexp.QuoteMeta(recs[0].Hosts)) var buf bytes.Buffer
for _, r := range recs[1:] {
regexpStr = regexpStr + "|" + fmt.Sprintf("\\S*\\t%s\\n", regexp.QuoteMeta(r.Hosts))
}
var re = regexp.MustCompile(regexpStr) s := bufio.NewScanner(old)
return ioutil.WriteFile(path, re.ReplaceAll(old, []byte("")), 0644) eol := []byte{'\n'}
loop:
for s.Scan() {
b := s.Bytes()
if b[0] == '#' {
buf.Write(b)
buf.Write(eol)
continue
}
for _, r := range recs {
if bytes.HasSuffix(b, []byte("\t"+r.Hosts)) {
continue loop
}
}
buf.Write(b)
buf.Write(eol)
}
old.Close()
if err := s.Err(); err != nil {
return err
}
return ioutil.WriteFile(path, buf.Bytes(), 0644)
} }
// Update all IP addresses where hostname matches. // Update all IP addresses where hostname matches.