package com.amazon.mzang.tools.asindetailsbs;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map.Entry;
import java.util.TreeMap;
public class MainTestApp {
BufferedReader origReader;
BufferedReader sbsReader;
PrintWriter output;
PrintWriter error;
int threshold;
TopAsinByIogGLAnalytMultiLevelSource analyst;
public void doTransform() throws IOException, SQLException {
analyst.doAnalysis();
}
public static void main(String... args) throws IOException {
BufferedReader origReader = new BufferedReader(new FileReader(new File(
"G:/UnhealthyAsinDetails-transformed.2012-08-21_to_2012-08-28.txt")));
BufferedReader sbsReader = new BufferedReader(new FileReader(new File(
"G:/UnhealthyAsinDetails-transformed.2012-08-21_to_2012-08-28.txt")));
TopAsinByIogGLAnalytMultiLevelSource analyst = new TopAsinByIogGLAnalytMultiLevelSource(
origReader, sbsReader, new PrintWriter(new OutputStreamWriter(System.out)),
new PrintWriter(new OutputStreamWriter(System.err)), 200);
analyst.doAnalysis();
}
}
class TopAsinByIogGLAnalytMultiLevelSource {
BufferedReader origReader;
BufferedReader sbsReader;
PrintWriter output;
PrintWriter error;
int threshold;
public TopAsinByIogGLAnalytMultiLevelSource(BufferedReader origReader,
BufferedReader sbsReader, PrintWriter output, PrintWriter error, int threshold) {
this.origReader = origReader;
this.sbsReader = sbsReader;
this.output = output;
this.error = error;
this.threshold = threshold;
}
public void doAnalysis() throws IOException {
HashMap<Integer, HashMap<Integer, TreeMap<String, AsinDetailsSBSFields>>> iog2glOrig = buildTree(origReader);
// veriyMap(new BufferedReader(new FileReader(new File(
// "G:/UnhealthyAsinDetails-transformed.2012-08-21_to_2012-08-28.txt"))),
// iog2glOrigMap);
HashMap<Integer, HashMap<Integer, SBSTopAsins>> sbsResult = analysisFileAgainstIog2GlMap(
sbsReader, iog2glOrig, threshold);
outputSBSResult(sbsResult, output);
}
// public static void veriyMap(BufferedReader reader, Iog2Gl iog2glOrigMap)
// throws IOException {
// String asindetailsLine = reader.readLine();
// while ((asindetailsLine = reader.readLine()) != null) {
// AsinDetailLine asindetail = new AsinDetailLine(asindetailsLine);
// AsinDetailsSBSFields sbs = AsinDetailsSBSFields.getInstance(asindetail);
// if (sbs.equals(iog2glOrigMap.getAsin(asindetail)) == false) {
// throw new RuntimeException("Verification Fail");
// }
// }
// System.out.println("verification pass");
// }
private static HashMap<Integer, HashMap<Integer, SBSTopAsins>> analysisFileAgainstIog2GlMap(
BufferedReader reader,
HashMap<Integer, HashMap<Integer, TreeMap<String, AsinDetailsSBSFields>>> iog2glOrig,
int threshold) throws IOException {
HashMap<Integer, HashMap<Integer, SBSTopAsins>> iog2glResult = new HashMap<Integer, HashMap<Integer, SBSTopAsins>>(
512);
String asindetailsLine = reader.readLine();
while ((asindetailsLine = reader.readLine()) != null) {
AsinDetailLine asinFromLine = new AsinDetailLine(asindetailsLine);
Integer iog = asinFromLine.getIOG();
Integer gl = asinFromLine.getGl();
AsinDetailsSBSFields asinSBS = getAsinDetailsSBSFromIog2GlMap(iog2glOrig, asinFromLine);
asinSBS.sbsAsin = AsinDetailsSBSFields.getInstance(asinFromLine);
HashMap<Integer, SBSTopAsins> gl2TopAsin = iog2glResult.get(iog);
if (gl2TopAsin == null) {
gl2TopAsin = new HashMap<Integer, SBSTopAsins>(512);
iog2glResult.put(iog, gl2TopAsin);
}
SBSTopAsins sbsTipAsin = gl2TopAsin.get(gl);
if (sbsTipAsin == null) {
sbsTipAsin = new SBSTopAsins(threshold);
gl2TopAsin.put(gl, sbsTipAsin);
}
sbsTipAsin.addTopAsin(asinSBS);
}
return iog2glResult;
}
private static void outputSBSResult(
HashMap<Integer, HashMap<Integer, SBSTopAsins>> iog2glSBSResult, PrintWriter output) {
String iog = null;
String gl = null;
String asin = null;
String totalInventoryOrig = null;
String totalInventoryNew = null;
String totalUnhealthyOrig = null;
String totalUnhealthyNew = null;
String tipOrig = null;
String tipNew = null;
String cartonOrig = null;
String cartonNew = null;
String diff = null;
String format = "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s";
for (Integer iogKey : iog2glSBSResult.keySet()) {
output.println("ASIN,GL,IOG,Diff,Total Inventory Orig,Total Inventory New,Total Unhealthy Orig,Total Unhealthy New,TIP Orig,TIP New,Carton Orig,Carton New");
HashMap<Integer, SBSTopAsins> gl2TopAsin = iog2glSBSResult.get(iogKey);
iog = String.valueOf(iogKey);
for (Integer glKey : gl2TopAsin.keySet()) {
gl = String.valueOf(glKey);
SBSTopAsins tipAsins = gl2TopAsin.get(glKey);
for (Entry<Integer, LinkedList<AsinDetailsSBSFields>> entry : tipAsins.topAsins
.entrySet()) {
diff = String.valueOf(entry.getKey());
LinkedList<AsinDetailsSBSFields> asins = entry.getValue();
for (AsinDetailsSBSFields asinSBS : asins) {
asin = asinSBS.asin;
totalInventoryOrig = String.valueOf(asinSBS.totalInventory);
totalInventoryNew = String.valueOf(asinSBS.sbsAsin.totalInventory);
totalUnhealthyOrig = String.valueOf(asinSBS.totalUnhealthy);
totalUnhealthyNew = String.valueOf(asinSBS.sbsAsin.totalInventory);
tipOrig = String.valueOf(asinSBS.tip);
tipNew = String.valueOf(asinSBS.sbsAsin.tip);
cartonOrig = String.valueOf(asinSBS.carton);
cartonNew = String.valueOf(asinSBS.sbsAsin.carton);
String line = String.format(format, asin, gl, iog, diff,
totalInventoryOrig, totalInventoryNew, totalUnhealthyOrig,
totalUnhealthyNew, tipNew, tipOrig, cartonOrig, cartonNew);
output.println(line);
}
}
}
}
output.flush();
output.close();
}
private static AsinDetailsSBSFields getAsinDetailsSBSFromIog2GlMap(
HashMap<Integer, HashMap<Integer, TreeMap<String, AsinDetailsSBSFields>>> iog2gl,
AsinDetailLine asindetail) {
Integer iog = asindetail.getIOG();
Integer gl = asindetail.getGl();
String asin = asindetail.getAsin();
HashMap<Integer, TreeMap<String, AsinDetailsSBSFields>> gl2asin = iog2gl.get(iog);
if (gl2asin == null) {
return null;
}
TreeMap<String, AsinDetailsSBSFields> asin2AsinSBS = gl2asin.get(gl);
if (asin2AsinSBS == null) {
return null;
}
return asin2AsinSBS.get(asin);
}
private static HashMap<Integer, HashMap<Integer, TreeMap<String, AsinDetailsSBSFields>>> buildTree(
BufferedReader reader) throws IOException {
long start = System.currentTimeMillis();
int count = 0;
HashMap<Integer, HashMap<Integer, TreeMap<String, AsinDetailsSBSFields>>> iog2gl = new HashMap<Integer, HashMap<Integer, TreeMap<String, AsinDetailsSBSFields>>>(
512);
String asindetailsLine = reader.readLine();
AsinDetailsSBSFields temp = null;
while ((asindetailsLine = reader.readLine()) != null) {
AsinDetailLine asinFromLine = new AsinDetailLine(asindetailsLine);
Integer iog = asinFromLine.getIOG();
Integer gl = asinFromLine.getGl();
String asin = asinFromLine.getAsin();
HashMap<Integer, TreeMap<String, AsinDetailsSBSFields>> gl2asin = iog2gl.get(iog);
if (gl2asin == null) {
gl2asin = new HashMap<Integer, TreeMap<String, AsinDetailsSBSFields>>(512);
iog2gl.put(iog, gl2asin);
}
TreeMap<String, AsinDetailsSBSFields> asin2AsinSBS = gl2asin.get(gl);
if (asin2AsinSBS == null) {
asin2AsinSBS = new TreeMap<String, AsinDetailsSBSFields>();
gl2asin.put(gl, asin2AsinSBS);
}
if (temp == null) {
temp = AsinDetailsSBSFields.getInstance(asinFromLine);
} else {
temp.fillInstance(asinFromLine);
}
temp = asin2AsinSBS.put(asin, temp);
count++;
if (count % 100000 == 0) {
System.out.println("Build Tree Processed " + count + " lines...");
}
if (count == 2000000) {
System.out.println("Time consumed:" + ((System.currentTimeMillis() - start) / 1000)
+ "s");
System.exit(0);
}
}
System.out.println("Time consumed:" + ((System.currentTimeMillis() - start) / 1000) + "s");
summerizeIog2GlMap(iog2gl);
return iog2gl;
}
private static void summerizeIog2GlMap(
HashMap<Integer, HashMap<Integer, TreeMap<String, AsinDetailsSBSFields>>> iog2gl) {
int count = 0;
for (Integer i : iog2gl.keySet()) {
System.out.println("IOG:" + i);
System.out.println("GL, Asin Count");
HashMap<Integer, TreeMap<String, AsinDetailsSBSFields>> gl2asin = iog2gl.get(i);
for (Integer j : gl2asin.keySet()) {
TreeMap<String, AsinDetailsSBSFields> asin2AsinSBS = gl2asin.get(j);
System.out.print(j + ", ");
System.out.print(asin2AsinSBS.size());
count += asin2AsinSBS.size();
}
}
System.out.println();
System.out.println("Total Group count of IOG-GL-ASIN:" + count);
}
}
class SBSTopAsins {
int topNumber;
TreeMap<Integer, LinkedList<AsinDetailsSBSFields>> topAsins = new TreeMap<Integer, LinkedList<AsinDetailsSBSFields>>();
public SBSTopAsins(int topNumber) {
this.topNumber = topNumber;
}
public boolean addTopAsin(AsinDetailsSBSFields asinSBS) {
int diff = asinSBS.getUnhealthyDiff();
if (topAsins.size() == topNumber) {
int miniDiff = topAsins.firstKey();
if (diff < miniDiff) {
return false;
} else if (diff == miniDiff) {
topAsins.get(miniDiff).add(asinSBS);
return true;
} else if (diff > miniDiff) {
topAsins.remove(miniDiff);
}
}
LinkedList<AsinDetailsSBSFields> diffList = topAsins.get(diff);
if (diffList == null) {
diffList = new LinkedList<AsinDetailsSBSFields>();
topAsins.put(diff, diffList);
}
diffList.add(asinSBS);
return true;
}
}
class AsinDetailsSBSFields {
public static AsinDetailsSBSFields getInstance(AsinDetailLine asindetail) {
AsinDetailsSBSFields ret = new AsinDetailsSBSFields();
ret.fillInstance(asindetail);
return ret;
}
public void fillInstance(AsinDetailLine asindetail) {
asin = asindetail.getAsin();
carton = asindetail.getCartonQuantity();
tip = asindetail.getTargetInventory();
totalInventory = asindetail.getTotalInventory();
totalUnhealthy = asindetail.getTotalUnhealthy();
}
String asin;
int totalInventory;
int totalUnhealthy;
int carton;
int tip;
AsinDetailsSBSFields sbsAsin;
public int getUnhealthyDiff() {
return Math.abs(this.totalUnhealthy - sbsAsin.totalUnhealthy);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((asin == null) ? 0 : asin.hashCode());
result = prime * result + carton;
result = prime * result + tip;
result = prime * result + totalInventory;
result = prime * result + totalUnhealthy;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AsinDetailsSBSFields other = (AsinDetailsSBSFields) obj;
if (asin == null) {
if (other.asin != null)
return false;
} else if (!asin.equals(other.asin))
return false;
if (carton != other.carton)
return false;
if (tip != other.tip)
return false;
if (totalInventory != other.totalInventory)
return false;
if (totalUnhealthy != other.totalUnhealthy)
return false;
return true;
}
@Override
public String toString() {
return "AsinDetailsSBSFields [asin=" + asin + ", totalInventory=" + totalInventory
+ ", totalUnhealthy=" + totalUnhealthy + ", carton=" + carton + ", tip=" + tip
+ "]";
}
}
class AsinDetailLine {
public static final int Asin = 0;
public static final int Iog = 1;
public static final int Gl = 2;
public static final int Target_Inventory_Level = 3;
public static final int Total_Inventory = 4;
public static final int Weekly_Forecast_Demand = 5;
public static final int Weekly_Cptl_Holding_Cost = 6;
public static final int One_Week_Historic_Demand = 7;
public static final int Two_Weeks_Historic_Demand = 8;
public static final int Three_Weeks_Historic_Demand = 9;
public static final int Four_Weeks_Historic_Demand = 10;
public static final int One_Year_Historic_Demand = 11;
public static final int Our_Price = 12;
public static final int Cost_Used_For_Calculations = 13;
public static final int Vendor_Cost = 14;
public static final int Retail_Contribution = 15;
public static final int Return_Contribution = 16;
public static final int Title_Description = 17;
public static final int Cube = 18;
public static final int Publication_Date = 19;
public static final int Release_Date = 20;
public static final int Sort_Type = 21;
public static final int Upc = 22;
public static final int Is_Unprep_Required = 23;
public static final int Allocated_Inventory = 24;
public static final int In_Process_Inventory = 25;
public static final int Unsellable_Inventory = 26;
public static final int Warehouse = 27;
public static final int Vendor = 28;
public static final int Order_Type = 29;
public static final int Removal_Type = 30;
public static final int Weekly_Fc_Holding_Cost = 31;
public static final int Fc_Receipt_Cost = 32;
public static final int Fc_Removal_Cost = 33;
public static final int Removal_Amount = 34;
public static final int Total_Savings = 35;
public static final int Unhealthy_Quantity = 36;
public static final int Healthy_Quantity = 37;
public static final int Dsi_Id = 38;
public static final int Receipt_Date = 39;
public static final int Cannot_Return_Before = 40;
public static final int Must_Return_Before = 41;
public static final int Do_Id = 42;
public static final int Ds_Id = 43;
public static final int Do_Date = 44;
public static final int Ds_Date = 45;
public static final int Distributor_Price = 46;
public static final int Distributor_Cost = 47;
public static final int Exclusion_Reason = 48;
public static final int Excluded_Vendor = 49;
public static final int Excluded_Order_Type = 50;
public static final int Excluded_Removal_Type = 51;
public static final int Excluded_Removal_Amount = 52;
public static final int Excluded_Total_Savings = 53;
public static final int Excluded_Unhealthy_Quantity = 54;
public static final int Excluded_Dsi_Id = 55;
public static final int Excluded_Receipt_Date = 56;
public static final int Excluded_Cannot_Return_Before = 57;
public static final int Excluded_Must_Return_Before = 58;
public static final int Excluded_Do_Id = 59;
public static final int Excluded_Ds_Id = 60;
public static final int Excluded_Do_Date = 61;
public static final int Excluded_Ds_Date = 62;
public static final int Excluded_Distributor_Price = 63;
public static final int Excluded_Distributor_Cost = 64;
public static final int Category = 65;
public static final int Subcategory = 66;
public static final int Markdown_Quantity = 67;
public static final int Markdown_Duration = 68;
public static final int Markdown_Price = 69;
public static final int Markdown_Demand_Factor = 70;
public static final int Elasticity = 71;
public static final int Total_Healthy_Quantity = 72;
public static final int Total_Unhealthy_Quantity = 73;
public static final int Total_Healthy_Woc = 74;
public static final int Total_Woc = 75;
public static final int Warehouse_Quantity = 76;
public static final int Is_Owoc = 77;
public static final int Vendor_Name = 78;
public static final int Ship_To_Name = 79;
public static final int Ship_To_Address_Line_1 = 80;
public static final int Ship_To_Address_Line_2 = 81;
public static final int Ship_To_Address_Line_3 = 82;
public static final int Ship_To_Address_City = 83;
public static final int Ship_To_Address_State = 84;
public static final int Ship_To_Address_Province = 85;
public static final int Ship_To_Address_Postal_Code = 86;
public static final int Ship_To_Address_Country_Code = 87;
public static final int Ean = 88;
public static final int List_Price = 89;
public static final int Map_Price = 90;
public static final int Is_Map_Required = 91;
public static final int Publisher_Code = 92;
public static final int Total_Retail_Healthy = 93;
public static final int Total_Retail_Savings = 94;
public static final int Cost_Used_For_Reporting = 95;
public static final int Parent_Asin = 96;
public static final int Replenishment_Category = 97;
public static final int Child_Asin = 98;
public static final int Bundle_Quantity = 99;
public static final int Is_Forced_Markdown = 100;
public static final int Mean_Age = 101;
public static final int Is_Deadwood = 102;
public static final int Fcsku = 103;
public static final int Expiration_Date = 104;
public static final int Realm = 105;
public static final int Is_Authorization_Required = 106;
public static final int Carton_Quantity = 107;
public static final int Forecast1 = 108;
public static final int Forecast2 = 109;
public static final int Forecast3 = 110;
public static final int Forecast4 = 111;
public static final int Forecast5 = 112;
public static final int Forecast6 = 113;
public static final int Forecast7 = 114;
public static final int Forecast8 = 115;
public static final int Forecast9 = 116;
public static final int Forecast10 = 117;
public static final int Forecast11 = 118;
public static final int Forecast12 = 119;
public static final int Forecast13 = 120;
public static final int Forecast14 = 121;
public static final int Forecast15 = 122;
public static final int Forecast16 = 123;
public static final int Forecast17 = 124;
public static final int Forecast18 = 125;
public static final int Forecast19 = 126;
public static final int Forecast20 = 127;
public static final int Forecast21 = 128;
public static final int Forecast22 = 129;
public static final int Forecast23 = 130;
public static final int Forecast24 = 131;
public static final int Forecast25 = 132;
public static final int Forecast26 = 133;
public static final int Forecast27 = 134;
public static final int Forecast28 = 135;
public static final int Forecast29 = 136;
public static final int Forecast30 = 137;
public static final int Forecast31 = 138;
public static final int Forecast32 = 139;
public static final int Forecast33 = 140;
String[] row;
public AsinDetailLine(String line) {
this(line.split(","));
}
public AsinDetailLine(String[] row) {
for (int i = 0; i < row.length; i++) {
// This is needed to avoid OOO
row[i] = new String(row[i]);
}
this.row = row;
}
public void clear() {
for (int i = 0; i < row.length; i++) {
// help GC
row[i] = null;
}
}
public int getIOG() {
return Integer.parseInt(row[Iog]);
}
public int getGl() {
return Integer.parseInt(row[Gl]);
}
public String getAsin() {
return row[Asin];
}
public String getCategory() {
return row[Category];
}
public String getSubcategory() {
return row[Subcategory];
}
public int getTotalInventory() {
return getRealIntFromString(row[Total_Inventory]);
}
public int getTotalUnhealthy() {
return getRealIntFromString(row[Total_Unhealthy_Quantity]);
}
public int getTotalHealthy() {
return getRealIntFromString(row[Total_Healthy_Quantity]);
}
public int getTargetInventory() {
return getRealIntFromString(row[Target_Inventory_Level]);
}
public int getCartonQuantity() {
return getRealIntFromString(row[Carton_Quantity]);
}
private int getRealIntFromString(String str) {
return Math.round(Float.parseFloat(str));
}
}