From b3f53a7a81c9ac558c76aaef599083da6acafdf2 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Mon, 20 Mar 2017 22:52:13 +0000 Subject: [PATCH] Call CodecDecodeSelf() instead of Decode() This avoids a runtime type lookup, so goes a little faster. Also having less recursion makes it easier to interpret profiles. --- extras/generate_latest_map | 5 +++-- report/controls.go | 5 ++--- report/edge_metadatas.go | 3 ++- report/latest_map_generated.go | 10 ++++++---- report/marshal.go | 7 +++++++ report/metrics.go | 5 ++--- 6 files changed, 22 insertions(+), 13 deletions(-) diff --git a/extras/generate_latest_map b/extras/generate_latest_map index 1639bb15b..05051c3e8 100755 --- a/extras/generate_latest_map +++ b/extras/generate_latest_map @@ -47,6 +47,7 @@ function generate_latest_map() { type ${entry_type} struct { Timestamp time.Time ${json_timestamp} Value ${data_type} ${json_value} + dummySelfer } // String returns the StringLatestEntry's string representation. @@ -122,7 +123,7 @@ function generate_latest_map() { if m.Map == nil { m.Map = ps.NewMap() } - return ${latest_map_type}{m.Map.Set(key, &${entry_type}{timestamp, value})} + return ${latest_map_type}{m.Map.Set(key, &${entry_type}{Timestamp: timestamp, Value: value})} } // Delete the value for the given key. @@ -178,7 +179,7 @@ function generate_latest_map() { out := mapRead(decoder, func(isNil bool) interface{} { value := &${entry_type}{} if !isNil { - decoder.Decode(value) + value.CodecDecodeSelf(decoder) } return value }) diff --git a/report/controls.go b/report/controls.go index 85eed408b..02e87a5b8 100644 --- a/report/controls.go +++ b/report/controls.go @@ -91,6 +91,7 @@ func (nc NodeControls) Add(ids ...string) NodeControls { type wireNodeControls struct { Timestamp string `json:"timestamp,omitempty"` Controls StringSet `json:"controls,omitempty"` + dummySelfer } // CodecEncodeSelf implements codec.Selfer @@ -104,9 +105,7 @@ func (nc *NodeControls) CodecEncodeSelf(encoder *codec.Encoder) { // CodecDecodeSelf implements codec.Selfer func (nc *NodeControls) CodecDecodeSelf(decoder *codec.Decoder) { in := wireNodeControls{} - if err := decoder.Decode(&in); err != nil { - return - } + in.CodecDecodeSelf(decoder) *nc = NodeControls{ Timestamp: parseTime(in.Timestamp), Controls: in.Controls, diff --git a/report/edge_metadatas.go b/report/edge_metadatas.go index 2609d8e85..13b0d40c0 100644 --- a/report/edge_metadatas.go +++ b/report/edge_metadatas.go @@ -180,7 +180,7 @@ func (c *EdgeMetadatas) CodecDecodeSelf(decoder *codec.Decoder) { out := mapRead(decoder, func(isNil bool) interface{} { var value EdgeMetadata if !isNil { - decoder.Decode(&value) + value.CodecDecodeSelf(decoder) } return value }) @@ -221,6 +221,7 @@ type EdgeMetadata struct { IngressPacketCount *uint64 `json:"ingress_packet_count,omitempty"` EgressByteCount *uint64 `json:"egress_byte_count,omitempty"` // Transport layer IngressByteCount *uint64 `json:"ingress_byte_count,omitempty"` // Transport layer + dummySelfer } // String returns a string representation of this EdgeMetadata diff --git a/report/latest_map_generated.go b/report/latest_map_generated.go index 1786b0a46..7192cd7d6 100644 --- a/report/latest_map_generated.go +++ b/report/latest_map_generated.go @@ -14,6 +14,7 @@ import ( type stringLatestEntry struct { Timestamp time.Time `json:"timestamp"` Value string `json:"value"` + dummySelfer } // String returns the StringLatestEntry's string representation. @@ -89,7 +90,7 @@ func (m StringLatestMap) Set(key string, timestamp time.Time, value string) Stri if m.Map == nil { m.Map = ps.NewMap() } - return StringLatestMap{m.Map.Set(key, &stringLatestEntry{timestamp, value})} + return StringLatestMap{m.Map.Set(key, &stringLatestEntry{Timestamp: timestamp, Value: value})} } // Delete the value for the given key. @@ -145,7 +146,7 @@ func (m *StringLatestMap) CodecDecodeSelf(decoder *codec.Decoder) { out := mapRead(decoder, func(isNil bool) interface{} { value := &stringLatestEntry{} if !isNil { - decoder.Decode(value) + value.CodecDecodeSelf(decoder) } return value }) @@ -165,6 +166,7 @@ func (*StringLatestMap) UnmarshalJSON(b []byte) error { type nodeControlDataLatestEntry struct { Timestamp time.Time `json:"timestamp"` Value NodeControlData `json:"value"` + dummySelfer } // String returns the StringLatestEntry's string representation. @@ -240,7 +242,7 @@ func (m NodeControlDataLatestMap) Set(key string, timestamp time.Time, value Nod if m.Map == nil { m.Map = ps.NewMap() } - return NodeControlDataLatestMap{m.Map.Set(key, &nodeControlDataLatestEntry{timestamp, value})} + return NodeControlDataLatestMap{m.Map.Set(key, &nodeControlDataLatestEntry{Timestamp: timestamp, Value: value})} } // Delete the value for the given key. @@ -296,7 +298,7 @@ func (m *NodeControlDataLatestMap) CodecDecodeSelf(decoder *codec.Decoder) { out := mapRead(decoder, func(isNil bool) interface{} { value := &nodeControlDataLatestEntry{} if !isNil { - decoder.Decode(value) + value.CodecDecodeSelf(decoder) } return value }) diff --git a/report/marshal.go b/report/marshal.go index 1e013761a..b21e01a17 100644 --- a/report/marshal.go +++ b/report/marshal.go @@ -10,6 +10,13 @@ import ( "github.com/ugorji/go/codec" ) +// Include this in a struct to be able to call CodecDecodeSelf() before code generation +type dummySelfer struct{} + +func (s *dummySelfer) CodecDecodeSelf(decoder *codec.Decoder) { + panic("This shouldn't happen: perhaps something has gone wrong in code generation?") +} + // WriteBinary writes a Report as a gzipped msgpack. func (rep Report) WriteBinary(w io.Writer, compressionLevel int) error { gzwriter, err := gzip.NewWriterLevel(w, compressionLevel) diff --git a/report/metrics.go b/report/metrics.go index 65ff5a35e..ea1122c92 100644 --- a/report/metrics.go +++ b/report/metrics.go @@ -225,6 +225,7 @@ type WireMetrics struct { Max float64 `json:"max"` First string `json:"first,omitempty"` Last string `json:"last,omitempty"` + dummySelfer } func renderTime(t time.Time) string { @@ -272,9 +273,7 @@ func (m *Metric) CodecEncodeSelf(encoder *codec.Encoder) { // CodecDecodeSelf implements codec.Selfer func (m *Metric) CodecDecodeSelf(decoder *codec.Decoder) { in := WireMetrics{} - if err := decoder.Decode(&in); err != nil { - return - } + in.CodecDecodeSelf(decoder) *m = in.FromIntermediate() }