1

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.

  • Without having read through your code: the standard solution is to remove the print job from the priority queue, change its priority and then insert it into the queue again. – Ole V.V. Dec 15 '16 at 14:44
  • See [Priority queue with dynamic item priorities](http://stackoverflow.com/questions/2288241/priority-queue-with-dynamic-item-priorities). – Ole V.V. Dec 15 '16 at 14:45
  • Ok but how can I remove an item from they priority queue ? –  Dec 15 '16 at 14:45
  • Well, you wrote the code … Does this link help? [How to remove elements from a binary heap?](http://stackoverflow.com/questions/12233809/how-to-remove-elements-from-a-binary-heap) – Ole V.V. Dec 15 '16 at 14:48

0 Answers0