001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.master.procedure;
019
020import org.apache.hadoop.hbase.procedure2.LockStatus;
021import org.apache.hadoop.hbase.procedure2.Procedure;
022import org.apache.hadoop.hbase.procedure2.ProcedureDeque;
023import org.apache.hadoop.hbase.util.AvlUtil.AvlLinkedNode;
024import org.apache.yetus.audience.InterfaceAudience;
025
026@InterfaceAudience.Private
027abstract class Queue<TKey extends Comparable<TKey>> extends AvlLinkedNode<Queue<TKey>> {
028
029  /**
030   * @param proc must not be null
031   */
032  abstract boolean requireExclusiveLock(Procedure<?> proc);
033
034  private final TKey key;
035  private final int priority;
036  private final ProcedureDeque runnables = new ProcedureDeque();
037  // Reference to status of lock on entity this queue represents.
038  private final LockStatus lockStatus;
039
040  protected Queue(TKey key, LockStatus lockStatus) {
041    this(key, 1, lockStatus);
042  }
043
044  protected Queue(TKey key, int priority, LockStatus lockStatus) {
045    assert priority >= 1 : "priority must be greater than or equal to 1";
046    this.key = key;
047    this.priority = priority;
048    this.lockStatus = lockStatus;
049  }
050
051  protected TKey getKey() {
052    return key;
053  }
054
055  public int getPriority() {
056    return priority;
057  }
058
059  protected LockStatus getLockStatus() {
060    return lockStatus;
061  }
062
063  public boolean isAvailable() {
064    return !isEmpty();
065  }
066
067  // ======================================================================
068  // Functions to handle procedure queue
069  // ======================================================================
070  public void add(Procedure<?> proc, boolean addToFront) {
071    if (addToFront) {
072      runnables.addFirst(proc);
073    } else {
074      runnables.addLast(proc);
075    }
076  }
077
078  public Procedure<?> peek() {
079    return runnables.peek();
080  }
081
082  public Procedure<?> poll() {
083    return runnables.poll();
084  }
085
086  public boolean isEmpty() {
087    return runnables.isEmpty();
088  }
089
090  public int size() {
091    return runnables.size();
092  }
093
094  // ======================================================================
095  // Generic Helpers
096  // ======================================================================
097  public int compareKey(TKey cmpKey) {
098    return key.compareTo(cmpKey);
099  }
100
101  @Override
102  public int compareTo(Queue<TKey> other) {
103    return compareKey(other.key);
104  }
105
106  @Override
107  public String toString() {
108    return String.format("%s(%s, xlock=%s sharedLock=%s size=%s)", getClass().getSimpleName(), key,
109      lockStatus.hasExclusiveLock() ? "true (" + lockStatus.getExclusiveLockProcIdOwner() + ")"
110          : "false",
111      lockStatus.getSharedLockCount(), size());
112  }
113}