Mina Queue Queue

Mina protocol codec filter 1 (protocol codec factory, protocol encoder):
http://donald-draper.iteye.com/blog/2376663
Mina protocol codec filter 2 (protocol decoder):
http://donald-draper.iteye.com/blog/2376663 donald-draper.iteye.com/blog/2376679 In
the previous two articles, Queue is involved. Let's take a look at how Queue works today.
/**
 * A unbounded circular queue.
 *
 * @author The Apache Directory Project ([email protected])
 * @version $Rev$, $Date$
 */
public class Queue extends AbstractList implements List, Serializable {
    private static final int DEFAULT_CAPACITY = 4;//Default capacity
    private static final int DEFAULT_MASK = DEFAULT_CAPACITY - 1;//default mask
    private Object[] items;//Store the array of queue elements
    private int mask;
    private int first = 0;//队头
    private int last = 0;//The end of the queue
    private int size = 0;//The actual capacity of the queue
    /**
     * Construct a new, empty queue.
     construct empty queue
     */
    public Queue() {
        items = new Object[DEFAULT_CAPACITY];
        mask = DEFAULT_MASK;
    }
}

From the above, the queue Queue is actually a List, which uses an object array items to store elements, an actual capacity counter size, a queue head first and a queue tail index last, and the default queue capacity is 4.

/
**
     * Enqueue into this queue. Add elements to the queue
     */
    public void push(Object item) {
        if (item == null) {
            throw new NullPointerException("item");
        }
        ensureCapacity();//Ensure that the queue can store elements
        items[last] = item;//Store elements
        increaseSize();//Update the actual capacity size, and the index at the end of the queue
    }

Check out ensureCapacity
private void ensureCapacity() {
        //If the queue is not full, return directly
        if (size < items.length) {
            return;
        }

        // expand queue, otherwise expand, twice the original size
        final int oldLen = items.length;
        Object[] tmp = new Object[oldLen * 2];
        //Copy the original queue data to the new queue
        if (first < last) {
            System.arraycopy(items, first, tmp, 0, last - first);
        } else {
            System.arraycopy(items, first, tmp, 0, oldLen - first);
            System.arraycopy(items, 0, tmp, oldLen - first, last);
        }
        first = 0;
        last = oldLen;
        items = tmp;
        mask = tmp.length - 1;
    }
//Update the tail of the queue, and size
  private void increaseSize() {
        last = (last + 1) & mask;
        size++;
    }

Look at the queue
/**
     * Dequeues from this queue.
     *
     * @return <code>null</code>, if this queue is empty or the element is
     *         really <code>null</code>.
     */
    public Object pop() {
        if (size == 0) {
            return null;
        }
       //Return the head element, empty the original head
        Object ret = items[first];
        items[first] = null;
        decreaseSize();//Update size, and head index
        return ret;
    }
 private void decreaseSize() {
        first = (first + 1) & mask;
        size--;
    }

Let's look at other operations:
/**
     * Returns the capacity of this queue. Returns the capacity of this queue.
     */
    public int capacity() {
        return items.length;
    }

    /**
     * Clears this queue. Clear the queue
     */
    public void clear() {
        Arrays.fill(items, null);
        first = 0;
        last = 0;
        size = 0;
    }
  /**
     * Returns the first element of the queue.
     * return the head element
     * @return <code>null</code>, if the queue is empty, or the element is
     *         really <code>null</code>.
     */
    public Object first() {
        if (size == 0) {
            return null;
        }

        return items[first];
    }
    /**
     * Returns the last element of the queue.
     * Get the tail element
     * @return <code>null</code>, if the queue is empty, or the element is
     *         really <code>null</code>.
     */
    public Object last() {
        if (size == 0) {
            return null;
        }

        return items[(last + items.length - 1) & mask];
    }
     /**
     * Returns <code>true</code> if the queue is empty. Is it empty
     */
    public boolean isEmpty() {
        return (size == 0);
    }

    /**
     * Returns the number of elements in the queue.
     Get the number of queue elements
     */
    public int size() {
        return size;
    }
    //Get the queue element corresponding to the index
    public Object get(int idx) {
        checkIndex(idx);//Check index
        return items[getRealIndex(idx)];
    }
    //check index
   private void checkIndex(int idx) {
        if (idx < 0 || idx >= size) {
            throw new IndexOutOfBoundsException(String.valueOf(idx));
        }
    }
   //Get the actual queue index
    private int getRealIndex(int idx) {
        return (first + idx) & mask;
    }
  //////////////////////////////////////////
    // java.util.List compatibility methods //
    //////////////////////////////////////////
    // add element to the queue
    public boolean add(Object o) {
        push(o);
        return true;
    }
   //Update the element corresponding to the index
    public Object set(int idx, Object o) {
        checkIndex(idx);

        int realIdx = getRealIndex(idx);
        Object old = items[realIdx];
        items [realIdx] = o;
        return old;
    }
   //Add element to specified index
    public void add(int idx, Object o) {
         //If it is a queue, add it directly
        if (idx == size) {
            push(o);
            return;
        }
        //Check the index to make sure the capacity is available
        checkIndex(idx);
        ensureCapacity();
        // get the actual index
        int realIdx = getRealIndex(idx);

        // Make a room for a new element.
	//The following operation is time-consuming, re-move the front and rear elements corresponding to the realIdx index into the queue, and put the index
	//The corresponding position is vacated
        if (first < last) {
            System
                    .arraycopy(items, realIdx, items, realIdx + 1, last
                            -realIdx);
        } else {
            if (realIdx >= first) {
                System.arraycopy(items, 0, items, 1, last);
                items[0] = items[items.length - 1];
                System.arraycopy(items, realIdx, items, realIdx + 1,
                        items.length - realIdx - 1);
            } else {
                System.arraycopy(items, realIdx, items, realIdx + 1, last
                        -realIdx);
            }
        }
        items [realIdx] = o;
        increaseSize();//Update size, and last
    }
   //Remove the element corresponding to the specified index
    public Object remove(int idx) {
        if (idx == 0) {
            return pop();
        }

        checkIndex(idx);

        int realIdx = getRealIndex(idx);
        Object removed = items[realIdx];

        // Remove a room for the removed element.
         //The following operation is time-consuming, re-move the front and rear elements corresponding to the realIdx index into the queue, and put the index
	//The corresponding position is cleared, that is, it is occupied
        if (first < last) {
            System.arraycopy(items, first, items, first + 1, realIdx - first);
        } else {
            if (realIdx >= first) {
                System.arraycopy(items, first, items, first + 1, realIdx
                        - first);
            } else {
                System.arraycopy(items, 0, items, 1, realIdx);
                items[0] = items[items.length - 1];
                System.arraycopy(items, first, items, first + 1, items.length
                        - first - 1);
            }
        }

        items[first] = null;
        decreaseSize();//Update size, and head last

        return removed;
    }

    ///////////////////////////////////////////
    // java.util.Queue compatibility methods //
    ///////////////////////////////////////////
    //add element
    public boolean offer(Object o) {
        push(o);
        return true;
    }
    // get the head element
    public Object poll() {
        return pop();
    }
    //remove the head element
    public Object remove() {
        if (size == 0) {
            throw new NoSuchElementException();
        }
        return pop();
    }
    //Check if the queue has elements
    public Object peek() {
        return first();
    }
    //return queue element
    public Object element() {
        if (size == 0) {
            throw new NoSuchElementException();
        }
        return first();
    }

Summary:
The queue Queue is actually a List, which uses an object array items to store elements, an actual capacity counter size, a queue head first and a queue tail index last, and the default queue capacity is 4. When pushing an element, first determine whether the queue is full. If it is full, the expansion queue is doubled. Queue is actually a List with queue characteristics. Queue has random access to the queue index.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326508697&siteId=291194637