View Javadoc

1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.mina.util;
21  
22  import static org.junit.Assert.assertEquals;
23  import static org.junit.Assert.assertTrue;
24  import static org.junit.Assert.fail;
25  
26  import java.util.Iterator;
27  
28  import org.junit.Before;
29  import org.junit.Test;
30  
31  /**
32   * Tests {@link org.apache.mina.util.CircularQueue}
33   * 
34   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
35   */
36  public class CircularQueueTest {
37      private volatile int pushCount;
38      private volatile int popCount;
39  
40      @Before
41      public void setUp() {
42          pushCount = 0;
43          popCount = 0;
44      }
45  
46      @Test
47      public void testRotation() {
48          CircularQueue<Integer> q = new CircularQueue<Integer>(); // DEFAULT_CAPACITY = 4
49          testRotation0(q);
50      }
51  
52      @Test
53      public void testExpandingRotation() {
54          CircularQueue<Integer> q = new CircularQueue<Integer>(); // DEFAULT_CAPACITY = 4
55          for (int i = 0; i < 10; i++) {
56              testRotation0(q);
57  
58              // make expansion happen
59              int oldCapacity = q.capacity();
60              for (int j = q.capacity(); j >= 0; j--) {
61                  q.offer(new Integer(++pushCount));
62              }
63  
64              assertTrue(q.capacity() > oldCapacity);
65              testRotation0(q);
66          }
67      }
68  
69      private void testRotation0(CircularQueue<Integer> q) {
70          for (int i = 0; i < q.capacity() * 7 / 4; i++) {
71              q.offer(new Integer(++pushCount));
72              assertEquals(++popCount, q.poll().intValue());
73          }
74      }
75  
76      @Test
77      public void testRandomAddOnQueue() {
78          CircularQueue<Integer> q = new CircularQueue<Integer>();
79          // Create a queue with 5 elements and capacity 8;
80          for (int i = 0; i < 5; i++) {
81              q.offer(new Integer(i));
82          }
83  
84          q.add(0, new Integer(100));
85          q.add(3, new Integer(200));
86          q.add(7, new Integer(300));
87  
88          Iterator<Integer> i = q.iterator();
89          assertEquals(8, q.size());
90          assertEquals(new Integer(100), i.next());
91          assertEquals(new Integer(0), i.next());
92          assertEquals(new Integer(1), i.next());
93          assertEquals(new Integer(200), i.next());
94          assertEquals(new Integer(2), i.next());
95          assertEquals(new Integer(3), i.next());
96          assertEquals(new Integer(4), i.next());
97          assertEquals(new Integer(300), i.next());
98  
99          try {
100             i.next();
101             fail();
102         } catch (Exception e) {
103             // an exception signifies a successfull test case
104             assertTrue(true);            
105         }
106     }
107 
108     @Test
109     public void testRandomAddOnRotatedQueue() {
110         CircularQueue<Integer> q = getRotatedQueue();
111 
112         q.add(0, new Integer(100)); // addFirst
113         q.add(2, new Integer(200));
114         q.add(4, new Integer(300));
115         q.add(10, new Integer(400));
116         q.add(12, new Integer(500)); // addLast
117 
118         Iterator<Integer> i = q.iterator();
119         assertEquals(13, q.size());
120         assertEquals(new Integer(100), i.next());
121         assertEquals(new Integer(0), i.next());
122         assertEquals(new Integer(200), i.next());
123         assertEquals(new Integer(1), i.next());
124         assertEquals(new Integer(300), i.next());
125         assertEquals(new Integer(2), i.next());
126         assertEquals(new Integer(3), i.next());
127         assertEquals(new Integer(4), i.next());
128         assertEquals(new Integer(5), i.next());
129         assertEquals(new Integer(6), i.next());
130         assertEquals(new Integer(400), i.next());
131         assertEquals(new Integer(7), i.next());
132         assertEquals(new Integer(500), i.next());
133 
134         try {
135             i.next();
136             fail();
137         } catch (Exception e) {
138             // an exception signifies a successfull test case
139             assertTrue(true);
140         }
141     }
142 
143     @Test
144     public void testRandomRemoveOnQueue() {
145         CircularQueue<Integer> q = new CircularQueue<Integer>();
146 
147         // Create a queue with 5 elements and capacity 8;
148         for (int i = 0; i < 5; i++) {
149             q.offer(new Integer(i));
150         }
151 
152         q.remove(0);
153         q.remove(2);
154         q.remove(2);
155 
156         Iterator<Integer> i = q.iterator();
157         assertEquals(2, q.size());
158         assertEquals(new Integer(1), i.next());
159         assertEquals(new Integer(2), i.next());
160 
161         try {
162             i.next();
163             fail();
164         } catch (Exception e) {
165             // an exception signifies a successfull test case
166             assertTrue(true);
167         }
168     }
169 
170     @Test
171     public void testRandomRemoveOnRotatedQueue() {
172         CircularQueue<Integer> q = getRotatedQueue();
173 
174         q.remove(0); // removeFirst
175         q.remove(2); // removeLast in the first half
176         q.remove(2); // removeFirst in the first half
177         q.remove(4); // removeLast
178 
179         Iterator<Integer> i = q.iterator();
180         assertEquals(4, q.size());
181         assertEquals(new Integer(1), i.next());
182         assertEquals(new Integer(2), i.next());
183         assertEquals(new Integer(5), i.next());
184         assertEquals(new Integer(6), i.next());
185 
186         try {
187             i.next();
188             fail();
189         } catch (Exception e) {
190             // an exception signifies a successfull test case
191             assertTrue(true);            
192         }
193     }
194     
195     @Test
196     public void testExpandAndShrink() throws Exception {
197         CircularQueue<Integer> q = new CircularQueue<Integer>();
198         for (int i = 0; i < 1024; i ++) {
199             q.offer(i);
200         }
201         
202         assertEquals(1024, q.capacity());
203         
204         for (int i = 0; i < 512; i ++) {
205             q.offer(i);
206             q.poll();
207         }
208         
209         assertEquals(2048, q.capacity());
210         
211         for (int i = 0; i < 1024; i ++) { 
212             q.poll();
213         }
214         
215         assertEquals(4, q.capacity());
216     }
217 
218     private CircularQueue<Integer> getRotatedQueue() {
219         CircularQueue<Integer> q = new CircularQueue<Integer>();
220 
221         // Ensure capacity: 16
222         for (int i = 0; i < 16; i++) {
223             q.offer(new Integer(-1));
224         }
225         q.clear();
226 
227         // Rotate it
228         for (int i = 0; i < 12; i++) {
229             q.offer(new Integer(-1));
230             q.poll();
231         }
232 
233         // Now push items
234         for (int i = 0; i < 8; i++) {
235             q.offer(new Integer(i));
236         }
237 
238         return q;
239     }
240 }