- producer links are moved to an "advanced" page, not intended for normal
[mir.git] / source / mircoders / global / JobQueue.java
index ab23c0f..34dd7b0 100755 (executable)
@@ -37,82 +37,158 @@ import java.util.*;
 
 public class JobQueue {
   private Vector jobs;
+  private Vector finishedJobs;
   private Map dataToJob;
+  private Map identifierToJob;
+  private int nrJobs;
 
   public static final int STATUS_PENDING = 0;
   public static final int STATUS_PROCESSING = 1;
   public static final int STATUS_PROCESSED = 2;
+  public static final int STATUS_CANCELLED = 3;
+  public static final int STATUS_ABORTED = 4;
+
+  public static final int PRIORITY_NORMAL = 100;
+  public static final int PRIORITY_LOW = 10;
+  public static final int PRIORITY_HIGH = 1000;
+
+  public static final int FINISHEDJOBS_LOGSIZE = 10;
 
   public JobQueue() {
+    finishedJobs = new Vector();
     jobs = new Vector();
     dataToJob = new HashMap();
+    identifierToJob = new HashMap();
+    nrJobs = 0;
   }
 
-  public void appendJob(Object aData) {
+  public String appendJob(Object aData) {
     synchronized (jobs) {
-      Job job = new Job(aData);
+      Job job = new Job(aData, Integer.toString(nrJobs));
+      nrJobs++;
       jobs.add(job);
       dataToJob.put(aData, job);
+      identifierToJob.put(job.getIdentifier(), job);
+      return job.getIdentifier();
     }
   }
 
   public Object acquirePendingJob() {
     synchronized (jobs) {
-      Iterator i = jobs.iterator();
+      int priorityFound= 0;
+      Job jobFound;
 
-      while (i.hasNext()) {
-        Job job = (Job) i.next();
+      do {
+        jobFound = null;
+        Iterator i = jobs.iterator();
+        while (i.hasNext()) {
+          Job job = (Job) i.next();
 
-        if (job.setProcessing()) {
-          return job.getData();
+          if (job.isPending() && (jobFound==null || priorityFound<job.getPriority())) {
+            jobFound = job;
+            priorityFound = job.getPriority();
+          }
         }
       }
+      while (jobFound!=null && !jobFound.setProcessing());
+
+      if (jobFound!=null)
+        return jobFound.getData();
+      else
+        return null;
     }
+  }
 
-    return null;
+  private void finishJob(Job aJob) {
+    synchronized (jobs) {
+      identifierToJob.remove(aJob.identifier);
+      jobs.remove(aJob);
+      finishedJobs.insertElementAt(aJob, 0);
+      if (finishedJobs.size()>FINISHEDJOBS_LOGSIZE)
+        finishedJobs.remove(finishedJobs.size()-1);
+    }
   }
 
-  public void flagOffJob(Object aData) {
+  public void jobProcessed(Object aData) {
     synchronized (jobs) {
       Job job = (Job) dataToJob.get(aData);
 
       if (job!=null) {
         job.setProcessed();
+        finishJob(job);
       }
     }
   }
 
-  public void cleanupJobs() {
+  public void jobAborted(Object aData) {
     synchronized (jobs) {
-      Iterator i = jobs.iterator();
+      Job job = (Job) dataToJob.get(aData);
 
-      while (i.hasNext()) {
-        Job job = (Job) i.next();
+      if (job!=null) {
+        job.setAborted();
+        finishJob(job);
+      }
+    }
+  }
 
-        if (job.hasBeenProcessed()) {
-          i.remove();
-        }
+  public void cancelJob(Object aData) {
+    synchronized (jobs) {
+      Job job = (Job) dataToJob.get(aData);
+
+      if (job!=null && job.setCancelled()) {
+        finishJob(job);
       }
     }
   }
 
+  public void makeJobListSnapshots(List aJobList, List aFinishedJobList) {
+    synchronized (jobs) {
+      aJobList.addAll(makeJobListSnapshot());
+      aFinishedJobList.addAll(makeFinishedJobListSnapshot());
+    }
+  }
+
   public List makeJobListSnapshot() {
     synchronized (jobs) {
       return (List) jobs.clone();
     }
   }
 
+  public List makeFinishedJobListSnapshot() {
+    synchronized (jobs) {
+      return (List) finishedJobs.clone();
+    }
+  }
+
   public class Job implements Cloneable {
     private Object data;
+    private Date lastChange;
+    private String identifier;
     private int status;
+    private int priority;
 
-    public Job(Object aData, int aStatus) {
+    public Job(Object aData, String anIdentifier, int aStatus, int aPriority, Date aLastChange) {
       data = aData;
       status = aStatus;
+      identifier = anIdentifier;
+      priority = aPriority;
+      lastChange = aLastChange;
+    }
+
+    public Job(Object aData, String anIdentifier, int aStatus, int aPriority) {
+      this(aData, anIdentifier, aStatus, aPriority, (new GregorianCalendar()).getTime());
+    }
+
+    public Date getLastChange() {
+      return lastChange;
+    }
+
+    public String getIdentifier() {
+      return identifier;
     }
 
-    public Job(Object aData) {
-      this(aData, STATUS_PENDING);
+    public Job(Object aData, String anIdentifier) {
+      this(aData, anIdentifier, STATUS_PENDING, PRIORITY_NORMAL);
     }
 
     public Object getData() {
@@ -125,6 +201,10 @@ public class JobQueue {
       }
     }
 
+    public int getPriority() {
+      return priority;
+    }
+
     protected boolean setProcessing() {
       return setStatus(STATUS_PENDING, STATUS_PROCESSING);
     }
@@ -133,10 +213,30 @@ public class JobQueue {
       setStatus(STATUS_PROCESSING, STATUS_PROCESSED);
     }
 
+    protected void setAborted() {
+      setStatus(STATUS_PROCESSING, STATUS_ABORTED);
+    }
+
+    protected boolean setCancelled() {
+      return setStatus(STATUS_PENDING, STATUS_CANCELLED);
+    }
+
     public boolean hasBeenProcessed() {
       return getStatus() == STATUS_PROCESSED;
     }
 
+    public boolean hasBeenAborted() {
+      return getStatus() == STATUS_ABORTED;
+    }
+
+    public boolean isCancelled() {
+      return getStatus() == STATUS_CANCELLED;
+    }
+
+    public boolean isFinished() {
+      return hasBeenProcessed() || hasBeenAborted() || isCancelled();
+    }
+
     public boolean isProcessing() {
       return getStatus() == STATUS_PROCESSING;
     }
@@ -149,6 +249,7 @@ public class JobQueue {
       synchronized(this) {
         if (status == anOldStatus) {
           status = aNewStatus;
+          lastChange = (new GregorianCalendar()).getTime();
           return true;
         }
         else {
@@ -159,7 +260,8 @@ public class JobQueue {
 
     protected Object clone() {
       synchronized(this) {
-        return new Job(data, status);
+        System.out.println("  blabla");
+        return new Job(data, identifier, status, priority, lastChange);
       }
     }
   }