Package com.google.dart.engine.internal.index.operation

Source Code of com.google.dart.engine.internal.index.operation.OperationQueue

/*
* Copyright (c) 2013, the Dart project authors.
*
* Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.dart.engine.internal.index.operation;

import com.google.common.collect.Lists;
import com.google.dart.engine.source.Source;
import com.google.dart.engine.utilities.translation.DartOmit;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
* Instances of the {@link OperationQueue} represent a queue of operations against the index that
* are waiting to be performed.
*
* @coverage dart.engine.index
*/
@DartOmit
public class OperationQueue {
  /**
   * The non-query operations that are waiting to be performed.
   */
  private final LinkedList<IndexOperation> nonQueryOperations = Lists.newLinkedList();

  /**
   * The query operations that are waiting to be performed.
   */
  private final LinkedList<IndexOperation> queryOperations = Lists.newLinkedList();

  /**
   * {@code true} if query operations should be returned by {@link #dequeue(long)} or {code false}
   * if not.
   */
  private boolean processQueries = true;

  /**
   * Initialize a newly created operation queue to be empty.
   */
  public OperationQueue() {
    super();
  }

  /**
   * If this queue is not empty, then remove the next operation from the head of this queue and
   * return it. If this queue is empty (see {@link #setProcessQueries(boolean)}, then the behavior
   * of this method depends on the value of the argument. If the argument is less than or equal to
   * zero (<code>0</code>), then {@code null} will be returned immediately. If the argument is
   * greater than zero, then this method will wait until at least one operation has been added to
   * this queue or until the given amount of time has passed. If, at the end of that time, this
   * queue is empty, then {@code null} will be returned. If this queue is not empty, then the first
   * operation will be removed and returned.
   * <p>
   * Note that {@code null} can be returned, even if a positive timeout is given.
   * <p>
   * Note too that this method's timeout is not treated the same way as the timeout value used for
   * {@link Object#wait(long)}. In particular, it is not possible to cause this method to wait for
   * an indefinite period of time.
   *
   * @param timeout the maximum number of milliseconds to wait for an operation to be available
   *          before giving up and returning {@code null}
   * @return the operation that was removed from the queue
   * @throws InterruptedException if the thread on which this method is running was interrupted
   *           while it was waiting for an operation to be added to the queue
   */
  public IndexOperation dequeue(long timeout) throws InterruptedException {
    synchronized (nonQueryOperations) {
      if (nonQueryOperations.isEmpty() && (!processQueries || queryOperations.isEmpty())) {
        if (timeout <= 0L) {
          return null;
        }
        waitForOperationAvailable(timeout);
      }
      if (!nonQueryOperations.isEmpty()) {
        return nonQueryOperations.removeFirst();
      }
      if (processQueries && !queryOperations.isEmpty()) {
        return queryOperations.removeFirst();
      }
      return null;
    }
  }

  /**
   * Add the given operation to the tail of this queue.
   *
   * @param operation the operation to be added to the queue
   */
  public void enqueue(IndexOperation operation) {
    synchronized (nonQueryOperations) {
      if (operation instanceof ClearOperation) {
        queryOperations.clear();
        nonQueryOperations.clear();
      }
      if (operation instanceof RemoveSourceOperation) {
        Source source = ((RemoveSourceOperation) operation).getSource();
        removeForSource(source, nonQueryOperations);
        removeForSource(source, queryOperations);
      }
      if (operation.isQuery()) {
        queryOperations.add(operation);
      } else {
        nonQueryOperations.add(operation);
      }
      notifyOperationAvailable();
    }
  }

  /**
   * Return a list containing all of the operations that are currently on the queue. Modifying this
   * list will not affect the state of the queue.
   *
   * @return all of the operations that are currently on the queue
   */
  public List<IndexOperation> getOperations() {
    List<IndexOperation> operations = Lists.newArrayList();
    synchronized (nonQueryOperations) {
      operations.addAll(nonQueryOperations);
      operations.addAll(queryOperations);
    }
    return operations;
  }

  /**
   * Set whether the receiver's {@link #dequeue(long)} method should return query operations.
   *
   * @param processQueries {@code true} if the receiver's {@link #dequeue(long)} method should
   *          return query operations or {@code false} if query operations should be queued but not
   *          returned by the receiver's {@link #dequeue(long)} method until this method is called
   *          with a value of {@code true}.
   */
  public void setProcessQueries(boolean processQueries) {
    synchronized (nonQueryOperations) {
      if (this.processQueries != processQueries) {
        this.processQueries = processQueries;
        if (processQueries && !queryOperations.isEmpty()) {
          notifyOperationAvailable();
        }
      }
    }
  }

  /**
   * Return the number of operations on the queue.
   *
   * @return the number of operations on the queue
   */
  public int size() {
    synchronized (nonQueryOperations) {
      return nonQueryOperations.size() + queryOperations.size();
    }
  }

  private void notifyOperationAvailable() {
    nonQueryOperations.notifyAll();
  }

  /**
   * Removes operations that should be removed when given {@link Source} is removed.
   */
  private void removeForSource(Source source, LinkedList<IndexOperation> operations) {
    for (Iterator<IndexOperation> iter = operations.listIterator(); iter.hasNext();) {
      IndexOperation indexOperation = iter.next();
      if (indexOperation.removeWhenSourceRemoved(source)) {
        iter.remove();
      }
    }
  }

  private void waitForOperationAvailable(long timeout) throws InterruptedException {
    nonQueryOperations.wait(timeout);
  }
}
TOP

Related Classes of com.google.dart.engine.internal.index.operation.OperationQueue

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.