/** * Licensed under the terms of the Apache License 2.0. Please see LICENSE file in the project root for terms. */ package apex.benchmark; import java.util.*; import com.datatorrent.api.DefaultOutputPort; import com.datatorrent.api.InputOperator; import com.datatorrent.common.util.BaseOperator; public class EventGenerator extends BaseOperator implements InputOperator { public final transient DefaultOutputPort<String> out = new DefaultOutputPort<String>(); private int adsIdx = 0; private int eventsIdx = 0; private StringBuilder sb = new StringBuilder(); private String pageID = UUID.randomUUID().toString(); private String userID = UUID.randomUUID().toString(); private final String[] eventTypes = new String[]{"view", "click", "purchase"}; private List<Integer> ads; private final Map<Integer, List<Integer>> campaigns; public EventGenerator() { this.campaigns = generateCampaigns(); this.ads = flattenCampaigns(); } public Map<Integer, List<Integer>> getCampaigns() { return campaigns; } /** * Generate a single element */ public String generateElement() { if (adsIdx == ads.size()) { adsIdx = 0; } if (eventsIdx == eventTypes.length) { eventsIdx = 0; } sb.setLength(0); sb.append("{\"user_id\":\""); sb.append(pageID); sb.append("\",\"page_id\":\""); sb.append(userID); sb.append("\",\"ad_id\":\""); sb.append(ads.get(adsIdx++)); sb.append("\",\"ad_type\":\""); sb.append("banner78"); // value is immediately discarded. The original generator would put a string with 38/5 = 7.6 chars. We put 8. sb.append("\",\"event_type\":\""); sb.append(eventTypes[eventsIdx++]); sb.append("\",\"event_time\":\""); sb.append(System.currentTimeMillis()); sb.append("\",\"ip_address\":\"1.2.3.4\"}"); return sb.toString(); } /** * Generate a random list of ads and campaigns */ private Map<Integer, List<Integer>> generateCampaigns() { int numCampaigns = 100; int numAdsPerCampaign = 10; Random random = new Random(); Map<Integer, List<Integer>> adsByCampaign = new LinkedHashMap<>(); for (int i = 0; i < numCampaigns; i++) { Integer campaign = random.nextInt(); ArrayList<Integer> ads = new ArrayList<>(); adsByCampaign.put(campaign, ads); for (int j = 0; j < numAdsPerCampaign; j++) { ads.add(random.nextInt()); } } return adsByCampaign; } /** * Flatten into just ads */ private List<Integer> flattenCampaigns() { // Flatten campaigns into simple list of ads List<Integer> ads = new ArrayList<>(); for (Map.Entry<Integer, List<Integer>> entry : campaigns.entrySet()) { for (Integer ad : entry.getValue()) { ads.add(ad); } } return ads; } @Override public void emitTuples() { for (int index = 0; index < 100; ++index) { out.emit(generateElement()); } } }