Package com.aicontest.visualizer

Source Code of com.aicontest.visualizer.ExecutionUnitQueue$Itr

package com.aicontest.visualizer;

import java.util.AbstractQueue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.NoSuchElementException;
import java.util.PriorityQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

import com.aicontest.visualizer.js.tasks.DelayedExecutionUnit;
import com.aicontest.visualizer.js.tasks.EventExecutionUnit;
import com.aicontest.visualizer.js.tasks.IExecutionUnit;

public class ExecutionUnitQueue extends AbstractQueue<IExecutionUnit> implements
    BlockingQueue<IExecutionUnit> {

  private transient final ReentrantLock lock = new ReentrantLock();
  private transient final Condition available = lock.newCondition();
  private final LinkedList<EventExecutionUnit> immediate = new LinkedList<EventExecutionUnit>();
  private final PriorityQueue<DelayedExecutionUnit> delayed = new PriorityQueue<DelayedExecutionUnit>();

  public void put(IExecutionUnit eu) {
    offer(eu);
  }

  public boolean offer(IExecutionUnit eu, long timeout, TimeUnit unit) {
    return offer(eu);
  }

  public boolean offer(IExecutionUnit eu) {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
      if (eu instanceof DelayedExecutionUnit) {
        DelayedExecutionUnit deu = (DelayedExecutionUnit) eu;
        DelayedExecutionUnit first = delayed.peek();
        delayed.offer(deu);
        if (first == null || deu.compareTo(first) < 0)
          available.signalAll();
      } else {
        immediate.offer((EventExecutionUnit) eu);
        available.signalAll();
      }
      return true;
    } finally {
      lock.unlock();
    }
  }

  public IExecutionUnit poll() {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
      IExecutionUnit eu = immediate.peek();
      if (eu == null) {
        DelayedExecutionUnit deu = delayed.peek();
        if (deu == null || deu.getDelay(TimeUnit.NANOSECONDS) > 0) {
          return null;
        } else {
          IExecutionUnit x = delayed.poll();
          assert x != null;
          if (delayed.size() != 0)
            available.signalAll();
          return x;
        }
      } else {
        IExecutionUnit x = immediate.poll();
        assert x != null;
        if (immediate.size() != 0)
          available.signalAll();
        return x;
      }
    } finally {
      lock.unlock();
    }
  }

  public IExecutionUnit take() throws InterruptedException {
    final ReentrantLock lock = this.lock;
    lock.lockInterruptibly();
    try {
      for (;;) {
        IExecutionUnit eu = immediate.peek();
        if (eu != null) {
          IExecutionUnit x = immediate.poll();
          assert x != null;
          if (immediate.size() != 0)
            available.signalAll();
          return x;
        }
        DelayedExecutionUnit deu = delayed.peek();
        if (deu != null) {
          long delay = deu.getDelay(TimeUnit.NANOSECONDS);
          if (delay > 0) {
            available.awaitNanos(delay);
          } else {
            IExecutionUnit x = delayed.poll();
            assert x != null;
            if (delayed.size() != 0)
              available.signalAll(); // wake up other takers
            return x;
          }
        } else {
          available.await();
        }
      }
    } finally {
      lock.unlock();
    }
  }

  public IExecutionUnit poll(long timeout, TimeUnit unit)
      throws InterruptedException {
    long nanos = unit.toNanos(timeout);
    final ReentrantLock lock = this.lock;
    lock.lockInterruptibly();
    try {
      for (;;) {
        IExecutionUnit eu = immediate.peek();
        if (eu != null) {
          IExecutionUnit x = immediate.poll();
          assert x != null;
          if (immediate.size() != 0)
            available.signalAll();
          return x;
        }
        DelayedExecutionUnit deu = delayed.peek();
        if (deu == null) {
          if (nanos <= 0)
            return null;
          else
            nanos = available.awaitNanos(nanos);
        } else {
          long delay = deu.getDelay(TimeUnit.NANOSECONDS);
          if (delay > 0) {
            if (nanos <= 0)
              return null;
            if (delay > nanos)
              delay = nanos;
            long timeLeft = available.awaitNanos(delay);
            nanos -= delay - timeLeft;
          } else {
            IExecutionUnit x = delayed.poll();
            assert x != null;
            if (delayed.size() != 0)
              available.signalAll();
            return x;
          }
        }
      }
    } finally {
      lock.unlock();
    }
  }

  public IExecutionUnit peek() {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
      IExecutionUnit eu = immediate.peek();
      if (eu != null) {
        return eu;
      }
      return delayed.peek();
    } finally {
      lock.unlock();
    }
  }

  public int size() {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
      return immediate.size() + delayed.size();
    } finally {
      lock.unlock();
    }
  }

  public int drainTo(Collection<? super IExecutionUnit> c) {
    if (c == null)
      throw new NullPointerException();
    if (c == this)
      throw new IllegalArgumentException();
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
      c.addAll(immediate);
      int n = immediate.size();
      immediate.clear();
      int i = n;
      for (;;) {
        DelayedExecutionUnit first = delayed.peek();
        if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
          break;
        c.add(delayed.poll());
        ++n;
      }
      if (n > i)
        available.signalAll();
      return n;
    } finally {
      lock.unlock();
    }
  }

  public int drainTo(Collection<? super IExecutionUnit> c, int maxElements) {
    if (c == null)
      throw new NullPointerException();
    if (c == this)
      throw new IllegalArgumentException();
    if (maxElements <= 0)
      return 0;
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
      int n;
      if (immediate.size() > maxElements) {
        n = 0;
        while (n < maxElements) {
          c.add(immediate.poll());
          ++n;
        }
      } else {
        c.addAll(immediate);
        n = immediate.size();
        immediate.clear();
        int i = n;
        while (n < maxElements) {
          DelayedExecutionUnit first = delayed.peek();
          if (first == null
              || first.getDelay(TimeUnit.NANOSECONDS) > 0)
            break;
          c.add(delayed.poll());
          ++n;
        }
        if (n > i)
          available.signalAll();
      }
      return n;
    } finally {
      lock.unlock();
    }
  }

  public void clear() {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
      immediate.clear();
      delayed.clear();
    } finally {
      lock.unlock();
    }
  }

  public int remainingCapacity() {
    return Integer.MAX_VALUE;
  }

  public Object[] toArray() {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
      ArrayList<IExecutionUnit> al = new ArrayList<IExecutionUnit>(
          immediate.size() + delayed.size());
      al.addAll(immediate);
      al.addAll(delayed);
      return al.toArray();
    } finally {
      lock.unlock();
    }
  }

  public <T> T[] toArray(T[] a) {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
      ArrayList<IExecutionUnit> al = new ArrayList<IExecutionUnit>(
          immediate.size() + delayed.size());
      al.addAll(immediate);
      al.addAll(delayed);
      return al.toArray(a);
    } finally {
      lock.unlock();
    }
  }

  public boolean remove(Object o) {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
      return immediate.remove(o) || delayed.remove(o);
    } finally {
      lock.unlock();
    }
  }

  public Iterator<IExecutionUnit> iterator() {
    return new Itr(toArray());
  }

  private class Itr implements Iterator<IExecutionUnit> {
    final Object[] array;
    int cursor;
    int lastRet;

    Itr(Object[] array) {
      lastRet = -1;
      this.array = array;
    }

    public boolean hasNext() {
      return cursor < array.length;
    }

    public IExecutionUnit next() {
      if (cursor >= array.length)
        throw new NoSuchElementException();
      lastRet = cursor;
      return (IExecutionUnit) array[cursor++];
    }

    public void remove() {
      if (lastRet < 0)
        throw new IllegalStateException();
      Object x = array[lastRet];
      lastRet = -1;
      lock.lock();
      try {
        for (Iterator<?> it = immediate.iterator(); it.hasNext();) {
          if (it.next() == x) {
            it.remove();
            return;
          }
        }
        for (Iterator<?> it = delayed.iterator(); it.hasNext();) {
          if (it.next() == x) {
            it.remove();
            return;
          }
        }
      } finally {
        lock.unlock();
      }
    }
  }

  public void compressEvent(EventExecutionUnit task) {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
      Iterator<EventExecutionUnit> it = immediate.iterator();
      while (it.hasNext()) {
        EventExecutionUnit eeu = it.next();
        if (eeu.matches(task))
          it.remove();
      }
      immediate.offer(task);
      available.signalAll();
    } finally {
      lock.unlock();
    }
  }
}
TOP

Related Classes of com.aicontest.visualizer.ExecutionUnitQueue$Itr

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.