source: branches/0.17.x/abcl/src/org/armedbear/lisp/ComplexBitVector.java

Last change on this file was 12254, checked in by ehuelsmann, 16 years ago

Remove 'throws ConditionThrowable?' method annotations:

it's an unchecked exception now, so no need to declare it thrown.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 11.8 KB
Line 
1/*
2 * ComplexBitVector.java
3 *
4 * Copyright (C) 2003-2005 Peter Graves
5 * $Id: ComplexBitVector.java 12254 2009-11-06 20:07:54Z ehuelsmann $
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 * As a special exception, the copyright holders of this library give you
22 * permission to link this library with independent modules to produce an
23 * executable, regardless of the license terms of these independent
24 * modules, and to copy and distribute the resulting executable under
25 * terms of your choice, provided that you also meet, for each linked
26 * independent module, the terms and conditions of the license of that
27 * module.  An independent module is a module which is not derived from
28 * or based on this library.  If you modify this library, you may extend
29 * this exception to your version of the library, but you are not
30 * obligated to do so.  If you do not wish to do so, delete this
31 * exception statement from your version.
32 */
33
34package org.armedbear.lisp;
35
36public final class ComplexBitVector extends AbstractBitVector
37{
38    private int fillPointer = -1; // -1 indicates no fill pointer.
39    private boolean isDisplaced;
40
41    // For displaced bit vectors.
42    private AbstractArray array;
43    private int displacement;
44
45    public ComplexBitVector(int capacity)
46    {
47        this.capacity = capacity;
48        int size = capacity >>> 6;
49        if ((capacity & LONG_MASK) != 0)
50            ++size;
51        bits = new long[size];
52    }
53
54    public ComplexBitVector(int capacity, AbstractArray array, int displacement)
55    {
56        this.capacity = capacity;
57        this.array = array;
58        this.displacement = displacement;
59        isDisplaced = true;
60    }
61
62    @Override
63    public LispObject typeOf()
64    {
65        return list(Symbol.BIT_VECTOR, Fixnum.getInstance(capacity));
66    }
67
68    @Override
69    public boolean hasFillPointer()
70    {
71        return fillPointer >= 0;
72    }
73
74    @Override
75    public int getFillPointer()
76    {
77        return fillPointer;
78    }
79
80    @Override
81    public void setFillPointer(int n)
82    {
83        fillPointer = n;
84    }
85
86    @Override
87    public void setFillPointer(LispObject obj)
88    {
89        if (obj == T)
90            fillPointer = capacity();
91        else {
92            int n = Fixnum.getValue(obj);
93            if (n > capacity()) {
94                StringBuffer sb = new StringBuffer("The new fill pointer (");
95                sb.append(n);
96                sb.append(") exceeds the capacity of the vector (");
97                sb.append(capacity());
98                sb.append(").");
99                error(new LispError(sb.toString()));
100            } else if (n < 0) {
101                StringBuffer sb = new StringBuffer("The new fill pointer (");
102                sb.append(n);
103                sb.append(") is negative.");
104                error(new LispError(sb.toString()));
105            } else
106                fillPointer = n;
107        }
108    }
109
110    @Override
111    public LispObject arrayDisplacement()
112    {
113        LispObject value1, value2;
114        if (array != null) {
115            value1 = array;
116            value2 = Fixnum.getInstance(displacement);
117        } else {
118            value1 = NIL;
119            value2 = Fixnum.ZERO;
120        }
121        return LispThread.currentThread().setValues(value1, value2);
122    }
123
124    @Override
125    public int length()
126    {
127        return fillPointer >= 0 ? fillPointer : capacity;
128    }
129
130    @Override
131    public LispObject elt(int index)
132    {
133        if (index >= length())
134            badIndex(index, length());
135        return AREF(index);
136    }
137
138    @Override
139    public LispObject AREF(int index)
140    {
141        if (index < 0 || index >= capacity)
142            badIndex(index, capacity);
143        if (bits != null) {
144            int offset = index >> 6;
145            return (bits[offset] & (1L << index)) != 0 ? Fixnum.ONE : Fixnum.ZERO;
146        } else {
147            // Displaced bit vector.
148            return array.AREF(index + displacement);
149        }
150    }
151
152    @Override
153    protected int getBit(int index)
154    {
155        if (bits != null) {
156            int offset = index >> 6;
157            return (bits[offset] & (1L << index)) != 0 ? 1 : 0;
158        } else
159            return Fixnum.getValue(array.AREF(index + displacement));
160    }
161
162    @Override
163    public void aset(int index, LispObject newValue)
164    {
165        if (index < 0 || index >= capacity)
166            badIndex(index, capacity);
167        if (newValue instanceof Fixnum) {
168            switch (((Fixnum)newValue).value) {
169                case 0:
170                    if (bits != null) {
171                        final int offset = index >> 6;
172                        bits[offset] &= ~(1L << index);
173                    } else
174                        clearBit(index);
175                    return;
176                case 1:
177                    if (bits != null) {
178                        final int offset = index >> 6;
179                        bits[offset] |= 1L << index;
180                    } else
181                        setBit(index);
182                    return;
183            }
184        }
185            // Fall through...
186        type_error(newValue, Symbol.BIT);
187    }
188
189    @Override
190    protected void setBit(int index)
191    {
192        if (bits != null) {
193            int offset = index >> 6;
194            bits[offset] |= 1L << index;
195        } else
196            array.aset(index + displacement, Fixnum.ONE);
197    }
198
199    @Override
200    protected void clearBit(int index)
201    {
202        if (bits != null) {
203            int offset = index >> 6;
204            bits[offset] &= ~(1L << index);
205        } else
206            array.aset(index + displacement, Fixnum.ZERO);
207    }
208
209    @Override
210    public void shrink(int n)
211    {
212        if (bits != null) {
213            if (n < capacity) {
214                int size = n >>> 6;
215                if ((n & LONG_MASK) != 0)
216                    ++size;
217                if (size < bits.length) {
218                    long[] newbits = new long[size];
219                    System.arraycopy(bits, 0, newbits, 0, size);
220                    bits = newbits;
221                }
222                capacity = n;
223                return;
224            }
225            if (n == capacity)
226                return;
227        }
228        error(new LispError());
229    }
230
231    @Override
232    public boolean isSimpleVector()
233    {
234        return false;
235    }
236
237    // FIXME
238    @Override
239    public void vectorPushExtend(LispObject element)
240    {
241        final int fp = getFillPointer();
242        if (fp < 0)
243            noFillPointer();
244        if (fp >= capacity()) {
245            // Need to extend vector.
246            ensureCapacity(capacity() * 2 + 1);
247        }
248        aset(fp, element);
249        setFillPointer(fp + 1);
250    }
251
252    // FIXME
253    @Override
254    public LispObject VECTOR_PUSH_EXTEND(LispObject element)
255
256    {
257        vectorPushExtend(element);
258        return Fixnum.getInstance(getFillPointer() - 1);
259    }
260
261    // FIXME
262    @Override
263    public LispObject VECTOR_PUSH_EXTEND(LispObject element, LispObject extension)
264
265    {
266        int ext = Fixnum.getValue(extension);
267        final int fp = getFillPointer();
268        if (fp < 0)
269            noFillPointer();
270        if (fp >= capacity()) {
271            // Need to extend vector.
272            ext = Math.max(ext, capacity() + 1);
273            ensureCapacity(capacity() + ext);
274        }
275        aset(fp, element);
276        setFillPointer(fp + 1);
277        return Fixnum.getInstance(fp);
278    }
279
280    private final void ensureCapacity(int minCapacity)
281    {
282        if (bits != null) {
283            if (capacity < minCapacity) {
284                int size = minCapacity >>> 6;
285                if ((minCapacity & LONG_MASK) != 0)
286                    ++size;
287                long[] newBits = new long[size];
288                System.arraycopy(bits, 0, newBits, 0, bits.length);
289                bits = newBits;
290                capacity = minCapacity;
291            }
292        } else {
293            Debug.assertTrue(array != null);
294            if (capacity < minCapacity ||
295                array.getTotalSize() - displacement < minCapacity)
296            {
297                // Copy array.
298                int size = minCapacity >>> 6;
299                if ((minCapacity & LONG_MASK) != 0)
300                    ++size;
301                bits = new long[size];
302                final int limit =
303                    Math.min(capacity, array.getTotalSize() - displacement);
304                for (int i = 0; i < limit; i++) {
305                    int n = Fixnum.getValue(array.AREF(displacement + i));
306                    if (n == 1)
307                        setBit(i);
308                    else
309                        clearBit(i);
310                }
311                capacity = minCapacity;
312                array = null;
313                displacement = 0;
314                isDisplaced = false;
315            }
316        }
317    }
318
319    @Override
320    public AbstractVector adjustArray(int newCapacity,
321                                       LispObject initialElement,
322                                       LispObject initialContents)
323
324    {
325        if (bits == null) {
326            // Copy array.
327            int size = capacity >>> 6;
328            if ((capacity & LONG_MASK) != 0)
329                ++size;
330            bits = new long[size];
331            for (int i = 0; i < capacity; i++) {
332                int n = Fixnum.getValue(array.AREF(displacement + i));
333                if (n == 1)
334                    setBit(i);
335                else
336                    clearBit(i);
337            }
338            array = null;
339            displacement = 0;
340            isDisplaced = false;
341        }
342        if (capacity != newCapacity) {
343            int size = newCapacity >>> 6;
344            if ((newCapacity & LONG_MASK) != 0)
345                ++size;
346            if (initialContents != null) {
347                bits = new long[size];
348                capacity = newCapacity;
349                if (initialContents.listp()) {
350                    LispObject list = initialContents;
351                    for (int i = 0; i < newCapacity; i++) {
352                        aset(i, list.car());
353                        list = list.cdr();
354                    }
355                } else if (initialContents.vectorp()) {
356                    for (int i = 0; i < newCapacity; i++)
357                        aset(i, initialContents.elt(i));
358                } else
359                    type_error(initialContents, Symbol.SEQUENCE);
360            } else {
361                long[] newBits = new long[size];
362                System.arraycopy(bits, 0, newBits, 0,
363                                 Math.min(bits.length, newBits.length));
364                bits = newBits;
365                if (newCapacity > capacity && initialElement != null) {
366                    int n = Fixnum.getValue(initialElement);
367                    if (n == 1)
368                        for (int i = capacity; i < newCapacity; i++)
369                            setBit(i);
370                    else
371                        for (int i = capacity; i < newCapacity; i++)
372                            clearBit(i);
373                }
374            }
375            capacity = newCapacity;
376        }
377        return this;
378    }
379
380    @Override
381    public AbstractVector adjustArray(int size, AbstractArray displacedTo,
382                                       int displacement)
383
384    {
385        capacity = size;
386        array = displacedTo;
387        this.displacement = displacement;
388        bits = null;
389        isDisplaced = true;
390        return this;
391    }
392}
Note: See TracBrowser for help on using the repository browser.