import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; public class Scheduler2 { private static final int MAX_OVERLAPPED_CONTENTS = 3; public Scheduler2() { // TODO Auto-generated constructor stub } public static enum Type { start, end } public static class TimeNode { public static List<TimeNode> constructNodes(ScheduleRequest scheduleRequest, int index) { List<TimeNode> timeNodes = new ArrayList<>(2); timeNodes.add(new TimeNode(index, scheduleRequest.id, scheduleRequest.startTime, Type.start)); timeNodes.add(new TimeNode(index, scheduleRequest.id, scheduleRequest.endTime, Type.end)); return timeNodes; } private final int index; private final String id; private final int time; private final Type type; private TimeNode(int index, String id, int time, Type type) { this.index = index; this.id = id; this.time = time; this.type = type; } public int getIndex() { return index; } public String getId() { return id; } public int getTime() { return time; } public Type getType() { return type; } public final static Comparator<TimeNode> timeComparator = new Comparator<TimeNode>() { public int compare(TimeNode t1, TimeNode t2) { //TODO should compareTo do null check? if (t1.getTime() == t2.getTime()) { if (t1.getType() == Type.start) { return -1; } else { return 1; } } return t1.getTime() - t2.getTime(); } }; } public static List<ScheduleRequest> schedule() { //TODO for 1 area only now List<ScheduleRequest> scheduleRequests = readCommercials(); if (scheduleRequests == null || scheduleRequests.size() == 0) { return new ArrayList<ScheduleRequest>(); } //split it into start end time List<TimeNode> timeNodes = new LinkedList<>(); //TODO sort performance on LinkedList and ArrayList for (int i = 0; i < scheduleRequests.size(); i++) { if (scheduleRequests.get(i) != null) { timeNodes.addAll(TimeNode.constructNodes(scheduleRequests.get(i), i)); } } //sort nodes according to time Collections.sort(timeNodes, TimeNode.timeComparator); List<ScheduleRequest> resultCommercials = new LinkedList<>(); List<ScheduleRequest> toRemoveCommercials = new LinkedList<>(); //TODO //a HashMap to maintain during scan, the String is the ID and the Integer is //the index of the Content in the Contents Map<String, Integer> map = new HashMap<>(); //scan the sorted timeNodes for (TimeNode node : timeNodes) { if (node.getType() == Type.start) { //this node represent a start time if (map.containsKey(node.getId())) { //id conflicts //TODO may change remove policy here //Remove policy: remove latest coming toRemoveCommercials.add(scheduleRequests.get(node.getIndex())); } else if (map.keySet().size() == MAX_OVERLAPPED_CONTENTS){ //at current point the set of overlapped contents is oversized //TODO may change remove policy here toRemoveCommercials.add(scheduleRequests.get(node.getIndex())); } else { //this node is selected into this point resultCommercials.add(scheduleRequests.get(node.getIndex())); } } else { //this node represent an end time if (map.containsKey(node.getId()) && map.get(node.getId()) == node.index) { //the corresponded start time is actually in the map map.remove(node.id); } } } //Output IO.writeAds(resultCommercials); return null; } public static List<ScheduleRequest> readCommercials() { List<ScheduleRequest> list = new LinkedList<>(); ScheduleRequest ad = null; while ((ad = IO.readAd()) != null) { list.add(ad); } return list; } }
时间: 2024-12-28 21:18:57