@@ -379,121 +379,124 @@ let process_ds_value ds value interval new_rrd =
379379 rate
380380
381381let ds_update rrd timestamp valuesandtransforms new_rrd =
382- (* Interval is the time between this and the last update
383-
384- Currently ds_update is called with datasources that belong to a single
385- plugin, correspondingly they all have the same timestamp.
386- Further refactoring is needed if timestamps per measurement are to be
387- introduced. *)
388- let first_ds_index, _ = valuesandtransforms.(0 ) in
389- let last_updated = rrd.rrd_dss.(first_ds_index).ds_last_updated in
390- let interval = timestamp -. last_updated in
391- (* Work around the clock going backwards *)
392- let interval = if interval < 0. then 5. else interval in
393-
394- (* start time (st) and age of the last processed pdp and the currently occupied one *)
395- let proc_pdp_st, _proc_pdp_age = get_times last_updated rrd.timestep in
396- let occu_pdp_st, occu_pdp_age = get_times timestamp rrd.timestep in
397-
398- (* The number of pdps that should result from this update *)
399- let elapsed_pdp_st =
400- Int64. to_int ((occu_pdp_st --- proc_pdp_st) /// rrd.timestep)
401- in
402-
403- (* if we're due one or more PDPs, pre_int is the amount of the
404- current update interval that will be used in calculating them, and
405- post_int is the amount left over
406- this step. If a PDP isn't post is what's left over *)
407- let pre_int, post_int =
408- if elapsed_pdp_st > 0 then
409- let pre = interval -. occu_pdp_age in
410- (pre, occu_pdp_age)
411- else
412- (interval, 0.0 )
413- in
414-
415- (* We're now done with the last_updated value, so update it *)
416- rrd.last_updated < - timestamp ;
382+ (* CA-408841 - don't update the rrd at all if list of datasources is empty *)
383+ if valuesandtransforms <> [||] then (
384+ (* Interval is the time between this and the last update
385+
386+ Currently ds_update is called with datasources that belong to a single
387+ plugin, correspondingly they all have the same timestamp.
388+ Further refactoring is needed if timestamps per measurement are to be
389+ introduced. *)
390+ let first_ds_index, _ = valuesandtransforms.(0 ) in
391+ let last_updated = rrd.rrd_dss.(first_ds_index).ds_last_updated in
392+ let interval = timestamp -. last_updated in
393+ (* Work around the clock going backwards *)
394+ let interval = if interval < 0. then 5. else interval in
395+
396+ (* start time (st) and age of the last processed pdp and the currently occupied one *)
397+ let proc_pdp_st, _proc_pdp_age = get_times last_updated rrd.timestep in
398+ let occu_pdp_st, occu_pdp_age = get_times timestamp rrd.timestep in
399+
400+ (* The number of pdps that should result from this update *)
401+ let elapsed_pdp_st =
402+ Int64. to_int ((occu_pdp_st --- proc_pdp_st) /// rrd.timestep)
403+ in
417404
418- (* Calculate the values we're going to store based on the input data and the type of the DS *)
419- let v2s =
420- Array. map
421- (fun (i , {value; _} ) ->
422- let v = process_ds_value rrd.rrd_dss.(i) value interval new_rrd in
423- rrd.rrd_dss.(i).ds_last_updated < - timestamp ;
424- (i, v)
425- )
426- valuesandtransforms
427- in
428- (* Update the PDP accumulators up until the most recent PDP *)
429- Array. iter
430- (fun (i , value ) ->
431- let ds = rrd.rrd_dss.(i) in
432- if Utils. isnan value then
433- ds.ds_unknown_sec < - pre_int
405+ (* if we're due one or more PDPs, pre_int is the amount of the
406+ current update interval that will be used in calculating them, and
407+ post_int is the amount left over
408+ this step. If a PDP isn't post is what's left over *)
409+ let pre_int, post_int =
410+ if elapsed_pdp_st > 0 then
411+ let pre = interval -. occu_pdp_age in
412+ (pre, occu_pdp_age)
434413 else
435- (* CA-404597 - Gauge and Absolute values should be passed as-is,
436- without being involved in time-based calculations at all.
437- This applies to calculations below as well *)
438- match ds.ds_ty with
439- | Gauge | Absolute ->
440- ds.ds_value < - value
441- | Derive ->
442- ds.ds_value < - ds.ds_value +. (pre_int *. value /. interval)
443- )
444- v2s ;
414+ (interval, 0.0 )
415+ in
416+
417+ (* We're now done with the last_updated value, so update it *)
418+ rrd.last_updated < - timestamp ;
445419
446- (* If we've passed a PDP point, we need to update the RRAs *)
447- if elapsed_pdp_st > 0 then (
448- (* Calculate the PDPs for each DS *)
449- let pdps =
420+ (* Calculate the values we're going to store based on the input data and the type of the DS *)
421+ let v2s =
450422 Array. map
451- (fun (i , {transform; _} ) ->
452- let ds = rrd.rrd_dss.(i) in
453- if interval > ds.ds_mrhb then
454- (i, nan)
455- else
456- let raw =
457- let proc_pdp_st = get_float_time last_updated rrd.timestep in
458- let occu_pdp_st = get_float_time timestamp rrd.timestep in
459-
460- match ds.ds_ty with
461- | Gauge | Absolute ->
462- ds.ds_value
463- | Derive ->
464- ds.ds_value
465- /. (occu_pdp_st -. proc_pdp_st -. ds.ds_unknown_sec)
466- in
467- (* Apply the transform after the raw value has been calculated *)
468- let raw = apply_transform_function transform raw in
469- (* Make sure the values are not out of bounds after all the processing *)
470- if raw < ds.ds_min || raw > ds.ds_max then
471- (i, nan)
472- else
473- (i, raw)
423+ (fun (i , {value; _} ) ->
424+ let v = process_ds_value rrd.rrd_dss.(i) value interval new_rrd in
425+ rrd.rrd_dss.(i).ds_last_updated < - timestamp ;
426+ (i, v)
474427 )
475428 valuesandtransforms
476429 in
477-
478- rra_update rrd proc_pdp_st elapsed_pdp_st pdps ;
479-
480- (* Reset the PDP accumulators *)
430+ (* Update the PDP accumulators up until the most recent PDP *)
481431 Array. iter
482432 (fun (i , value ) ->
483433 let ds = rrd.rrd_dss.(i) in
484- if Utils. isnan value then (
485- ds.ds_value < - 0.0 ;
486- ds.ds_unknown_sec < - post_int
487- ) else (
488- ds.ds_unknown_sec < - 0.0 ;
434+ if Utils. isnan value then
435+ ds.ds_unknown_sec < - pre_int
436+ else
437+ (* CA-404597 - Gauge and Absolute values should be passed as-is,
438+ without being involved in time-based calculations at all.
439+ This applies to calculations below as well *)
489440 match ds.ds_ty with
490441 | Gauge | Absolute ->
491442 ds.ds_value < - value
492443 | Derive ->
493- ds.ds_value < - post_int *. value /. interval
494- )
444+ ds.ds_value < - ds.ds_value +. (pre_int *. value /. interval)
495445 )
496- v2s
446+ v2s ;
447+
448+ (* If we've passed a PDP point, we need to update the RRAs *)
449+ if elapsed_pdp_st > 0 then (
450+ (* Calculate the PDPs for each DS *)
451+ let pdps =
452+ Array. map
453+ (fun (i , {transform; _} ) ->
454+ let ds = rrd.rrd_dss.(i) in
455+ if interval > ds.ds_mrhb then
456+ (i, nan)
457+ else
458+ let raw =
459+ let proc_pdp_st = get_float_time last_updated rrd.timestep in
460+ let occu_pdp_st = get_float_time timestamp rrd.timestep in
461+
462+ match ds.ds_ty with
463+ | Gauge | Absolute ->
464+ ds.ds_value
465+ | Derive ->
466+ ds.ds_value
467+ /. (occu_pdp_st -. proc_pdp_st -. ds.ds_unknown_sec)
468+ in
469+ (* Apply the transform after the raw value has been calculated *)
470+ let raw = apply_transform_function transform raw in
471+ (* Make sure the values are not out of bounds after all the processing *)
472+ if raw < ds.ds_min || raw > ds.ds_max then
473+ (i, nan)
474+ else
475+ (i, raw)
476+ )
477+ valuesandtransforms
478+ in
479+
480+ rra_update rrd proc_pdp_st elapsed_pdp_st pdps ;
481+
482+ (* Reset the PDP accumulators *)
483+ Array. iter
484+ (fun (i , value ) ->
485+ let ds = rrd.rrd_dss.(i) in
486+ if Utils. isnan value then (
487+ ds.ds_value < - 0.0 ;
488+ ds.ds_unknown_sec < - post_int
489+ ) else (
490+ ds.ds_unknown_sec < - 0.0 ;
491+ match ds.ds_ty with
492+ | Gauge | Absolute ->
493+ ds.ds_value < - value
494+ | Derive ->
495+ ds.ds_value < - post_int *. value /. interval
496+ )
497+ )
498+ v2s
499+ )
497500 )
498501
499502(* * Update the rrd with named values rather than just an ordered array
0 commit comments