package topasin.util;
import static topasin.util.TopAsinUtil.log;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import topasin.calculate.AsinDetailAnalysisFields;
/**
* Create asin map. Store asin map history size.
*
* @author mengzang
*
*/
@SuppressWarnings("unchecked")
public class TopAsinMapFactory {
private static Map<String, Integer> group2AsinCountMap = new LinkedHashMap<String, Integer>();
private static String binFile;
private static int threadNumber = 3;
private static final boolean USE_THREAD_SAFE = false;
public static void init(Map<String, Object> rtOptions) {
binFile = (String) rtOptions.get(TopAsinContext.GROUP2ASIN_COUNT_BIN_FILE_NAME);
threadNumber = (Integer) rtOptions.get(TopAsinContext.BUILD_TREE_THREAD_NUMBER);
loadHistoryGroupSize();
}
public static void storeHistoryGroupSize(Map<String, Map<String, AsinDetailAnalysisFields>> group2AsinMap) {
Collection<Entry<String, Map<String, AsinDetailAnalysisFields>>> sortedEntries = TopAsinUtil
.sortMapEntryByGroupKey(group2AsinMap.entrySet());
for (Entry<String, Map<String, AsinDetailAnalysisFields>> entry : sortedEntries) {
String groupKey = entry.getKey();
int asinCount = entry.getValue().size();
log("Group " + groupKey + " has " + asinCount + " asins.");
group2AsinCountMap.put(groupKey, asinCount);
}
try {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(binFile));
oos.writeObject(group2AsinCountMap);
oos.close();
} catch (Throwable ex) {
log("Store Group 2 Asin Count error: " + ex);
}
}
private static void loadHistoryGroupSize() {
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(binFile));
group2AsinCountMap = (Map<String, Integer>) ois.readObject();
ois.close();
} catch (Throwable ex) {
log("No previous Group 2 Asin Count: " + ex);
}
}
public static <K, V> Map<K, V> getAsinMap(String groupKey) {
if (USE_THREAD_SAFE) {
return getAsinMapThreadSafe(groupKey);
} else {
return getAsinMapThreadUnsafe(groupKey);
}
}
public static <K, V> Map<K, V> getGroupMap() {
if (USE_THREAD_SAFE) {
return getGroupMapThreadSafe();
} else {
return getGroupMapThreadUnsafe();
}
}
public static <K, V> Map<K, V> getAsinMapThreadSafe(String groupKey) {
Integer asinCount = group2AsinCountMap.get(groupKey);
if (asinCount == null) {
return new ConcurrentHashMap<K, V>(2 << 20, 0.75f, threadNumber);
}
return new ConcurrentHashMap<K, V>((int) Math.round(asinCount * 1.25), 1.0f, threadNumber);
}
public static <K, V> Map<K, V> getGroupMapThreadSafe() {
int groupSize = group2AsinCountMap.size();
if (groupSize == 0) {
return new ConcurrentHashMap<K, V>(2 << 10, 0.75f, threadNumber);
}
return new ConcurrentHashMap<K, V>((int) Math.round(groupSize * 1.25), 1.0f, threadNumber);
}
public static <K, V> Map<K, V> getAsinMapThreadUnsafe(String groupKey) {
Integer asinCount = group2AsinCountMap.get(groupKey);
if (asinCount == null) {
return new HashMap<K, V>(2 << 20, 0.75f);
}
return new HashMap<K, V>((int) Math.round(asinCount * 1.25), 1.0f);
}
public static <K, V> Map<K, V> getGroupMapThreadUnsafe() {
int groupSize = group2AsinCountMap.size();
if (groupSize == 0) {
return new HashMap<K, V>(2 << 10, 0.75f);
}
return new HashMap<K, V>((int) Math.round(groupSize * 1.25), 1.0f);
}
}