+/* read_cumulative_state reads the start time and start value of cumulative
+ * (i.e. DERIVE or COUNTER) metrics from the cache. If a metric is seen for the
+ * first time, or when a DERIVE metric is reset, the start time is (re)set to
+ * vl->time. */
+static int read_cumulative_state(data_set_t const *ds, value_list_t const *vl,
+ int ds_index, cdtime_t *ret_start_time,
+ int64_t *ret_start_value) {
+ int ds_type = ds->ds[ds_index].type;
+ if ((ds_type != DS_TYPE_DERIVE) && (ds_type != DS_TYPE_COUNTER)) {
+ return 0;
+ }
+
+ char start_value_key[DATA_MAX_NAME_LEN];
+ snprintf(start_value_key, sizeof(start_value_key),
+ "stackdriver:start_value[%d]", ds_index);
+
+ int status =
+ uc_meta_data_get_signed_int(vl, start_value_key, ret_start_value);
+ if ((status == 0) && ((ds_type != DS_TYPE_DERIVE) ||
+ (*ret_start_value <= vl->values[ds_index].derive))) {
+ return uc_meta_data_get_unsigned_int(vl, "stackdriver:start_time",
+ ret_start_time);
+ }
+
+ if (ds_type == DS_TYPE_DERIVE) {
+ *ret_start_value = vl->values[ds_index].derive;
+ } else {
+ *ret_start_value = (int64_t)vl->values[ds_index].counter;
+ }
+ *ret_start_time = vl->time;
+
+ status = uc_meta_data_add_signed_int(vl, start_value_key, *ret_start_value);
+ if (status != 0) {
+ return status;
+ }
+ return uc_meta_data_add_unsigned_int(vl, "stackdriver:start_time",
+ *ret_start_time);
+} /* int read_cumulative_state */
+