Merge pull request #681 from LK4D4/speedup_etchosts_delete

Speedup etchosts delete
This commit is contained in:
aboch 2015-12-03 11:27:47 -08:00
commit 9deda49cde
2 changed files with 81 additions and 8 deletions

View file

@ -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.

View file

@ -223,6 +223,10 @@ func TestDelete(t *testing.T) {
Hosts: "testhostname2",
IP: "2.2.2.2",
},
Record{
Hosts: "testhostname3",
IP: "3.3.3.3",
},
}); err != nil {
t.Fatal(err)
}
@ -232,6 +236,10 @@ func TestDelete(t *testing.T) {
Hosts: "testhostname1",
IP: "1.1.1.1",
},
Record{
Hosts: "testhostname3",
IP: "3.3.3.3",
},
}); err != nil {
t.Fatal(err)
}
@ -307,3 +315,50 @@ func TestConcurrentWrites(t *testing.T) {
t.Fatalf("Expected to find '%s' got '%s'", expected, content)
}
}
func benchDelete(b *testing.B) {
b.StopTimer()
file, err := ioutil.TempFile("", "")
if err != nil {
b.Fatal(err)
}
defer func() {
b.StopTimer()
file.Close()
os.Remove(file.Name())
b.StartTimer()
}()
err = Build(file.Name(), "", "", "", nil)
if err != nil {
b.Fatal(err)
}
var records []Record
var toDelete []Record
for i := 0; i < 255; i++ {
record := Record{
Hosts: fmt.Sprintf("testhostname%d", i),
IP: fmt.Sprintf("%d.%d.%d.%d", i, i, i, i),
}
records = append(records, record)
if i%2 == 0 {
toDelete = append(records, record)
}
}
if err := Add(file.Name(), records); err != nil {
b.Fatal(err)
}
b.StartTimer()
if err := Delete(file.Name(), toDelete); err != nil {
b.Fatal(err)
}
}
func BenchmarkDelete(b *testing.B) {
for i := 0; i < b.N; i++ {
benchDelete(b)
}
}