From f50e44937348491d51bd6603fcd9dd1244196e62 Mon Sep 17 00:00:00 2001
From: Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
Date: Tue, 8 Nov 2016 00:27:28 -0500
Subject: [PATCH] refactoring in the stats system to fix some compiler errors

---
 include/villas/hooks.h     |  2 +-
 include/villas/path.h      |  2 +-
 include/villas/stats.h     | 12 ++++----
 lib/hooks/hooks-internal.c |  3 +-
 lib/hooks/hooks-stats.c    |  3 +-
 lib/stats.c                | 56 +++++++++++++++-----------------------
 6 files changed, 34 insertions(+), 44 deletions(-)

diff --git a/include/villas/hooks.h b/include/villas/hooks.h
index f87f228d1..f88635a21 100644
--- a/include/villas/hooks.h
+++ b/include/villas/hooks.h
@@ -112,7 +112,7 @@ enum hook_type {
 	/** All path related actions */
 	HOOK_PATH		= HOOK_PATH_START | HOOK_PATH_STOP | HOOK_PATH_RESTART,
 	/** Hooks which are used to collect statistics. */
-	HOOK_STATS		= HOOK_INTERNAL | HOOK_STORAGE | HOOK_PATH | HOOK_READ | HOOK_PERIODIC,
+	HOOK_STATS		= HOOK_STORAGE | HOOK_PATH | HOOK_READ | HOOK_PERIODIC,
 	/** @} */
 };
 
diff --git a/include/villas/path.h b/include/villas/path.h
index 7bf71a003..c9e5104aa 100644
--- a/include/villas/path.h
+++ b/include/villas/path.h
@@ -67,7 +67,7 @@ struct path
 	
 	char *_name;			/**< Singleton: A string which is used to print this path to screen. */
 	
-	struct stats *stats;	/**< Statistic counters. This is a pointer to the statistic hooks private data. */
+	struct stats_delta *stats;	/**< Statistic counters. This is a pointer to the statistic hooks private data. */
 	
 	config_setting_t *cfg;		/**< A pointer to the libconfig object which instantiated this path */
 };
diff --git a/include/villas/stats.h b/include/villas/stats.h
index f5c4178c5..dc69beb41 100644
--- a/include/villas/stats.h
+++ b/include/villas/stats.h
@@ -34,7 +34,9 @@ enum stats_id {
 };
 
 struct stats_delta {
-	double vals[STATS_COUNT];
+	double values[STATS_COUNT];
+	
+	struct sample *last;
 };
 
 struct stats {
@@ -47,14 +49,12 @@ int stats_init(struct stats *s);
 
 void stats_destroy(struct stats *s);
 
-void stats_update(struct stats *s, enum stats_id id, double val);
+void stats_update(struct stats_delta *s, enum stats_id id, double val);
+
+void stats_collect(struct stats_delta *s, struct sample *smps[], size_t cnt);
 
 int stats_commit(struct stats *s, struct stats_delta *d);
 
-void stats_collect(struct stats *s, struct sample *smps[], size_t cnt);
-
-void stats_decollect(struct stats *s, struct sample *smps[], size_t cnt);
-
 #ifdef WITH_JANSSON
 json_t * stats_json(struct stats *s);
 #endif
diff --git a/lib/hooks/hooks-internal.c b/lib/hooks/hooks-internal.c
index 5ce5cf705..81673a3c3 100644
--- a/lib/hooks/hooks-internal.c
+++ b/lib/hooks/hooks-internal.c
@@ -76,8 +76,9 @@ int hook_drop(struct hook *h, int when, struct hook_info *j)
 		if (h->prev) {
 			dist = h->last->sequence - (int32_t) h->prev->sequence;
 			if (dist <= 0) {
-				stats_update(j->path->stats, STATS_DROPPED, dist);
 				warn("Dropped sample: dist = %d, i = %d", dist, i);
+				if (j->path)
+					stats_update(j->path->stats, STATS_DROPPED, dist);
 			}
 			else {
 				struct sample *tmp;
diff --git a/lib/hooks/hooks-stats.c b/lib/hooks/hooks-stats.c
index e0139efff..f9fb97b7f 100644
--- a/lib/hooks/hooks-stats.c
+++ b/lib/hooks/hooks-stats.c
@@ -22,8 +22,9 @@ int hook_stats(struct hook *h, int when, struct hook_info *j)
 	switch (when) {
 		case HOOK_READ:
 			assert(j->smps);
+			assert(j->path);
 		
-			stats_collect(s, j->smps, j->cnt);
+			stats_collect(j->path->stats, j->smps, j->cnt);
 			break;
 
 		case HOOK_PATH_STOP:
diff --git a/lib/stats.c b/lib/stats.c
index e62dda812..6441edf85 100644
--- a/lib/stats.c
+++ b/lib/stats.c
@@ -48,54 +48,42 @@ void stats_destroy(struct stats *s)
 	}
 }
 
-void stats_update(struct stats *s, enum stats_id id, double val)
+void stats_update(struct stats_delta *d, enum stats_id id, double val)
 {
-	if (!s)
-		return;
-	
-	hist_put(&s->histograms[id], val);
+	if (d && id >= 0 && id < STATS_COUNT)
+		d->values[id] = val;
 }
 
-#if 0
-int stats_delta(struct stats_delta *d, struct sample *s, struct sample *p)
-{
-	d->histogram.owd      = time_delta(&smps[i]->ts.origin,   &smps[i]->ts.received);
-	d->histogram.gap      = time_delta(&s->last->ts.origin,   &smps[i]->ts.origin);
-	d->histogram.gap_seq  = s->sequence - (int32_t) p->sequence;
-	d->histogram.gap_recv = time_delta(&s->last->ts.received, &smps[i]->ts.received);
-	
-	d->counter.dropped    = d->histogram.gap_seq <= 0 ? 1 : 0;
-	d->counter.invalid    = 0;
-	
-	return 0;
-}
-#endif
-
 int stats_commit(struct stats *s, struct stats_delta *d)
 {
 	for (int i = 0; i < STATS_COUNT; i++) {
-		hist_put(&s->histograms[i], d->vals[i]);
+		hist_put(&s->histograms[i], d->values[i]);
 	}
 	
 	return 0;
 }
 
-void stats_collect(struct stats *s, struct sample *smps[], size_t cnt)
+void stats_collect(struct stats_delta *s, struct sample *smps[], size_t cnt)
 {
-	for (int i = 0; i < cnt; i++) {
-		if (s->last) {
-//			struct stats_delta d;
-//			stats_get_delta(&d, smps[i], s->last);
-//			stats_commit(s, &d);
+	struct sample *previous = s->last;
+	
+	if (previous) {
+		sample_put(previous);
+		
+		for (int i = 0; i < cnt; i++) {
+			stats_update(s, STATS_GAP_RECEIVED, time_delta(&previous->ts.received, &smps[i]->ts.received));
+			stats_update(s, STATS_GAP_SAMPLE,   time_delta(&previous->ts.origin,   &smps[i]->ts.origin));
+			stats_update(s, STATS_OWD,          time_delta(&smps[i]->ts.origin,    &smps[i]->ts.received));
+			stats_update(s, STATS_GAP_SEQUENCE, smps[i]->sequence - (int32_t) previous->sequence);
+		
+			/* Make sure there is always a reference to the previous sample */
+
+			previous = smps[i];
 		}
-
-		if (i == 0 && s->last)
-			sample_put(s->last);
-		if (i == cnt - 1)
-			sample_get(smps[i]);
-
-		s->last = smps[i];
 	}
+
+	sample_get(previous);
+	s->last = previous;
 }
 
 #ifdef WITH_JANSSON