package topasin.util; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import org.apache.commons.lang3.ArrayUtils; /** * Util for top asin * * @author mengzang * */ public final class TopAsinUtil { public static final String LB = System.getProperty("line.separator"); // Error code public static final String CONTEXT_VERIFY_FAILLED_ERR = "Context verification failure error"; public static final String RESOURCE_NOT_FOUNT_ERR = "Resource Not Found error"; public static final String OUTPUT_FILE_NOT_CREATEABLE_ERR = "Output file not readable error"; public static final String NO_ASIN_DESCRIBER_ERR = "No asin describer found error"; public static final String NO_SUCH_COMPARATOR_ERR = "No such comparator error"; public static final String PROCESS_RESOUCE_ERR = "Error occured while processing file"; public static final String SCRIPT_EVAL_ERROR = "Error occured while evalue script"; public static final String SCRIPT_RETRIEVE_ERROR = "Error occured when retrieving script"; public static final String ASINFIELDS_NOT_FOUND = "No AsinFields found for input"; private static final String TOP_ASIN_GROUP_SEPERATOR = "-"; public static int getInt(Object val, int defVal) { if (val == null) { return defVal; } if (val instanceof Integer) { return (Integer) val; } try { return Integer.parseInt(val.toString()); } catch (Exception ex) { return defVal; } } public static <K, V> Collection<Entry<String, Map<K, V>>> sortMapEntryByGroupKey( Set<Entry<String, Map<K, V>>> entries) { List<Entry<String, Map<K, V>>> sortedEntries = new ArrayList<Entry<String, Map<K, V>>>(entries.size()); sortedEntries.addAll(entries); GroupKeyComparator<K, V> comparator = new GroupKeyComparator<K, V>(); Collections.sort(sortedEntries, comparator); return sortedEntries; } public static class GroupKeyComparator<K, V> implements Comparator<Entry<String, Map<K, V>>> { @Override public int compare(Entry<String, Map<K, V>> o1, Entry<String, Map<K, V>> o2) { if (o1 == null && o2 == null) { return 0; } if (o1 == null) { return -1; } if (o2 == null) { return 1; } String[] groupKeyElements1 = o1.getKey().split(TOP_ASIN_GROUP_SEPERATOR); String[] groupKeyElements2 = o2.getKey().split(TOP_ASIN_GROUP_SEPERATOR); for (int i = 0; i < groupKeyElements1.length; i++) { String e1 = groupKeyElements1[i]; String e2 = groupKeyElements2[i]; int ret = e1.compareTo(e2); if (ret == 0) { continue; } else { try { int i1 = Integer.parseInt(e1); int i2 = Integer.parseInt(e2); return i1 - i2; } catch (Exception ex) { return e1.compareTo(e2); } } } return 0; } } public static int getRealIntFromAsinDetailColunmString(String str) { return Math.round(Float.parseFloat(str)); } public static int doubleCompare(double d1, double d2) { double diffVal = d1 - d2; if (diffVal < 0.0001 && diffVal > -0.0001) { return 0; } else { return diffVal > 0 ? 1 : -1; } } public static void executeMulthThreadAndWait4Termination(final String taskName, final Runnable[] runnables, final long interval, final Number counter) throws InterruptedException { log("Starting " + taskName + " with " + runnables.length + " threads..."); long start = System.currentTimeMillis(); ExecutorService service = Executors.newFixedThreadPool(runnables.length); for (Runnable runnable : runnables) { service.execute(runnable); } service.shutdown(); if (counter != null) { int preProcessedLineNumber = 0; while (service.awaitTermination(interval, TimeUnit.SECONDS) == false) { int totalProcessedLineNumber = counter.intValue(); throughputLog(interval, start, taskName, preProcessedLineNumber, totalProcessedLineNumber); preProcessedLineNumber = totalProcessedLineNumber; } } else { while (service.awaitTermination(interval, TimeUnit.SECONDS) == false) { log("Time consumed " + ((System.currentTimeMillis() - start) / 1000) + "s. Processing..."); } } log("====================================================================================================================================="); StringBuilder endMessage = new StringBuilder(taskName + " finished. Time consumed " + ((System.currentTimeMillis() - start) / 1000) + "s. "); if (counter != null) { endMessage.append("Total processed " + counter.intValue() + " lines."); } log(endMessage.toString()); log("====================================================================================================================================="); } private static void throughputLog(final long interval, final long start, final String logTitle, final int preNumber, int totalProcessedLineNumber) { int processKLineCountInterval = (totalProcessedLineNumber - preNumber) / 1000; int totalProcessedKLine = totalProcessedLineNumber / 1000; int timeUsed = (int) ((System.currentTimeMillis() - start) / 1000); log(logTitle + " processed " + processKLineCountInterval + "k lines in " + interval + " seconds.Total Processed " + totalProcessedKLine + "k lines in " + timeUsed + " seconds"); } public static void asyncExecuteMulthThreadAndWait4Termination(final String taskName, final Runnable[] runnables, final long interval, final Number counter, final Runnable callback) { Thread taskThread = new Thread(new Runnable() { @Override public void run() { try { executeMulthThreadAndWait4Termination(taskName, runnables, interval, counter); } catch (InterruptedException e) { e.printStackTrace(); } finally { if (callback != null) { callback.run(); } } } }); taskThread.start(); return; } public static String genGroupKeyFromStringArray(String[] groupElements) { if (groupElements == null) { return ""; } StringBuilder groupKeyBuilder = new StringBuilder(); for (String groupElement : groupElements) { groupKeyBuilder.append(groupElement); groupKeyBuilder.append(TOP_ASIN_GROUP_SEPERATOR); } groupKeyBuilder.deleteCharAt(groupKeyBuilder.length() - 1); return groupKeyBuilder.toString(); } @SuppressWarnings("unchecked") public static String describeMap(Map<? extends Object, ? extends Object> map, String indent) { StringBuilder des = new StringBuilder(); des.append(LB); des.append(indent); des.append("["); for (Entry<? extends Object, ? extends Object> entry : map.entrySet()) { des.append(LB); des.append(indent); des.append(entry.getKey()); des.append(" --> "); Object value = entry.getValue(); if (value instanceof Object[]) { des.append(ArrayUtils.toString((Object[]) value)); } else if (value instanceof Map) { // this would bring a dead loop if map value has the same map instance... des.append(describeMap((Map<? extends Object, ? extends Object>) value, indent + " ")); } else { des.append(value); } } des.append(LB); des.append(indent); des.append("]"); return des.toString(); } public static int moneyCompare(double m1, double m2) { double diff = m1 - m2; if (diff < 0.001 && diff > -0.001) { return 0; } return diff > 0 ? 1 : -1; } public static void appendLine(StringBuilder content, Object line) { if (line != null) { content.append(line); } content.append(LB); } public static void log(Object obj) { System.out.println(obj); } }