View Javadoc

1   /*
2    * ============================================================================
3    * The Apache Software License, Version 1.1
4    * ============================================================================
5    * 
6    * Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
7    * 
8    * Redistribution and use in source and binary forms, with or without modifica-
9    * tion, are permitted provided that the following conditions are met: 1.
10   * Redistributions of source code must retain the above copyright notice, this
11   * list of conditions and the following disclaimer. 2. Redistributions in
12   * binary form must reproduce the above copyright notice, this list of
13   * conditions and the following disclaimer in the documentation and/or other
14   * materials provided with the distribution. 3. The end-user documentation
15   * included with the redistribution, if any, must include the following
16   * acknowledgment: "This product includes software developed by the Apache
17   * Software Foundation (http://www.apache.org/)." Alternately, this
18   * acknowledgment may appear in the software itself, if and wherever such
19   * third-party acknowledgments normally appear. 4. The names "log4j" and
20   * "Apache Software Foundation" must not be used to endorse or promote products
21   * derived from this software without prior written permission. For written
22   * permission, please contact apache@apache.org. 5. Products derived from this
23   * software may not be called "Apache", nor may "Apache" appear in their name,
24   * without prior written permission of the Apache Software Foundation.
25   * 
26   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
27   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
28   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29   * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
30   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
31   * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
32   * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
33   * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36   * 
37   * This software consists of voluntary contributions made by many individuals
38   * on behalf of the Apache Software Foundation. For more information on the
39   * Apache Software Foundation, please see <http://www.apache.org/> .
40   *  
41   */
42  
43  package smtphandler;
44  
45  import java.util.logging.LogRecord;
46  
47  /**
48   * 
49   * CyclicBuffer is used by other handlers to hold {@link LogRecord} objects for
50   * immediate or differed display.
51   * 
52   * <p>
53   * This buffer gives read access to any element in the buffer not just the
54   * first or last element.
55   * 
56   * @author Ceki G&uuml;lc&uuml;
57   * @author Sean C. Sullivan
58   *  
59   */
60  public class CyclicBuffer
61  {
62  	private LogRecord[] records;
63  	private int first;
64  	private int last;
65  	private int numElems;
66  	private int maxSize;
67  
68  	/**
69  	 * Instantiate a new CyclicBuffer of at most <code>maxSize</code>
70  	 * records.
71  	 * 
72  	 * The <code>maxSize</code> argument must a positive integer.
73  	 * 
74  	 * @param maxSize
75  	 *            The maximum number of elements in the buffer.
76  	 */
77  	public CyclicBuffer(int maxSize) throws IllegalArgumentException
78  	{
79  		if (maxSize < 1)
80  		{
81  			throw new IllegalArgumentException(
82  				"The maxSize argument ("
83  					+ maxSize
84  					+ ") is not a positive integer.");
85  		}
86  		this.maxSize = maxSize;
87  		records = new LogRecord[maxSize];
88  		first = 0;
89  		last = 0;
90  		numElems = 0;
91  	}
92  
93  	/**
94  	 * Add a <code>record</code> as the last record in the buffer.
95  	 *  
96  	 * @param record must be non-null
97  	 * 
98  	 */
99  	public void add(LogRecord record)
100 	{
101 		records[last] = record;
102 		if (++last == maxSize)
103 			last = 0;
104 
105 		if (numElems < maxSize)
106 			numElems++;
107 		else if (++first == maxSize)
108 			first = 0;
109 	}
110 
111 	/**
112 	 * Get the <i>i</i> th oldest record currently in the buffer. If <em>i</em>
113 	 * is outside the range 0 to the number of elements currently in the
114 	 * buffer, then <code>null</code> is returned.
115 	 * 
116 	 * @return may return null
117 	 *  
118 	 */
119 	public LogRecord get(int i)
120 	{
121 		if (i < 0 || i >= numElems)
122 			return null;
123 
124 		return records[(first + i) % maxSize];
125 	}
126 
127 	public int getMaxSize()
128 	{
129 		return maxSize;
130 	}
131 
132 	/**
133 	 * Get the oldest (first) element in the buffer. The oldest element is
134 	 * removed from the buffer.
135 	 * 
136 	 * @return may return null
137 	 * 
138 	 */
139 	public LogRecord get()
140 	{
141 		LogRecord r = null;
142 		if (numElems > 0)
143 		{
144 			numElems--;
145 			r = records[first];
146 			records[first] = null;
147 			if (++first == maxSize)
148 				first = 0;
149 		}
150 		return r;
151 	}
152 
153 	/**
154 	 * Get the number of elements in the buffer. This number is guaranteed to
155 	 * be in the range 0 to <code>maxSize</code> (inclusive).
156 	 */
157 	public int length()
158 	{
159 		return numElems;
160 	}
161 
162 	/**
163 	 * Resize the cyclic buffer to <code>newSize</code>.
164 	 * 
165 	 * @throws IllegalArgumentException
166 	 *             if <code>newSize</code> is negative.
167 	 */
168 	public void resize(int newSize)
169 	{
170 		if (newSize < 0)
171 		{
172 			throw new IllegalArgumentException(
173 				"Negative array size [" + newSize + "] not allowed.");
174 		}
175 		if (newSize == numElems)
176 		{	
177 			return; // nothing to do
178 		}
179 		
180 		LogRecord[] temp = new LogRecord[newSize];
181 
182 		int loopLen = newSize < numElems ? newSize : numElems;
183 
184 		for (int i = 0; i < loopLen; i++)
185 		{
186 			temp[i] = records[first];
187 			records[first] = null;
188 			if (++first == numElems)
189 				first = 0;
190 		}
191 		records = temp;
192 		first = 0;
193 		numElems = loopLen;
194 		maxSize = newSize;
195 		if (loopLen == newSize)
196 		{
197 			last = 0;
198 		}
199 		else
200 		{
201 			last = loopLen;
202 		}
203 	}
204 	
205 	public String toString()
206 	{
207 		StringBuffer sb = new StringBuffer();
208 		sb.append("length=" + length());
209 		return sb.toString();
210 	}
211 }