001/* 002 * This file is part of the Jikes RVM project (http://jikesrvm.org). 003 * 004 * This file is licensed to You under the Eclipse Public License (EPL); 005 * You may not use this file except in compliance with the License. You 006 * may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/eclipse-1.0.php 009 * 010 * See the COPYRIGHT.txt file distributed with this work for information 011 * regarding copyright ownership. 012 */ 013package org.jikesrvm.util; 014 015import java.util.Collection; 016import java.util.Iterator; 017import java.util.List; 018import java.util.ListIterator; 019import org.jikesrvm.VM; 020 021/** 022 * Implementation of java.util.LinkedList for use in classes that 023 * end up in the boot image. 024 */ 025public final class LinkedListRVM<T> implements List<T> { 026 027 /** Element count */ 028 private int count = 0; 029 030 /** pointer to first element in the list */ 031 Element<T> head = null; 032 033 /** pointer to last element in the list */ 034 Element<T> tail = null; 035 036 /** 037 * Insert an element at a given position in the list. 038 * <p> 039 * UNIMPLEMENTED 040 * 041 * @param pos Position in the list (0..size()-1) 042 * @param entry Element to insert 043 */ 044 @Override 045 public void add(int pos, T entry) { 046 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); 047 } 048 049 /** 050 * Insert at the tail of the list 051 * 052 * @param entry The entry to add. 053 * @return true (as per java collections framework standard) 054 */ 055 @Override 056 public boolean add(final T entry) { 057 final Element<T> element = new Element<T>(entry); 058 element.next = null; 059 if (head == null) { 060 if (VM.VerifyAssertions) VM._assert(tail == null); 061 head = element; 062 element.prev = null; 063 } else { 064 tail.next = element; 065 element.prev = tail; 066 } 067 tail = element; 068 count++; 069 return true; 070 } 071 072 /** 073 * Insert an entry after the given element. Used via the iterator. 074 * 075 * @param e List element 076 * @param t New list entry 077 */ 078 void insertAfter(Element<T> e, T t) { 079 Element<T> newElement = new Element<T>(t); 080 if (e == null) { 081 newElement.next = head; 082 newElement.prev = null; 083 head = newElement; 084 } else { 085 newElement.next = e.next; 086 newElement.prev = e; 087 if (e.next != null) { 088 e.next.prev = newElement; 089 } 090 e.next = newElement; 091 } 092 if (tail == null || tail == e) { 093 tail = newElement; 094 } 095 count++; 096 } 097 098 /** 099 * Add all members of the given collection. 100 * <p> 101 * UNIMPLEMENTED 102 */ 103 @Override 104 public boolean addAll(Collection<? extends T> arg0) { 105 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); 106 return false; 107 } 108 109 /** 110 * Add all members of the given collection after the given element. 111 * <p> 112 * UNIMPLEMENTED 113 */ 114 @Override 115 public boolean addAll(int arg0, Collection<? extends T> arg1) { 116 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); 117 return false; 118 } 119 120 /** 121 * Discard all entries in the list 122 */ 123 @Override 124 public void clear() { 125 head = tail = null; 126 count = 0; 127 } 128 129 /** 130 * Membership test 131 * 132 * @param arg0 Object to check 133 * @return true if the list contains arg0, false otherwise 134 */ 135 @Override 136 public boolean contains(Object arg0) { 137 return indexOf(arg0) != -1; 138 } 139 140 /** 141 * Set inclusion test 142 * 143 * @param arg0 Objects to check 144 * @return true if the list contains all objects in arg0, false otherwise 145 */ 146 @Override 147 public boolean containsAll(Collection<?> arg0) { 148 for (Object o : arg0) { 149 if (!contains(o)) { 150 return false; 151 } 152 } 153 return true; 154 } 155 156 /** 157 * @param index index of the element to return 158 * @return the nth element of the list 159 */ 160 @Override 161 public T get(int index) { 162 /* Special-case getting the head of the list for speed */ 163 if (index == 0 && head != null) { 164 return head.entry; 165 } 166 167 /* bounds check */ 168 if (index < 0 || index >= size()) { 169 throw new IndexOutOfBoundsException(); 170 } 171 172 Element<T> cursor = head; 173 for (int i = 0; i < index; i++) { 174 cursor = cursor.next; 175 } 176 return cursor.entry; 177 } 178 179 /** 180 * Return the position of the given element. 181 * 182 * @param arg0 Member to test for. 183 * @return Zero-based index of the element, or -1 if not found. 184 */ 185 @Override 186 public int indexOf(Object arg0) { 187 int i = 0; 188 for (T t : this) { 189 if (t == arg0) { 190 return i; 191 } 192 i++; 193 } 194 return -1; 195 } 196 197 @Override 198 public boolean isEmpty() { 199 return count == 0; 200 } 201 202 @Override 203 public Iterator<T> iterator() { 204 return new LinkedListIteratorRVM<T>(this); 205 } 206 207 /** UNIMPLEMENTED */ 208 @Override 209 public int lastIndexOf(Object arg0) { 210 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); 211 return 0; 212 } 213 214 @Override 215 public ListIterator<T> listIterator() { 216 return new LinkedListIteratorRVM<T>(this); 217 } 218 219 /** UNIMPLEMENTED */ 220 @Override 221 public ListIterator<T> listIterator(int arg0) { 222 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); 223 return null; 224 } 225 226 /** 227 * Remove the nth element of the list. 228 * 229 * @param index n 230 * @return The nth element 231 */ 232 @Override 233 public T remove(int index) { 234 /* bounds check */ 235 if (index < 0 || index >= size()) { 236 throw new IndexOutOfBoundsException(); 237 } 238 239 Element<T> cursor = head; 240 for (int i = 0; i < index; i++) { 241 cursor = cursor.next; 242 } 243 removeInternal(cursor); 244 return cursor.entry; 245 } 246 247 /** 248 * Remove the given element from the list 249 */ 250 @Override 251 public boolean remove(Object arg0) { 252 Element<T> cursor = head; 253 while (cursor != null && !(arg0 == null ? cursor.entry == null : cursor.entry.equals(arg0))) { 254 cursor = cursor.next; 255 } 256 if (cursor == null) { 257 return false; 258 } else { 259 removeInternal(cursor); 260 return true; 261 } 262 } 263 264 void removeInternal(Element<T> e) { 265 if (e.prev == null) { 266 if (VM.VerifyAssertions) VM._assert(e == head); 267 head = e.next; 268 } else { 269 e.prev.next = e.next; 270 } 271 272 if (e.next == null) { 273 if (VM.VerifyAssertions) VM._assert(e == tail); 274 tail = e.prev; 275 } else { 276 e.next.prev = e.prev; 277 } 278 279 count--; 280 } 281 282 /** UNIMPLEMENTED */ 283 @Override 284 public boolean removeAll(Collection<?> arg0) { 285 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); 286 return false; 287 } 288 289 /** UNIMPLEMENTED */ 290 @Override 291 public boolean retainAll(Collection<?> arg0) { 292 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); 293 return false; 294 } 295 296 /** UNIMPLEMENTED */ 297 @Override 298 public T set(int arg0, T arg1) { 299 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); 300 return null; 301 } 302 303 @Override 304 public int size() { 305 return count; 306 } 307 308 /** UNIMPLEMENTED */ 309 @Override 310 public List<T> subList(int arg0, int arg1) { 311 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); 312 return null; 313 } 314 315 /** UNIMPLEMENTED */ 316 @Override 317 public Object[] toArray() { 318 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); 319 return null; 320 } 321 322 /** UNIMPLEMENTED */ 323 @Override 324 public <U> U[] toArray(U[] arg0) { 325 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); 326 return null; 327 } 328 329 /** 330 * Class for the actual elements of the list. 331 * 332 * 333 * @param <T> Type of the entry 334 */ 335 static class Element<T> { 336 Element<T> next; 337 Element<T> prev; 338 T entry; 339 340 Element(T entry) { 341 this.entry = entry; 342 } 343 } 344}