package org.hackreduce.storm.vmc.common;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import backtype.storm.tuple.Values;
public final class Utils
{
public final static Comparator<Values> topNComparator = new Comparator<Values>()
{
@Override
public int compare(Values o1, Values o2)
{return retrieveX(o1) - retrieveX(o2);}
};
public static int retrieveX(Values v)
{
Integer n = Integer.MIN_VALUE;
if ((v != null) && (v.size() >= 4))
try
{n = (Integer)(v.get(3));}
catch(ClassCastException cce)
{n = Integer.MIN_VALUE;}
return n != null?n:Integer.MIN_VALUE;
}
/**
* Given a tuple represented v and top n list represented by q, insertion sort on just v. It should also not add v
* if it is already in q (since feeds can retrieve the same data when polled several times in short intervals.
*
* pre: q is sorted, n > 0, q.size <= n
* post: q is size n and sorted. Return true if (v was added to q and v in q).
* @param q
* @param v
* @param n
* @return
*/
public static boolean setTopN(List<Values> q, Values v, int n)
{
if (v == null) return false;
assert(q.size() <= n);
if (q.size() == 0)
{
q.add(v);
return true;
}
int i = 0;
for (Values cur: q)
{
if (v.get(2).equals(cur.get(2))) return false;
if (topNComparator.compare(v, cur) < 0)
{
q.add(i, v);
if (q.size() > n) q.remove(n);
return true;
}
i++;
}
if (q.size() < n)
{
q.add(v);
return true;
}
return false;
}
public static Values[] mapToTuples(Map<String, String> lookup)
{
Set<String> keys = lookup.keySet();
Values[] tuples = new Values[keys.size()];
int i = 0;
for (String key: keys)
tuples[i++] = new Values(key, lookup.get(key));
return tuples;
}
public static Map<String, String> loadFileFromUrl(URL url) throws Exception
{
Map<String, String> lookup = new HashMap<String, String>();
BufferedReader in = null;
InputStreamReader isr = null;
try
{
isr = new InputStreamReader(url.openStream());
in = new BufferedReader(isr);
String line;
while ((line = in.readLine()) != null)
{
String[] kv = line.split("\t");
lookup.put(kv[0], kv[1]);
}
return lookup;
}
finally
{if (in != null) in.close();}
}
public static String displayTopN(Map<String, List<Values>> lookup, String descr)
{
Set<String> keys = lookup.keySet();
List<String> keysSorted = new ArrayList<String>();
keysSorted.addAll(keys);
Collections.sort(keysSorted);
StringBuilder sb = new StringBuilder();
for (String key: keysSorted)
{
sb.append("\n**************************\n [" + key + "] for " + descr + "\n");
List<Values> values = lookup.get(key);
for (Values value: values)
sb.append(String.format("[%s], %s: [%d] with title [%s] and link [%s].\n", value.get(0), descr, value.get(3), value.get(1), value.get(2)));
}
return sb.toString();
}
public static String displayHelloCounts(Map<String, String> lookup, Map<String, Integer> counts)
{
Set<String> keys = lookup.keySet();
List<String> keysSorted = new ArrayList<String>();
keysSorted.addAll(keys);
Collections.sort(keysSorted);
StringBuilder sb = new StringBuilder();
for (String key: keysSorted)
sb.append(String.format("[%d3] people said \"[%s]\" (Hello!) in [%s].\n", counts.get(key), lookup.get(key), key));
return sb.toString();
}
}