KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > lisp > ComplexBitVector


1 /*
2  * ComplexBitVector.java
3  *
4  * Copyright (C) 2003-2004 Peter Graves
5  * $Id: ComplexBitVector.java,v 1.9 2004/05/27 17:11:14 piso Exp $
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */

21
22 package org.armedbear.lisp;
23
24 public final class ComplexBitVector extends AbstractBitVector
25 {
26     private int fillPointer = -1; // -1 indicates no fill pointer.
27
private boolean isDisplaced;
28
29     // For displaced bit-vectors.
30
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 JavaDoc sb = new StringBuffer JavaDoc("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 JavaDoc sb = new StringBuffer JavaDoc("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         // The index < 0 case is checked in get().
114
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 JavaDoc e) {
162             // Fall through...
163
}
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     // FIXME
212
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             // Need to extend vector.
220
ensureCapacity(capacity() * 2 + 1);
221         }
222         setRowMajor(fp, element);
223         setFillPointer(fp + 1);
224         return new Fixnum(fp);
225     }
226
227     // FIXME
228
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             // Need to extend vector.
237
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                 // Copy array.
261
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             // Copy array.
287
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