1 21 22 package org.armedbear.lisp; 23 24 public final class ComplexBitVector extends AbstractBitVector 25 { 26 private int fillPointer = -1; private boolean isDisplaced; 28 29 private AbstractArray array; 31 private int displacement; 32 33 public ComplexBitVector(int capacity) throws ConditionThrowable 34 { 35 this.capacity = capacity; 36 int size = capacity >>> 6; 37 if ((capacity & LONG_MASK) != 0) 38 ++size; 39 bits = new long[size]; 40 } 41 42 public ComplexBitVector(int capacity, AbstractArray array, int displacement) 43 { 44 this.capacity = capacity; 45 this.array = array; 46 this.displacement = displacement; 47 isDisplaced = true; 48 } 49 50 public LispObject typeOf() 51 { 52 return list2(Symbol.BIT_VECTOR, new Fixnum(capacity)); 53 } 54 55 public boolean hasFillPointer() 56 { 57 return fillPointer >= 0; 58 } 59 60 public int getFillPointer() 61 { 62 return fillPointer; 63 } 64 65 public void setFillPointer(int n) 66 { 67 fillPointer = n; 68 } 69 70 public void setFillPointer(LispObject obj) throws ConditionThrowable 71 { 72 if (obj == T) 73 fillPointer = capacity(); 74 else { 75 int n = Fixnum.getValue(obj); 76 if (n > capacity()) { 77 StringBuffer sb = new StringBuffer ("The new fill pointer ("); 78 sb.append(n); 79 sb.append(") exceeds the capacity of the vector ("); 80 sb.append(capacity()); 81 sb.append(")."); 82 signal(new LispError(sb.toString())); 83 } else if (n < 0) { 84 StringBuffer sb = new StringBuffer ("The new fill pointer ("); 85 sb.append(n); 86 sb.append(") is negative."); 87 signal(new LispError(sb.toString())); 88 } else 89 fillPointer = n; 90 } 91 } 92 93 public LispObject arrayDisplacement() throws ConditionThrowable 94 { 95 LispObject value1, value2; 96 if (array != null) { 97 value1 = array; 98 value2 = new Fixnum(displacement); 99 } else { 100 value1 = NIL; 101 value2 = Fixnum.ZERO; 102 } 103 return LispThread.currentThread().setValues(value1, value2); 104 } 105 106 public int length() 107 { 108 return fillPointer >= 0 ? fillPointer : capacity; 109 } 110 111 public LispObject elt(int index) throws ConditionThrowable 112 { 113 if (index >= length()) 115 badIndex(index, length()); 116 return getRowMajor(index); 117 } 118 119 public LispObject getRowMajor(int index) throws ConditionThrowable 120 { 121 if (bits != null) { 122 if (index < 0 || index >= capacity) 123 badIndex(index, capacity); 124 int offset = index >> 6; 125 return (bits[offset] & (1L << index)) != 0 ? Fixnum.ONE : Fixnum.ZERO; 126 } else 127 return array.getRowMajor(index + displacement); 128 } 129 130 protected int getBit(int index) throws ConditionThrowable 131 { 132 if (bits != null) { 133 int offset = index >> 6; 134 return (bits[offset] & (1L << index)) != 0 ? 1 : 0; 135 } else 136 return Fixnum.getValue(array.getRowMajor(index + displacement)); 137 } 138 139 public void setRowMajor(int index, LispObject newValue) throws ConditionThrowable 140 { 141 if (index < 0 || index >= capacity) 142 badIndex(index, capacity); 143 try { 144 switch (((Fixnum)newValue).value) { 145 case 0: 146 if (bits != null) { 147 final int offset = index >> 6; 148 bits[offset] &= ~(1L << index); 149 } else 150 clearBit(index); 151 return; 152 case 1: 153 if (bits != null) { 154 final int offset = index >> 6; 155 bits[offset] |= 1L << index; 156 } else 157 setBit(index); 158 return; 159 } 160 } 161 catch (ClassCastException e) { 162 } 164 signal(new TypeError(newValue, Symbol.BIT)); 165 } 166 167 protected void setBit(int index) throws ConditionThrowable 168 { 169 if (bits != null) { 170 int offset = index >> 6; 171 bits[offset] |= 1L << index; 172 } else 173 array.setRowMajor(index + displacement, Fixnum.ONE); 174 } 175 176 protected void clearBit(int index) throws ConditionThrowable 177 { 178 if (bits != null) { 179 int offset = index >> 6; 180 bits[offset] &= ~(1L << index); 181 } else 182 array.setRowMajor(index + displacement, Fixnum.ZERO); 183 } 184 185 public void shrink(int n) throws ConditionThrowable 186 { 187 if (bits != null) { 188 if (n < capacity) { 189 int size = n >>> 6; 190 if ((n & LONG_MASK) != 0) 191 ++size; 192 if (size < bits.length) { 193 long[] newbits = new long[size]; 194 System.arraycopy(bits, 0, newbits, 0, size); 195 bits = newbits; 196 } 197 capacity = n; 198 return; 199 } 200 if (n == capacity) 201 return; 202 } 203 signal(new LispError()); 204 } 205 206 public boolean isSimpleVector() 207 { 208 return false; 209 } 210 211 public LispObject vectorPushExtend(LispObject element) 213 throws ConditionThrowable 214 { 215 final int fp = getFillPointer(); 216 if (fp < 0) 217 noFillPointer(); 218 if (fp >= capacity()) { 219 ensureCapacity(capacity() * 2 + 1); 221 } 222 setRowMajor(fp, element); 223 setFillPointer(fp + 1); 224 return new Fixnum(fp); 225 } 226 227 public LispObject vectorPushExtend(LispObject element, LispObject extension) 229 throws ConditionThrowable 230 { 231 int ext = Fixnum.getValue(extension); 232 final int fp = getFillPointer(); 233 if (fp < 0) 234 noFillPointer(); 235 if (fp >= capacity()) { 236 ext = Math.max(ext, capacity() + 1); 238 ensureCapacity(capacity() + ext); 239 } 240 setRowMajor(fp, element); 241 setFillPointer(fp + 1); 242 return new Fixnum(fp); 243 } 244 245 private final void ensureCapacity(int minCapacity) throws ConditionThrowable 246 { 247 if (bits != null) { 248 if (capacity < minCapacity) { 249 int size = minCapacity >>> 6; 250 if ((minCapacity & LONG_MASK) != 0) 251 ++size; 252 long[] newBits = new long[size]; 253 System.arraycopy(bits, 0, newBits, 0, bits.length); 254 bits = newBits; 255 capacity = minCapacity; 256 } 257 } else { 258 Debug.assertTrue(array != null); 259 if (array.getTotalSize() - displacement < minCapacity) { 260 int size = minCapacity >>> 6; 262 if ((minCapacity & LONG_MASK) != 0) 263 ++size; 264 bits = new long[size]; 265 for (int i = 0; i < capacity; i++) { 266 int n = Fixnum.getValue(array.getRowMajor(displacement + i)); 267 if (n == 1) 268 setBit(i); 269 else 270 clearBit(i); 271 } 272 capacity = minCapacity; 273 array = null; 274 displacement = 0; 275 isDisplaced = false; 276 } 277 } 278 } 279 280 public AbstractVector adjustVector(int newCapacity, 281 LispObject initialElement, 282 LispObject initialContents) 283 throws ConditionThrowable 284 { 285 if (bits == null) { 286 int size = capacity >>> 6; 288 if ((capacity & LONG_MASK) != 0) 289 ++size; 290 bits = new long[size]; 291 for (int i = 0; i < capacity; i++) { 292 int n = Fixnum.getValue(array.getRowMajor(displacement + i)); 293 if (n == 1) 294 setBit(i); 295 else 296 clearBit(i); 297 } 298 array = null; 299 displacement = 0; 300 isDisplaced = false; 301 } 302 if (capacity != newCapacity) { 303 int size = newCapacity >>> 6; 304 if ((newCapacity & LONG_MASK) != 0) 305 ++size; 306 if (initialContents != NIL) { 307 bits = new long[size]; 308 if (initialContents.listp()) { 309 LispObject list = initialContents; 310 for (int i = 0; i < newCapacity; i++) { 311 setRowMajor(i, list.car()); 312 list = list.cdr(); 313 } 314 } else if (initialContents.vectorp()) { 315 for (int i = 0; i < newCapacity; i++) 316 setRowMajor(i, initialContents.elt(i)); 317 } else 318 signal(new TypeError(initialContents, Symbol.SEQUENCE)); 319 } else { 320 long[] newBits = new long[size]; 321 System.arraycopy(bits, 0, newBits, 0, 322 Math.min(bits.length, newBits.length)); 323 bits = newBits; 324 if (newCapacity > capacity) { 325 int n = Fixnum.getValue(initialElement); 326 if (n == 1) 327 for (int i = capacity; i < newCapacity; i++) 328 setBit(i); 329 else 330 for (int i = capacity; i < newCapacity; i++) 331 clearBit(i); 332 } 333 } 334 capacity = newCapacity; 335 } 336 return this; 337 } 338 339 public AbstractVector adjustVector(int size, AbstractArray displacedTo, 340 int displacement) 341 throws ConditionThrowable 342 { 343 capacity = size; 344 array = displacedTo; 345 this.displacement = displacement; 346 bits = null; 347 isDisplaced = true; 348 return this; 349 } 350 } 351 | Popular Tags |