Merge pull request #681 from LK4D4/speedup_etchosts_delete
Speedup etchosts delete
This commit is contained in:
commit
9deda49cde
2 changed files with 81 additions and 8 deletions
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue