1 23 package com.sun.appserv.management.util.misc; 24 25 import java.util.List ; 26 import java.util.ArrayList ; 27 import java.util.AbstractList ; 28 import java.lang.reflect.Array ; 29 30 import com.sun.appserv.management.util.stringifier.ArrayStringifier; 31 32 33 36 public final class CircularList<T> extends AbstractList <T> 37 { 38 private final T[] mObjects; 39 private int mNumItems; 40 private int mFirst; 41 private OverflowHandler mOverflowHandler; 42 43 public 44 CircularList( Class <T> theClass, final int size ) 45 { 46 if ( size == 0 ) 47 { 48 throw new IllegalArgumentException ( "list must have at least one item" ); 49 } 50 51 mObjects = ArrayUtil.newArray( theClass, size ); 52 mFirst = 0; 53 mNumItems = 0; 54 55 mOverflowHandler = null; 56 } 57 58 public interface OverflowHandler 59 { 60 void handleBufferOverflow( Object o ); 61 } 62 63 public void 64 setOverflowHandler( final OverflowHandler handler ) 65 { 66 mOverflowHandler = handler; 67 } 68 69 public OverflowHandler 70 getOverflowHandler( ) 71 { 72 return( mOverflowHandler ); 73 } 74 75 public final int 76 size() 77 { 78 return( mNumItems ); 79 } 80 81 public final int 82 capacity() 83 { 84 return( mObjects.length ); 85 } 86 87 88 public final void 89 clear() 90 { 91 for( int i = 0; i < size(); ++i ) 92 { 93 set( i, null ); 94 } 95 mNumItems = 0; 96 ++modCount; 97 } 98 99 private final int 100 getPhysicalIndex( final int logicalIndex ) 101 { 102 return( (mFirst + logicalIndex) % capacity() ); 103 } 104 105 public final T 106 get( final int i) 107 { 108 checkInBounds( i ); 109 110 return( mObjects[ getPhysicalIndex( i ) ] ); 111 } 112 113 114 public final T 115 set( 116 final int i, 117 final T item) 118 { 119 checkInBounds( i ); 120 121 final int physicalIndex = getPhysicalIndex( i ); 122 final T oldItem = mObjects[ physicalIndex ]; 123 mObjects[ physicalIndex ] = item; 124 125 return( oldItem ); 126 } 127 128 129 protected void 130 discardedObject( final T o ) 131 { 132 if ( mOverflowHandler != null ) 133 { 134 mOverflowHandler.handleBufferOverflow( o ); 135 } 136 } 137 138 private final void 139 store( 140 final int logicalIndex, 141 final T item ) 142 { 143 mObjects[ getPhysicalIndex( logicalIndex ) ] = item; 144 } 145 146 public final boolean 147 add( final T item ) 148 { 149 final int capacity = capacity(); 150 151 assert( mFirst < capacity ); 152 153 if ( size() == capacity ) 156 { 157 final T overwrittenObject = get( 0 ); 158 159 mFirst = (mFirst + 1) % capacity; 161 store( capacity - 1, item ); 162 163 discardedObject( overwrittenObject ); 164 165 } 166 else 167 { 168 store( mNumItems, item ); 169 ++mNumItems; 170 } 171 172 ++modCount; 173 return( true ); 174 } 175 176 179 public final void 180 add( 181 final int index, 182 final T item ) 183 { 184 if ( index == mNumItems ) 185 { 186 add( item ); 187 } 188 else 189 { 190 throw new UnsupportedOperationException ( "add not at end" ); 191 } 192 } 193 194 public final T 195 remove( final int i) 196 { 197 T result = null; 198 199 if ( i == 0 ) 200 { 201 result = removeFirst(); 202 } 203 else if ( i == mNumItems - 1 ) 204 { 205 result = removeLast(); 206 } 207 else 208 { 209 throw new UnsupportedOperationException (); 210 } 211 212 ++modCount; 213 return( result ); 214 } 215 216 private final void 217 checkInBounds( final int i ) 218 { 219 if ( i < 0 || i >= mNumItems ) 220 { 221 throw new IndexOutOfBoundsException ( "" + i ); 222 } 223 } 224 225 public final T 226 removeFirst() 227 { 228 checkInBounds( 0 ); 229 230 final T result = get( 0 ); 231 --mNumItems; 232 mFirst = (mFirst + 1) % capacity(); 233 234 return( result ); 235 } 236 237 238 public final T 239 removeLast() 240 { 241 checkInBounds( 0 ); 242 243 final T result = get( mNumItems - 1 ); 244 --mNumItems; 245 246 return( result ); 247 } 248 249 250 public boolean 251 equals( final Object rhsIn ) 252 { 253 boolean equal = false; 254 255 if ( rhsIn == this ) 256 { 257 equal = true; 258 } 259 else if ( ! (rhsIn instanceof CircularList) ) 260 { 261 equal = false; 262 } 263 else 264 { 265 final CircularList rhs = (CircularList)rhsIn; 266 267 equal = capacity() == rhs.capacity() && 268 size() == rhs.size(); 269 if ( equal ) 270 { 271 final int size = size(); 272 for( int i = 0; i < size(); ++i ) 273 { 274 if ( ! CompareUtil.objectsEqual( get( i ), rhs.get( i ) ) ) 275 { 276 equal = false; 277 break; 278 } 279 } 280 } 281 } 282 283 return( equal ); 284 } 285 286 public String 287 toString() 288 { 289 return( ArrayStringifier.stringify( toArray( ), ", " ) ); 290 } 291 } 292 293 | Popular Tags |