source: branches/0.16.x/abcl/src/org/armedbear/lisp/SimpleBitVector.java

Last change on this file was 11754, checked in by vvoutilainen, 16 years ago

Convert using ClassCastException? to checking instanceof.
Performance tests show this approach to be faster.
Patch by Douglas R. Miles. I modified the patch to
remove tabs, so indentation may be slightly off in places.
That's something that we need to handle separately, abcl
doesn't have a clear indentation policy.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 16.9 KB
Line 
1/*
2 * SimpleBitVector.java
3 *
4 * Copyright (C) 2004-2005 Peter Graves
5 * $Id: SimpleBitVector.java 11754 2009-04-12 10:53:39Z vvoutilainen $
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
36// "The type of a bit vector that is not displaced to another array, has no
37// fill pointer, and is not expressly adjustable is a subtype of type SIMPLE-
38// BIT-VECTOR."
39public final class SimpleBitVector extends AbstractBitVector
40{
41    public SimpleBitVector(int capacity)
42    {
43        this.capacity = capacity;
44        int size = capacity >>> 6; // 64 bits in a long
45        // If the capacity is not an integral multiple of 64, we'll need one
46        // more long.
47        if ((capacity & LONG_MASK) != 0)
48            ++size;
49        bits = new long[size];
50    }
51
52    public SimpleBitVector(String s) throws ConditionThrowable
53    {
54        this(s.length());
55        for (int i = capacity; i-- > 0;) {
56            char c = s.charAt(i);
57            if (c == '0') {
58            } else if (c == '1')
59                setBit(i);
60            else
61                Debug.assertTrue(false);
62        }
63    }
64
65    @Override
66    public LispObject typeOf()
67    {
68        return list(Symbol.SIMPLE_BIT_VECTOR, Fixnum.getInstance(capacity));
69    }
70
71    @Override
72    public LispObject classOf()
73    {
74        return BuiltInClass.SIMPLE_BIT_VECTOR;
75    }
76
77    @Override
78    public LispObject typep(LispObject type) throws ConditionThrowable
79    {
80        if (type == Symbol.SIMPLE_BIT_VECTOR)
81            return T;
82        if (type == Symbol.SIMPLE_ARRAY)
83            return T;
84        if (type == BuiltInClass.SIMPLE_BIT_VECTOR)
85            return T;
86        if (type == BuiltInClass.SIMPLE_ARRAY)
87            return T;
88        return super.typep(type);
89    }
90
91    @Override
92    public boolean hasFillPointer()
93    {
94        return false;
95    }
96
97    @Override
98    public boolean isAdjustable()
99    {
100        return false;
101    }
102
103    @Override
104    public boolean isSimpleVector()
105    {
106        return true;
107    }
108
109    @Override
110    public int length()
111    {
112        return capacity;
113    }
114
115    @Override
116    public LispObject elt(int index) throws ConditionThrowable
117    {
118        if (index < 0 || index >= length())
119            badIndex(index, length());
120        int offset = index >> 6; // Divide by 64.
121        return (bits[offset] & (1L << (index & LONG_MASK))) != 0 ? Fixnum.ONE : Fixnum.ZERO;
122    }
123
124    @Override
125    public LispObject AREF(int index) throws ConditionThrowable
126    {
127        if (index < 0 || index >= capacity)
128            badIndex(index, capacity);
129        int offset = index >> 6;
130        return (bits[offset] & (1L << (index & LONG_MASK))) != 0 ? Fixnum.ONE : Fixnum.ZERO;
131    }
132
133    @Override
134    public void aset(int index, LispObject newValue) throws ConditionThrowable
135    {
136        if (index < 0 || index >= capacity)
137            badIndex(index, capacity);
138        final int offset = index >> 6;
139        if (newValue instanceof Fixnum) {
140            switch (((Fixnum)newValue).value) {
141                case 0:
142                    bits[offset] &= ~(1L << (index & LONG_MASK));
143                    return;
144                case 1:
145                    bits[offset] |= 1L << (index & LONG_MASK);
146                    return;
147            }
148        }
149        // Fall through...
150        type_error(newValue, Symbol.BIT);
151    }
152
153    @Override
154    protected int getBit(int index)
155    {
156        int offset = index >> 6;
157        return (bits[offset] & (1L << (index & LONG_MASK))) != 0 ? 1 : 0;
158    }
159
160    @Override
161    protected void setBit(int index)
162    {
163        int offset = index >> 6;
164        bits[offset] |= 1L << (index & LONG_MASK);
165    }
166
167    @Override
168    protected void clearBit(int index)
169    {
170        int offset = index >> 6;
171        bits[offset] &= ~(1L << (index & LONG_MASK));
172    }
173
174    @Override
175    public void shrink(int n) throws ConditionThrowable
176    {
177        if (n < capacity) {
178            int size = n >>> 6;
179            if ((n & LONG_MASK) != 0)
180                ++size;
181            if (size < bits.length) {
182                long[] newbits = new long[size];
183                System.arraycopy(bits, 0, newbits, 0, size);
184                bits = newbits;
185            }
186            capacity = n;
187            return;
188        }
189        if (n == capacity)
190            return;
191        error(new LispError());
192    }
193
194    @Override
195    public AbstractVector adjustArray(int newCapacity,
196                                       LispObject initialElement,
197                                       LispObject initialContents)
198        throws ConditionThrowable
199    {
200        if (initialContents != null) {
201            SimpleBitVector v = new SimpleBitVector(newCapacity);
202            if (initialContents.listp()) {
203                LispObject list = initialContents;
204                for (int i = 0; i < newCapacity; i++) {
205                    v.aset(i, list.car());
206                    list = list.cdr();
207                }
208            } else if (initialContents.vectorp()) {
209                for (int i = 0; i < newCapacity; i++)
210                    v.aset(i, initialContents.elt(i));
211            } else
212                error(new TypeError(initialContents, Symbol.SEQUENCE));
213            return v;
214        }
215        if (capacity != newCapacity) {
216            SimpleBitVector v = new SimpleBitVector(newCapacity);
217            final int limit = Math.min(capacity, newCapacity);
218            for (int i = limit; i-- > 0;) {
219                if (getBit(i) == 1)
220                    v.setBit(i);
221                else
222                    v.clearBit(i);
223            }
224            if (initialElement != null && capacity < newCapacity) {
225                int n = Fixnum.getValue(initialElement);
226                if (n == 1)
227                    for (int i = capacity; i < newCapacity; i++)
228                        v.setBit(i);
229                else
230                    for (int i = capacity; i < newCapacity; i++)
231                        v.clearBit(i);
232            }
233            return v;
234        }
235        // No change.
236        return this;
237    }
238
239    @Override
240    public AbstractVector adjustArray(int newCapacity,
241                                       AbstractArray displacedTo,
242                                       int displacement)
243        throws ConditionThrowable
244    {
245        return new ComplexBitVector(newCapacity, displacedTo, displacement);
246    }
247
248    private SimpleBitVector and(SimpleBitVector v, SimpleBitVector result)
249    {
250        if (result == null)
251            result = new SimpleBitVector(capacity);
252        for (int i = bits.length; i-- > 0;)
253            result.bits[i] = bits[i] & v.bits[i];
254        return result;
255    }
256
257    private SimpleBitVector ior(SimpleBitVector v, SimpleBitVector result)
258    {
259        if (result == null)
260            result = new SimpleBitVector(capacity);
261        for (int i = bits.length; i-- > 0;)
262            result.bits[i] = bits[i] | v.bits[i];
263        return result;
264    }
265
266    private SimpleBitVector xor(SimpleBitVector v, SimpleBitVector result)
267    {
268        if (result == null)
269            result = new SimpleBitVector(capacity);
270        for (int i = bits.length; i-- > 0;)
271            result.bits[i] = bits[i] ^ v.bits[i];
272        return result;
273    }
274
275    private SimpleBitVector eqv(SimpleBitVector v, SimpleBitVector result)
276    {
277        if (result == null)
278            result = new SimpleBitVector(capacity);
279        for (int i = bits.length; i-- > 0;)
280            result.bits[i] = ~(bits[i] ^ v.bits[i]);
281        return result;
282    }
283
284    private SimpleBitVector nand(SimpleBitVector v, SimpleBitVector result)
285    {
286        if (result == null)
287            result = new SimpleBitVector(capacity);
288        for (int i = bits.length; i-- > 0;)
289            result.bits[i] = ~(bits[i] & v.bits[i]);
290        return result;
291    }
292
293    private SimpleBitVector nor(SimpleBitVector v, SimpleBitVector result)
294    {
295        if (result == null)
296            result = new SimpleBitVector(capacity);
297        for (int i = bits.length; i-- > 0;)
298            result.bits[i] = ~(bits[i] | v.bits[i]);
299        return result;
300    }
301
302    private SimpleBitVector andc1(SimpleBitVector v, SimpleBitVector result)
303    {
304        if (result == null)
305            result = new SimpleBitVector(capacity);
306        for (int i = bits.length; i-- > 0;)
307            result.bits[i] = ~bits[i] & v.bits[i];
308        return result;
309    }
310
311    private SimpleBitVector andc2(SimpleBitVector v, SimpleBitVector result)
312    {
313        if (result == null)
314            result = new SimpleBitVector(capacity);
315        for (int i = bits.length; i-- > 0;)
316            result.bits[i] = bits[i] & ~v.bits[i];
317        return result;
318    }
319
320    private SimpleBitVector orc1(SimpleBitVector v, SimpleBitVector result)
321    {
322        if (result == null)
323            result = new SimpleBitVector(capacity);
324        for (int i = bits.length; i-- > 0;)
325            result.bits[i] = ~bits[i] | v.bits[i];
326        return result;
327    }
328
329    private SimpleBitVector orc2(SimpleBitVector v, SimpleBitVector result)
330    {
331        if (result == null)
332            result = new SimpleBitVector(capacity);
333        for (int i = bits.length; i-- > 0;)
334            result.bits[i] = bits[i] | ~v.bits[i];
335        return result;
336    }
337
338    // ### %simple-bit-vector-bit-and
339    private static final Primitive _SIMPLE_BIT_VECTOR_BIT_AND =
340        new Primitive("%simple-bit-vector-bit-and", PACKAGE_SYS, false,
341                      "bit-vector1 bit-vector2 result-bit-vector")
342    {
343        @Override
344        public LispObject execute(LispObject first, LispObject second,
345                                  LispObject third)
346            throws ConditionThrowable
347        {
348            return ((SimpleBitVector)first).and((SimpleBitVector)second,
349                                                ((SimpleBitVector)third));
350        }
351    };
352
353    // ### %simple-bit-vector-bit-ior
354    private static final Primitive _SIMPLE_BIT_VECTOR_BIT_IOR =
355        new Primitive("%simple-bit-vector-bit-ior", PACKAGE_SYS, false,
356                      "bit-vector1 bit-vector2 result-bit-vector")
357    {
358        @Override
359        public LispObject execute(LispObject first, LispObject second,
360                                  LispObject third)
361            throws ConditionThrowable
362        {
363            return ((SimpleBitVector)first).ior((SimpleBitVector)second,
364                                                (SimpleBitVector)third);
365
366        }
367    };
368
369    // ### %simple-bit-vector-bit-xor
370    private static final Primitive _SIMPLE_BIT_VECTOR_BIT_XOR =
371        new Primitive("%simple-bit-vector-bit-xor", PACKAGE_SYS, false,
372                      "bit-vector1 bit-vector2 result-bit-vector")
373    {
374        @Override
375        public LispObject execute(LispObject first, LispObject second,
376                                  LispObject third)
377            throws ConditionThrowable
378        {
379            return ((SimpleBitVector)first).xor((SimpleBitVector)second,
380                                                (SimpleBitVector)third);
381
382        }
383    };
384
385    // ### %simple-bit-vector-bit-eqv
386    private static final Primitive _SIMPLE_BIT_VECTOR_BIT_EQV =
387        new Primitive("%simple-bit-vector-bit-eqv", PACKAGE_SYS, false,
388                      "bit-vector1 bit-vector2 result-bit-vector")
389    {
390        @Override
391        public LispObject execute(LispObject first, LispObject second,
392                                  LispObject third)
393            throws ConditionThrowable
394        {
395            return ((SimpleBitVector)first).eqv((SimpleBitVector)second,
396                                                (SimpleBitVector)third);
397        }
398    };
399
400    // ### %simple-bit-vector-bit-nand
401    private static final Primitive _SIMPLE_BIT_VECTOR_BIT_NAND =
402        new Primitive("%simple-bit-vector-bit-nand", PACKAGE_SYS, false,
403                      "bit-vector1 bit-vector2 result-bit-vector")
404    {
405        @Override
406        public LispObject execute(LispObject first, LispObject second,
407                                  LispObject third)
408            throws ConditionThrowable
409        {
410            return ((SimpleBitVector)first).nand((SimpleBitVector)second,
411                                                 (SimpleBitVector)third);
412        }
413    };
414
415    // ### %simple-bit-vector-bit-nor
416    private static final Primitive _SIMPLE_BIT_VECTOR_BIT_NOR =
417        new Primitive("%simple-bit-vector-bit-nor", PACKAGE_SYS, false,
418                      "bit-vector1 bit-vector2 result-bit-vector")
419    {
420        @Override
421        public LispObject execute(LispObject first, LispObject second,
422                                  LispObject third)
423            throws ConditionThrowable
424        {
425            return ((SimpleBitVector)first).nor((SimpleBitVector)second,
426                                                 (SimpleBitVector)third);
427        }
428    };
429
430    // ### %simple-bit-vector-bit-andc1
431    private static final Primitive _SIMPLE_BIT_VECTOR_BIT_ANDC1 =
432        new Primitive("%simple-bit-vector-bit-andc1", PACKAGE_SYS, false,
433                      "bit-vector1 bit-vector2 result-bit-vector")
434    {
435        @Override
436        public LispObject execute(LispObject first, LispObject second,
437                                  LispObject third)
438            throws ConditionThrowable
439        {
440            return ((SimpleBitVector)first).andc1((SimpleBitVector)second,
441                                                  (SimpleBitVector)third);
442        }
443    };
444
445    // ### %simple-bit-vector-bit-andc2
446    private static final Primitive _SIMPLE_BIT_VECTOR_BIT_ANDC2 =
447        new Primitive("%simple-bit-vector-bit-andc2", PACKAGE_SYS, false,
448                      "bit-vector1 bit-vector2 result-bit-vector")
449    {
450        @Override
451        public LispObject execute(LispObject first, LispObject second,
452                                  LispObject third)
453            throws ConditionThrowable
454        {
455            return ((SimpleBitVector)first).andc2((SimpleBitVector)second,
456                                                  (SimpleBitVector)third);
457        }
458    };
459
460
461    // ### %simple-bit-vector-bit-orc1
462    private static final Primitive _SIMPLE_BIT_VECTOR_BIT_ORC1 =
463        new Primitive("%simple-bit-vector-bit-orc1", PACKAGE_SYS, false,
464                      "bit-vector1 bit-vector2 result-bit-vector")
465    {
466        @Override
467        public LispObject execute(LispObject first, LispObject second,
468                                  LispObject third)
469            throws ConditionThrowable
470        {
471            return ((SimpleBitVector)first).orc1((SimpleBitVector)second,
472                                                 (SimpleBitVector)third);
473        }
474    };
475
476    // ### %simple-bit-vector-bit-orc2
477    private static final Primitive _SIMPLE_BIT_VECTOR_BIT_ORC2 =
478        new Primitive("%simple-bit-vector-bit-orc2", PACKAGE_SYS, false,
479                      "bit-vector1 bit-vector2 result-bit-vector")
480    {
481        @Override
482        public LispObject execute(LispObject first, LispObject second,
483                                  LispObject third)
484            throws ConditionThrowable
485        {
486            return ((SimpleBitVector)first).orc2((SimpleBitVector)second,
487                                                 (SimpleBitVector)third);
488        }
489    };
490
491    // ### %simple-bit-vector-bit-not
492    private static final Primitive _SIMPLE_BIT_VECTOR_BIT_NOT =
493        new Primitive("%simple-bit-vector-bit-not", PACKAGE_SYS, false,
494                      "bit-vector result-bit-vector")
495    {
496        @Override
497        public LispObject execute(LispObject first, LispObject second)
498            throws ConditionThrowable
499        {
500            SimpleBitVector v = (SimpleBitVector) first;
501            SimpleBitVector result = (SimpleBitVector) second;
502            for (int i = v.bits.length; i-- > 0;)
503                result.bits[i] = ~v.bits[i];
504            return result;
505        }
506    };
507}
Note: See TracBrowser for help on using the repository browser.