I have created a priority queue implementation which I am using to simulate a print server. I also have a PrintJob for the items that are going to be printed.In this print server the smallest items (files to be printed) have the biggest priority. Although, sometimes the biggest files may wait too much time in the priority queue so what I am trying to do is : if a file waits in the priority queue for 15 seconds then change the priority. What's the best way to do this ?
My priority queue implementation is :
import java.util.Comparator;
public class MaxPQ<T> {
public T[] heap;
private int size;
protected Comparator<T> cmp;
public MaxPQ(int capacity, Comparator<T> cmp) {
if (capacity < 1) throw new IllegalArgumentException();
this.heap = (T []) new Object[capacity+1];
this.size = 0;
this.cmp = cmp;
}
MaxPQ() {}
private void swap(int i, int j) {
T tmp = heap[i];
heap[i] = heap[j];
heap[j] = tmp;
}
public void print() {
for (int i=1; i<=size; i++){
System.out.print(heap[i]+ "");
}
System.out.println();
}
boolean isEmpty(){
return size == 0;
}
public void insert(T object) {
if (object == null) throw new IllegalArgumentException();
if (size == heap.length - 1) throw new IllegalStateException();
if (size >= 0.75*heap.length) {
resize(2*heap.length);
}
heap[++size] = object;
swim(size);
}
public T getMax() {
if (size == 0) throw new IllegalStateException();
T object = heap[1];
if (size > 1) heap[1] = heap[size];
heap[size--] = null;
sink(1);
return object;
}
private void swim(int i) {
while (i > 1) { //if i root (i==1) return
int p = i/2; //find parent
int result = cmp.compare(heap[i], heap[p]); //compare parent with child
if (result <= 0) return; //if child <= parent return
swap(i, p); //else swap and i=p
i = p;
}
}
private void sink(int i){
int left = 2*i, right = left+1, max = left;
while (left <= size) {
if (right <= size) {
max = cmp.compare(heap[left], heap[right]) < 0 ? right : left;
}
if (cmp.compare(heap[i], heap[max]) >= 0) return;
swap(i, max);
i = max; left = 2*i; right = left+1; max = left;
}
}
private void resize(int newSize) {
Object[] newHeap = new Object[newSize];
System.arraycopy(heap, 0, newHeap, 0, size);
heap = (T[]) newHeap;
}
public int size(){
return size;
}
}
The printjob items contains the following fields : id , size(the size of the file),waitingtime(the time in the queue),arrivaltime(the arrival time in the print,priority)
Here is what I have done:
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import static java.lang.Double.min;
import java.util.ArrayList;
import java.util.Scanner;
public class AlgorithmC {
public static void runC() throws FileNotFoundException{
readFile("arxeia");
}
private static final int MAXSIZE = 128;
private int T = 0;
static ArrayList<PrintJob> printList = new ArrayList<>();
MaxPQ<PrintJob> printPQ = new MaxPQ<>();
public static void readFile(String filename) throws FileNotFoundException{
Scanner scanner = new Scanner(new File("filename.txt"));
int waitingTime = 0;
int r = 0;
while(scanner.hasNextInt()){
int size = scanner.nextInt();
int arrivalTime = scanner.nextInt();
PrintJob p = new PrintJob(size,waitingTime,arrivalTime,size);
printList.add(p);
}
for(int i = 0;i < printList.size(); i++){
if((printList.get(i).getArrivalTime()) <= (printList.get(i+1).getArrivalTime())){
r += 1;
}
}
if(r != (printList.size()) - 1){
System.out.println("Invalid file format!");
}
for(int i = 0;i < printList.size(); i++){
if((printList.get(i).getSize() < 0 || printList.get(i).getSize() > MAXSIZE )){
System.out.println("Invalid file size!");
}
}
}
public void storeFile(String filename){
BufferedWriter bw = null;
FileWriter fw = null;
try {
int i = 0;
fw = new FileWriter(filename);
bw = new BufferedWriter(fw);
T = printList.get(1).getArrivalTime();
bw.write("t = " + (T + printList.get(1).getSize()) + ",completed file" + printList.get(1).getid());
T = T + printList.get(1).getSize();
printList.remove(1);
for (PrintJob printItem : printList) {
printPQ.insert(printItem);
}
int size = printPQ.size();
int max = 0;
int tempID = 0;
int time = 0;
while(i < size){
PrintJob nextPrint = printPQ.getMax();
T = T + nextPrint.getSize();
bw.write("t = " + T + ",completed file" + printList.get(i).getid());
time =+ (T - nextPrint.getArrivalTime());
for(int j = 0; j < printPQ.size(); j++){
if((T-(printPQ.heap[j].getArrivalTime())) >= 15){
printPQ.heap[j].setPriority((int) min(127,printPQ.heap[j].getPriority() + printPQ.heap[j].getWaitingTime()));
}
}
nextPrint.setWaitingTime(time);
if(time > max){
max = time;
tempID = nextPrint.getid();
}
i =+ 1;
}
int averageWaitingTime = time/(size-1);
bw.write("Average waiting time = " + averageWaitingTime + " " );
bw.write("Maximum waiting time = " + max + "achieved by file " + tempID + " ");
}
catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bw != null)
bw.close();
if (fw != null)
fw.close();
}
catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
So when I change the priority I may ruin the heap structure.