summaryrefslogtreecommitdiffhomepage
path: root/gomrt/main.go
diff options
context:
space:
mode:
authorISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2015-06-23 23:27:40 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-06-25 22:24:28 +0900
commit9340fa83d1a54ef71dd0143b21638e8942a377a3 (patch)
treec811962a2210e9c747139bc04795ca70794ce058 /gomrt/main.go
parentd933f0a0c1a0b64ec1bf19bdc113acf8b04af7e8 (diff)
gomrt: split parsing and sending into different goroutines
another performance improvement. [before] $ time gomrt -i rib.20150617.2000 gomrt -i /vagrant/rib.20150617.2000 48.98s user 149.40s system 97% cpu 3:24.30 total [after] $ time gomrt -i rib.20150617.2000 gomrt -i /vagrant/rib.20150617.2000 30.57s user 99.59s system 96% cpu 2:15.27 total Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
Diffstat (limited to 'gomrt/main.go')
-rw-r--r--gomrt/main.go130
1 files changed, 70 insertions, 60 deletions
diff --git a/gomrt/main.go b/gomrt/main.go
index 1e44737f..1f3e7e19 100644
--- a/gomrt/main.go
+++ b/gomrt/main.go
@@ -72,81 +72,91 @@ func main() {
idx := 0
- stream, err := client.ModPath(context.Background())
- if err != nil {
- fmt.Println("failed to modpath:", err)
- os.Exit(1)
- }
+ ch := make(chan *api.Path, 1024)
- for {
- buf := make([]byte, mrt.COMMON_HEADER_LEN)
- _, err := file.Read(buf)
- if err == io.EOF {
- break
- } else if err != nil {
- fmt.Println("failed to read:", err)
- os.Exit(1)
- }
-
- h := &mrt.Header{}
- err = h.DecodeFromBytes(buf)
- if err != nil {
- fmt.Println("failed to parse")
- os.Exit(1)
- }
-
- buf = make([]byte, h.Len)
- _, err = file.Read(buf)
- if err != nil {
- fmt.Println("failed to read")
- os.Exit(1)
- }
-
- msg, err := mrt.ParseBody(h, buf)
- if err != nil {
- fmt.Println("failed to parse:", err)
- os.Exit(1)
- }
+ go func() {
- if msg.Header.Type == mrt.TABLE_DUMPv2 {
- subType := mrt.SubTypeTableDumpv2(msg.Header.SubType)
- var af *api.AddressFamily
- switch subType {
- case mrt.PEER_INDEX_TABLE:
- continue
- case mrt.RIB_IPV4_UNICAST:
- af = api.AF_IPV4_UC
- case mrt.RIB_IPV6_UNICAST:
- af = api.AF_IPV6_UC
- default:
- fmt.Println("unsupported subType:", subType)
+ for {
+ buf := make([]byte, mrt.COMMON_HEADER_LEN)
+ _, err := file.Read(buf)
+ if err == io.EOF {
+ break
+ } else if err != nil {
+ fmt.Println("failed to read:", err)
os.Exit(1)
}
- rib := msg.Body.(*mrt.Rib)
- prefix := rib.Prefix.String()
- path := &api.Path{}
- path.Nlri = &api.Nlri{
- Af: af,
- Prefix: prefix,
+
+ h := &mrt.Header{}
+ err = h.DecodeFromBytes(buf)
+ if err != nil {
+ fmt.Println("failed to parse")
+ os.Exit(1)
}
- arg := &api.ModPathArguments{
- Resource: api.Resource_GLOBAL,
- Path: path,
+ buf = make([]byte, h.Len)
+ _, err = file.Read(buf)
+ if err != nil {
+ fmt.Println("failed to read")
+ os.Exit(1)
}
- err = stream.Send(arg)
+ msg, err := mrt.ParseBody(h, buf)
if err != nil {
- fmt.Println("failed to send:", err)
+ fmt.Println("failed to parse:", err)
os.Exit(1)
}
+ if msg.Header.Type == mrt.TABLE_DUMPv2 {
+ subType := mrt.SubTypeTableDumpv2(msg.Header.SubType)
+ var af *api.AddressFamily
+ switch subType {
+ case mrt.PEER_INDEX_TABLE:
+ continue
+ case mrt.RIB_IPV4_UNICAST:
+ af = api.AF_IPV4_UC
+ case mrt.RIB_IPV6_UNICAST:
+ af = api.AF_IPV6_UC
+ default:
+ fmt.Println("unsupported subType:", subType)
+ os.Exit(1)
+ }
+ rib := msg.Body.(*mrt.Rib)
+ prefix := rib.Prefix.String()
+ path := &api.Path{}
+ path.Nlri = &api.Nlri{
+ Af: af,
+ Prefix: prefix,
+ }
+
+ ch <- path
+ }
+
+ idx += 1
+
+ if idx == globalOpts.Count {
+ break
+ }
}
- idx += 1
+ close(ch)
+ }()
- if idx == globalOpts.Count {
- break
+ stream, err := client.ModPath(context.Background())
+ if err != nil {
+ fmt.Println("failed to modpath:", err)
+ os.Exit(1)
+ }
+
+ for path := range ch {
+ arg := &api.ModPathArguments{
+ Resource: api.Resource_GLOBAL,
+ Path: path,
+ }
+
+ err = stream.Send(arg)
+ if err != nil {
+ fmt.Println("failed to send:", err)
+ os.Exit(1)
}
}