From 36a8f5822c9562d12812df73a994ddabbdf37e62 Mon Sep 17 00:00:00 2001 From: Alexander Morozov Date: Mon, 19 Oct 2015 09:22:29 -0700 Subject: [PATCH] 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 --- libnetwork/etchosts/etchosts.go | 34 +++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/libnetwork/etchosts/etchosts.go b/libnetwork/etchosts/etchosts.go index 92597b71b4..256a89dfa8 100644 --- a/libnetwork/etchosts/etchosts.go +++ b/libnetwork/etchosts/etchosts.go @@ -1,6 +1,7 @@ package etchosts import ( + "bufio" "bytes" "fmt" "io" @@ -138,19 +139,36 @@ func Delete(path string, recs []Record) error { if len(recs) == 0 { return nil } - - old, err := ioutil.ReadFile(path) + old, err := os.Open(path) if err != nil { return err } - regexpStr := fmt.Sprintf("\\S*\\t%s\\n", regexp.QuoteMeta(recs[0].Hosts)) - for _, r := range recs[1:] { - regexpStr = regexpStr + "|" + fmt.Sprintf("\\S*\\t%s\\n", regexp.QuoteMeta(r.Hosts)) - } + var buf bytes.Buffer - var re = regexp.MustCompile(regexpStr) - return ioutil.WriteFile(path, re.ReplaceAll(old, []byte("")), 0644) + s := bufio.NewScanner(old) + 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.