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.