From 5143b56293d84312db29ee93dc5b90555d8d14bc Mon Sep 17 00:00:00 2001
From: Nelson Tavares de Sousa <ntd@informatik.uni-kiel.de>
Date: Tue, 17 Feb 2015 13:30:04 +0100
Subject: [PATCH] first version of CountingmapMerger

---
 .../java/teetime/stage/CountingmapMerger.java | 56 +++++++++++++++++++
 .../java/teetime/stage/util/CountingMap.java  | 34 ++++++++++-
 2 files changed, 89 insertions(+), 1 deletion(-)
 create mode 100644 src/main/java/teetime/stage/CountingmapMerger.java

diff --git a/src/main/java/teetime/stage/CountingmapMerger.java b/src/main/java/teetime/stage/CountingmapMerger.java
new file mode 100644
index 00000000..1a4d2fc5
--- /dev/null
+++ b/src/main/java/teetime/stage/CountingmapMerger.java
@@ -0,0 +1,56 @@
+package teetime.stage;
+
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import teetime.framework.AbstractConsumerStage;
+import teetime.framework.OutputPort;
+import teetime.stage.util.CountingMap;
+
+/**
+ * Receives different CountingMap instances and merges them into a single one.
+ * The result is sent upon termination.
+ *
+ * @author Nelson Tavares de Sousa
+ *
+ * @param <T>
+ *            Key type of the map to be sent
+ */
+public class CountingmapMerger<T> extends AbstractConsumerStage<CountingMap<T>> {
+
+	private final CountingMap<T> result = new CountingMap<T>();
+	private final OutputPort<Map<T, Integer>> port = createOutputPort();
+
+	private final int numberOfInputPorts;
+
+	public CountingmapMerger(final int numberOfInputPorts) {
+		for (int i = 1; i < numberOfInputPorts; i++) {
+			createInputPort();
+		}
+		this.numberOfInputPorts = numberOfInputPorts;
+	}
+
+	@Override
+	protected void execute(final CountingMap<T> element) {
+		Set<Map.Entry<T, Integer>> entries = element.entrySet();
+		for (Entry<T, Integer> entry : entries) {
+			Integer resultValue = result.get(entry.getKey());
+			if (resultValue == null) {
+				result.put(entry.getKey(), entry.getValue());
+			}
+			else {
+				Integer temp = result.get(entry.getKey());
+				temp += entry.getValue();
+				result.put(entry.getKey(), temp);
+			}
+		}
+	}
+
+	@Override
+	public void onTerminating() throws Exception {
+		port.send(result);
+		super.onTerminating();
+	}
+
+}
diff --git a/src/main/java/teetime/stage/util/CountingMap.java b/src/main/java/teetime/stage/util/CountingMap.java
index d9bb6f39..0e6ae4ef 100644
--- a/src/main/java/teetime/stage/util/CountingMap.java
+++ b/src/main/java/teetime/stage/util/CountingMap.java
@@ -2,6 +2,15 @@ package teetime.stage.util;
 
 import java.util.HashMap;
 
+/**
+ * An implementation of HashMap which can be used to count the occurrence of different keys.
+ * This conaitns all methods of HashMap, but is enhanched with the {@link #add(T, Integer)} and {@link #increment(T)} methods.
+ *
+ * @author Nelson Tavares de Sousa
+ *
+ * @param <T>
+ *            Key type to be count
+ */
 public class CountingMap<T> extends HashMap<T, Integer> {
 
 	/**
@@ -9,13 +18,36 @@ public class CountingMap<T> extends HashMap<T, Integer> {
 	 */
 	private static final long serialVersionUID = -8036971796701648200L;
 
+	/**
+	 * Increments the value of key by one.
+	 *
+	 * @param key
+	 */
 	public void increment(final T key) {
 		if (super.containsKey(key)) {
 			Integer i = super.get(key);
 			i++;
 			super.put(key, i);
 		} else {
-			super.put(key, 0);
+			super.put(key, 1);
+		}
+	}
+
+	/**
+	 * Adds i to the value of key.
+	 *
+	 * @param key
+	 *            Key which is used to add i.
+	 * @param i
+	 *            Integer value to be added.
+	 */
+	public void add(final T key, final Integer i) {
+		if (super.containsKey(key)) {
+			Integer j = super.get(key);
+			j += i;
+			super.put(key, j);
+		} else {
+			super.put(key, i);
 		}
 	}
 
-- 
GitLab