fixed issue with invalid readings being visible

Before this change readings for sensors that are not yet available were
displayed as value 0.0 with timestamp 1970-01-01 which was meant to
represent invalid readings. This behaviour is undesired in case of
periodic report with appendLimit set. After this change invalid readings
are no longer visible.

Tested:
- Readings for sensors that is currently not available are not present
  on redfish.
- Confirmed in new unit tests that sensor readings can appear in any
  order. And produce correct results.

Signed-off-by: Krzysztof Grobelny <krzysztof.grobelny@intel.com>
Change-Id: I340b85017530d120f2da2cc8ac4ae1840177e78c
diff --git a/src/interfaces/metric.hpp b/src/interfaces/metric.hpp
index c40e960..c52dd45 100644
--- a/src/interfaces/metric.hpp
+++ b/src/interfaces/metric.hpp
@@ -19,7 +19,7 @@
 
     virtual void initialize() = 0;
     virtual void deinitialize() = 0;
-    virtual std::vector<MetricValue> getReadings() const = 0;
+    virtual const std::vector<MetricValue>& getUpdatedReadings() = 0;
     virtual LabeledMetricParameters dumpConfiguration() const = 0;
     virtual uint64_t sensorCount() const = 0;
     virtual void registerForUpdates(interfaces::MetricListener& listener) = 0;
diff --git a/src/metric.cpp b/src/metric.cpp
index a9cf45e..d6b62d8 100644
--- a/src/metric.cpp
+++ b/src/metric.cpp
@@ -21,11 +21,7 @@
         metrics::makeCollectionData(sensors.size(), operationType,
                                     collectionTimeScope, collectionDuration)),
     clock(std::move(clockIn))
-{
-    readings = utils::transform(sensors, [this](const auto& sensor) {
-        return MetricValue{id, sensor->metadata(), 0.0, 0u};
-    });
-}
+{}
 
 void Metric::registerForUpdates(interfaces::MetricListener& listener)
 {
@@ -58,25 +54,40 @@
     }
 }
 
-std::vector<MetricValue> Metric::getReadings() const
+const std::vector<MetricValue>& Metric::getUpdatedReadings()
 {
     const auto steadyTimestamp = clock->steadyTimestamp();
-    const auto systemTimestamp = clock->systemTimestamp();
+    const auto systemTimestamp =
+        std::chrono::duration_cast<Milliseconds>(clock->systemTimestamp())
+            .count();
 
-    auto resultReadings = readings;
-
-    for (size_t i = 0; i < resultReadings.size(); ++i)
+    for (size_t i = 0; i < collectionAlgorithms.size(); ++i)
     {
         if (const auto value = collectionAlgorithms[i]->update(steadyTimestamp))
         {
-            resultReadings[i].timestamp =
-                std::chrono::duration_cast<Milliseconds>(systemTimestamp)
-                    .count();
-            resultReadings[i].value = *value;
+            if (i < readings.size())
+            {
+                readings[i].timestamp = systemTimestamp;
+                readings[i].value = *value;
+            }
+            else
+            {
+                if (i > readings.size())
+                {
+                    const auto idx = readings.size();
+                    std::swap(collectionAlgorithms[i],
+                              collectionAlgorithms[idx]);
+                    std::swap(sensors[i], sensors[idx]);
+                    i = idx;
+                }
+
+                readings.emplace_back(id, sensors[i]->metadata(), *value,
+                                      systemTimestamp);
+            }
         }
     }
 
-    return resultReadings;
+    return readings;
 }
 
 void Metric::sensorUpdated(interfaces::Sensor& notifier, Milliseconds timestamp,
diff --git a/src/metric.hpp b/src/metric.hpp
index b627b4e..8b367b3 100644
--- a/src/metric.hpp
+++ b/src/metric.hpp
@@ -20,7 +20,7 @@
 
     void initialize() override;
     void deinitialize() override;
-    std::vector<MetricValue> getReadings() const override;
+    const std::vector<MetricValue>& getUpdatedReadings() override;
     void sensorUpdated(interfaces::Sensor&, Milliseconds,
                        double value) override;
     LabeledMetricParameters dumpConfiguration() const override;
diff --git a/src/report.cpp b/src/report.cpp
index 945d4e6..540418a 100644
--- a/src/report.cpp
+++ b/src/report.cpp
@@ -462,7 +462,7 @@
     for (const auto& metric : metrics)
     {
         for (const auto& [id, metadata, value, timestamp] :
-             metric->getReadings())
+             metric->getUpdatedReadings())
         {
             if (reportUpdates == ReportUpdates::appendStopsWhenFull &&
                 readingsBuffer.isFull())