From 3691ece4a5d84320cc74a3a37af8c59ea1a1ee63 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 2 Feb 2020 23:59:41 -0500 Subject: wip rpn --- rrdformat/format.go | 8 ----- rrdformat/marshal_xml.go | 54 +++++++++++++++++++++++++--- rrdformat/op_string.go | 92 ++++++++++++++++++++++++++++++++++++++++++++++++ rrdformat/rpn.go | 78 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 219 insertions(+), 13 deletions(-) create mode 100644 rrdformat/op_string.go create mode 100644 rrdformat/rpn.go diff --git a/rrdformat/format.go b/rrdformat/format.go index bb37761..ca0c459 100644 --- a/rrdformat/format.go +++ b/rrdformat/format.go @@ -93,14 +93,6 @@ func (ts TimeWithUsec) Time() time.Time { return time.Unix(int64(ts.Sec), int64(ts.Usec)*1000) } -type TimeWithoutUsec struct { - Sec rrdbinary.Time -} - -func (ts TimeWithoutUsec) Time() time.Time { - return time.Unix(int64(ts.Sec), 0) -} - type PDPPrep struct { LastDS rrdbinary.String `rrdbinary:"size=30"` Scratch [10]rrdbinary.Unival diff --git a/rrdformat/marshal_xml.go b/rrdformat/marshal_xml.go index 033073c..7b97894 100644 --- a/rrdformat/marshal_xml.go +++ b/rrdformat/marshal_xml.go @@ -40,7 +40,7 @@ func (rrd RRD) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if err := e.EncodeToken(xml.Comment(" Seconds ")); err != nil { return err } - // 3. Step + // 3. Last Update if err := e.EncodeElement(rrd.LastUpdated, xmlStart("lastupdate")); err != nil { return err } @@ -69,10 +69,6 @@ func (rrd RRD) MarshalXML(e *xml.Encoder, start xml.StartElement) error { } func (t TimeWithUsec) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - return e.EncodeElement(TimeWithoutUsec{Sec: t.Sec}, start) -} - -func (t TimeWithoutUsec) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if err := e.EncodeToken(start); err != nil { return err } @@ -90,3 +86,51 @@ func (t TimeWithoutUsec) MarshalXML(e *xml.Encoder, start xml.StartElement) erro } return nil } + +func (ds DSDef) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + if err := e.EncodeToken(start); err != nil { + return err + } + if err := e.EncodeElement(" "+ds.DSName+" ", xmlStart("name")); err != nil { + return err + } + if err := e.EncodeElement(" "+ds.DSType+" ", xmlStart("type")); err != nil { + return err + } + + switch ds.DSType { + case DST_CDEF: + var rpnps []rrdbinary.RPNToken + for _, param := range ds.Params { + rpnps = append(rpnps, param.AsRPNTokens()...) + } + strs := make([]string, len(rpnps)) + for _, rpnp := range rpnps { + switch Op(rpnp.Op) { + case OP_NUMBER: + strs = append(strs, fmt.Sprintf("%d", rpnp.Val)) + case OP_VARIABLE: + if rpnp.Val < 0 || rpnp.Val >= len(rrd.DSDefs) { + return fmt.Errorf("out-of-bounds %s %d", Op(rpnp.Op), rpnp.Val) + } + strs = append(strs, rrd.DSDefs[int(rpnp.Val)].Name) + case OP_PREV_OTHER: + if rpnp.Val < 0 || rpnp.Val >= len(rrd.DSDefs) { + return fmt.Errorf("out-of-bounds %s %d", Op(rpnp.Op), rpnp.Val) + } + strs = append(strs, fmt.Sprintf("PREV(%s)", rrd.DSDefs[int(rpnp.Val)].Name)) + default: + strs = append(strs, rpnp.Op.String()) + } + } + if err := e.EncodeElement(strings.Join(strs, ","), xmlStart("cdef")); err != nil { + return err + } + default: + + } + + if err := e.EncodeToken(start.End()); err != nil { + return err + } +} diff --git a/rrdformat/op_string.go b/rrdformat/op_string.go new file mode 100644 index 0000000..4ec909b --- /dev/null +++ b/rrdformat/op_string.go @@ -0,0 +1,92 @@ +// Code generated by "stringer -type=Op -trimprefix=OP_"; DO NOT EDIT. + +package rrdformat + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[OP_NUMBER-0] + _ = x[OP_VARIABLE-1] + _ = x[OP_INF-2] + _ = x[OP_PREV-3] + _ = x[OP_NEGINF-4] + _ = x[OP_UNKN-5] + _ = x[OP_NOW-6] + _ = x[OP_TIME-7] + _ = x[OP_ADD-8] + _ = x[OP_MOD-9] + _ = x[OP_SUB-10] + _ = x[OP_MUL-11] + _ = x[OP_DIV-12] + _ = x[OP_SIN-13] + _ = x[OP_DUP-14] + _ = x[OP_EXC-15] + _ = x[OP_POP-16] + _ = x[OP_COS-17] + _ = x[OP_LOG-18] + _ = x[OP_EXP-19] + _ = x[OP_LT-20] + _ = x[OP_LE-21] + _ = x[OP_GT-22] + _ = x[OP_GE-23] + _ = x[OP_EQ-24] + _ = x[OP_IF-25] + _ = x[OP_MIN-26] + _ = x[OP_MAX-27] + _ = x[OP_LIMIT-28] + _ = x[OP_FLOOR-29] + _ = x[OP_CEIL-30] + _ = x[OP_UN-31] + _ = x[OP_END-32] + _ = x[OP_LTIME-33] + _ = x[OP_NE-34] + _ = x[OP_ISINF-35] + _ = x[OP_PREV_OTHER-36] + _ = x[OP_COUNT-37] + _ = x[OP_ATAN-38] + _ = x[OP_SQRT-39] + _ = x[OP_SORT-40] + _ = x[OP_REV-41] + _ = x[OP_TREND-42] + _ = x[OP_TRENDNAN-43] + _ = x[OP_ATAN2-44] + _ = x[OP_RAD2DEG-45] + _ = x[OP_DEG2RAD-46] + _ = x[OP_PREDICT-47] + _ = x[OP_PREDICTSIGMA-48] + _ = x[OP_AVG-49] + _ = x[OP_ABS-50] + _ = x[OP_ADDNAN-51] + _ = x[OP_MINNAN-52] + _ = x[OP_MAXNAN-53] + _ = x[OP_MEDIAN-54] + _ = x[OP_PREDICTPERC-55] + _ = x[OP_DEPTH-56] + _ = x[OP_COPY-57] + _ = x[OP_ROLL-58] + _ = x[OP_INDEX-59] + _ = x[OP_STEPWIDTH-60] + _ = x[OP_NEWDAY-61] + _ = x[OP_NEWWEEK-62] + _ = x[OP_NEWMONTH-63] + _ = x[OP_NEWYEAR-64] + _ = x[OP_SMIN-65] + _ = x[OP_SMAX-66] + _ = x[OP_STDEV-67] + _ = x[OP_PERCENT-68] + _ = x[OP_POW-69] +} + +const _Op_name = "NUMBERVARIABLEINFPREVNEGINFUNKNNOWTIMEADDMODSUBMULDIVSINDUPEXCPOPCOSLOGEXPLTLEGTGEEQIFMINMAXLIMITFLOORCEILUNENDLTIMENEISINFPREV_OTHERCOUNTATANSQRTSORTREVTRENDTRENDNANATAN2RAD2DEGDEG2RADPREDICTPREDICTSIGMAAVGABSADDNANMINNANMAXNANMEDIANPREDICTPERCDEPTHCOPYROLLINDEXSTEPWIDTHNEWDAYNEWWEEKNEWMONTHNEWYEARSMINSMAXSTDEVPERCENTPOW" + +var _Op_index = [...]uint16{0, 6, 14, 17, 21, 27, 31, 34, 38, 41, 44, 47, 50, 53, 56, 59, 62, 65, 68, 71, 74, 76, 78, 80, 82, 84, 86, 89, 92, 97, 102, 106, 108, 111, 116, 118, 123, 133, 138, 142, 146, 150, 153, 158, 166, 171, 178, 185, 192, 204, 207, 210, 216, 222, 228, 234, 245, 250, 254, 258, 263, 272, 278, 285, 293, 300, 304, 308, 313, 320, 323} + +func (i Op) String() string { + if i >= Op(len(_Op_index)-1) { + return "Op(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _Op_name[_Op_index[i]:_Op_index[i+1]] +} diff --git a/rrdformat/rpn.go b/rrdformat/rpn.go new file mode 100644 index 0000000..a138263 --- /dev/null +++ b/rrdformat/rpn.go @@ -0,0 +1,78 @@ +//go:generate stringer -type=Op -trimprefix=OP_ + +package rrdformat + +type Op uint8 + +const ( + OP_NUMBER Op = iota // rrdtool 1.1.x 2001-03-10 + OP_VARIABLE // rrdtool 1.1.x 2001-03-10 + OP_INF // rrdtool 1.1.x 2001-03-10 + OP_PREV // rrdtool 1.1.x 2001-03-10 + OP_NEGINF // rrdtool 1.1.x 2001-03-10 + OP_UNKN // rrdtool 1.1.x 2001-03-10 + OP_NOW // rrdtool 1.1.x 2001-03-10 + OP_TIME // rrdtool 1.1.x 2001-03-10 + OP_ADD // rrdtool 1.1.x 2001-03-10 + OP_MOD // rrdtool 1.1.x 2001-03-10 + OP_SUB // rrdtool 1.1.x 2001-03-10 + OP_MUL // rrdtool 1.1.x 2001-03-10 + OP_DIV // rrdtool 1.1.x 2001-03-10 + OP_SIN // rrdtool 1.1.x 2001-03-10 + OP_DUP // rrdtool 1.1.x 2001-03-10 + OP_EXC // rrdtool 1.1.x 2001-03-10 + OP_POP // rrdtool 1.1.x 2001-03-10 + OP_COS // rrdtool 1.1.x 2001-03-10 + OP_LOG // rrdtool 1.1.x 2001-03-10 + OP_EXP // rrdtool 1.1.x 2001-03-10 + OP_LT // rrdtool 1.1.x 2001-03-10 + OP_LE // rrdtool 1.1.x 2001-03-10 + OP_GT // rrdtool 1.1.x 2001-03-10 + OP_GE // rrdtool 1.1.x 2001-03-10 + OP_EQ // rrdtool 1.1.x 2001-03-10 + OP_IF // rrdtool 1.1.x 2001-03-10 + OP_MIN // rrdtool 1.1.x 2001-03-10 + OP_MAX // rrdtool 1.1.x 2001-03-10 + OP_LIMIT // rrdtool 1.1.x 2001-03-10 + OP_FLOOR // rrdtool 1.1.x 2001-03-10 + OP_CEIL // rrdtool 1.1.x 2001-03-10 + OP_UN // rrdtool 1.1.x 2001-03-10 + OP_END // rrdtool 1.1.x 2001-03-10 + OP_LTIME // rrdtool 1.1.x 2001-03-10 + OP_NE // rrdtool 1.1.x 2002-03-10 + OP_ISINF // rrdtool 1.1.x 2002-03-10 + OP_PREV_OTHER // rrdtool 1.1.x 2002-07-06 + OP_COUNT // rrdtool 1.1.x 2003-07-14 + OP_ATAN // rrdtool 1.1.x 2004-05-04 + OP_SQRT // rrdtool 1.1.x 2004-08-24 + OP_SORT // rrdtool 1.1.x 2004-08-24 + OP_REV // rrdtool 1.1.x 2004-08-24 + OP_TREND // rrdtool 1.1.x 2004-09-24 + OP_TRENDNAN // rrdtool 1.3.0 // Problematic: Wasn't inserted at end + OP_ATAN2 // rrdtool 1.2.10 // Problematic: Definition in [1.2.10,1.3.0) differs from current + OP_RAD2DEG // rrdtool 1.2.10 // Problematic: Definition in [1.2.10,1.3.0) differs from current + OP_DEG2RAD // rrdtool 1.2.10 // Problematic: Definition in [1.2.10,1.3.0) differs from current + OP_PREDICT // rrdtool 1.4.0 // Problematic: Wasn't inserted at end + OP_PREDICTSIGMA // rrdtool 1.4.0 // Problematic: Wasn't inserted at end + OP_AVG // rrdtool 1.2.14 // Problematic: Definition in [1.2.14,1.4.0) differs from current + OP_ABS // rrdtool 1.2.20 // Problematic: Definition in [1.2.20,1.4.0) differs from current + OP_ADDNAN // rrdtool 1.3.0 // Problematic: Definition in [1.3.0,1.4.0) differs from current + OP_MINNAN // rrdtool 1.5.0 // Problematic: Wasn't inserted at end + OP_MAXNAN // rrdtool 1.5.0 // Problematic: Wasn't inserted at end + OP_MEDIAN // rrdtool 1.5.0 // Problematic: Definition in [1.5.0-pre.2012.06.01,1.5.0-pre.2014.02.07) differs from current + OP_PREDICTPERC // rrdtool 1.5.0 + OP_DEPTH // rrdtool 1.5.0 + OP_COPY // rrdtool 1.5.0 + OP_ROLL // rrdtool 1.5.0 + OP_INDEX // rrdtool 1.5.0 + OP_STEPWIDTH // rrdtool 1.5.4 + OP_NEWDAY // rrdtool 1.5.4 + OP_NEWWEEK // rrdtool 1.5.4 + OP_NEWMONTH // rrdtool 1.5.4 + OP_NEWYEAR // rrdtool 1.5.4 + OP_SMIN // rrdtool 1.6.0 + OP_SMAX // rrdtool 1.6.0 + OP_STDEV // rrdtool 1.6.0 + OP_PERCENT // rrdtool 1.6.0 + OP_POW // rrdtool 1.6.0 +) -- cgit v1.2.3