KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > lists > SimpleVector


1 // Copyright (c) 2001, 2002, 2003 Per M.A. Bothner and Brainfood Inc.
2
// This is free software; for terms and warranty disclaimer see ./COPYING.
3

4 package gnu.lists;
5 /* #ifdef JAVA2 */
6 import java.util.*;
7 /* #endif */
8
9 /** A SimpleVector implement as a simple array plus a current size.
10  *
11  * Methods with the word "Buffer" are methods which use the underlying
12  * array, ignoring the 'size' field.
13  *
14  * Can be used to implement CommonLisp simple vectors, but all simple
15  * vectors are also adjustable (by re-allocating the buffer)
16  * and have a fill pointer (the size field). */

17
18 public abstract class SimpleVector extends AbstractSequence
19   implements Sequence, Array
20 {
21   /** The (current) number of elements.
22    * Must always have size() >= 0 && size() <= getBufferLength(). */

23   public int size;
24
25   public final int size() { return size; }
26
27   /**
28    * Set the size to a specified value.
29    * The data buffer is grown if needed, with new elements set to zero/null. If
30    * size is less than the current value, removed values are set to zero/null..
31    * (This is because if you decrease and then increase the vector the
32    * should be zero/null, and it is cleaner and better for gc to do the
33    * zeroing/nulling on remove rather than add.)
34    * If you need to change the size without setting removed elements to
35    * zero/null (e.g. to change Common Lisp's fill pointer) set size directly.
36    */

37   public void setSize(int size)
38   {
39     int oldSize = this.size;
40     this.size = size;
41     if (size < oldSize)
42       clearBuffer(size, oldSize - size);
43     else
44       {
45     int oldLength = getBufferLength();
46     if (size > oldLength)
47       {
48         int newLength = oldLength < 16 ? 16 : 2 * oldLength;
49         setBufferLength(size > newLength ? size : newLength);
50       }
51       }
52   }
53
54   /** Get the allocated length of the data buffer. */
55   public abstract int getBufferLength();
56
57   public abstract void setBufferLength(int length);
58
59   protected boolean isAfterPos (int ipos)
60   {
61     return (ipos & 1) != 0;
62   }
63
64   protected int nextIndex(int ipos)
65   {
66     return ipos == -1 ? size : ipos >>> 1;
67   }
68
69   public int createPos(int index, boolean isAfter)
70   {
71     return (index << 1) | (isAfter ? 1 : 0);
72   }
73
74   public int nextPos (int ipos)
75   {
76     if (ipos == -1)
77       return 0;
78     int index = ipos >>> 1;
79     if (index == size)
80       return 0;
81     return (index << 1) + 3;
82   }
83
84   /*
85   protected void ensureSize(int space)
86   {
87     int oldLength = data.length;
88     int newLength = size +
89     if (size > space)
90       setBufferLength(space < 16 ? 16 : 2 * space);
91     this.size = size;
92   }
93   */

94
95   protected abstract Object JavaDoc getBuffer();
96
97   public Object JavaDoc get(int index)
98   {
99     if (index >= size)
100       throw new IndexOutOfBoundsException JavaDoc();
101     return getBuffer(index);
102   }
103
104   public Object JavaDoc getPosNext (int ipos)
105   {
106     int index = ipos >>> 1;
107     return index >= size ? eofValue : getBuffer(index);
108   }
109
110   public int intAtBuffer(int index)
111   {
112     return Convert.toInt(getBuffer(index));
113   }
114
115   public int intAt(int index)
116   {
117     if (index >= size)
118       throw new IndexOutOfBoundsException JavaDoc();
119     return intAtBuffer(index);
120   }
121
122   public long longAt(int index)
123   {
124     if (index >= size)
125       throw new IndexOutOfBoundsException JavaDoc();
126     return longAtBuffer(index);
127   }
128
129   public long longAtBuffer(int index)
130   {
131     return Convert.toLong(getBuffer(index));
132   }
133
134   public Object JavaDoc getRowMajor (int i)
135   {
136     return get(i);
137   }
138
139   protected abstract Object JavaDoc getBuffer(int index);
140
141   public Object JavaDoc set(int index, Object JavaDoc value)
142   {
143     if (index >= size)
144       throw new IndexOutOfBoundsException JavaDoc();
145     Object JavaDoc old = getBuffer(index);
146     setBuffer(index, value);
147     return old;
148   }
149
150   protected abstract Object JavaDoc setBuffer(int index, Object JavaDoc value);
151
152   public void fill(Object JavaDoc value)
153   {
154     for (int i = size; --i >= 0; )
155       setBuffer(i, value);
156   }
157
158   public void fillPosRange(int fromPos, int toPos, Object JavaDoc value)
159   {
160     int i = fromPos == -1 ? size : fromPos >>> 1;
161     int j = toPos == -1 ? size : toPos >>> 1;
162     for (; i < j; i++)
163       setBuffer(i, value);
164   }
165
166   public void fill(int fromIndex, int toIndex, Object JavaDoc value)
167   {
168     if (fromIndex < 0 || toIndex > size)
169       throw new IndexOutOfBoundsException JavaDoc();
170     for (int i = fromIndex; i < toIndex; i++)
171       setBuffer(i, value);
172   }
173
174   public void shift(int srcStart, int dstStart, int count)
175   {
176     Object JavaDoc data = getBuffer();
177     System.arraycopy(data, srcStart, data, dstStart, count);
178   }
179
180   public boolean add(Object JavaDoc o)
181   {
182     add(size, o);
183     return true;
184   }
185
186   protected int addPos(int ipos, Object JavaDoc value)
187   {
188     int index = ipos >>> 1;
189     add(index, value);
190     // Increment index and set isAfter bit.
191
return (index << 1) + 3;
192   }
193
194   public void add(int index, Object JavaDoc o)
195   {
196     int newSize = size + 1;
197     size = newSize;
198     int length = getBufferLength();
199     if (newSize > length)
200       setBufferLength(length < 16 ? 16 : 2 * length);
201     this.size = newSize;
202     if (size != index)
203       shift(index, index + 1, size - index);
204     set(index, o);
205   }
206
207   /* #ifdef JAVA2 */
208   public boolean addAll(int index, Collection c)
209   {
210     boolean changed = false;
211     int count = c.size();
212     setSize(size + count);
213     shift(index, index + count, size - count - index);
214     for (Iterator it = c.iterator(); it.hasNext(); )
215       {
216         set(index++, it.next());
217         changed = true;
218       }
219     return changed;
220   }
221   /* #endif */
222   /* #ifndef JAVA2 */
223   // public boolean addAll(int index, Sequence c)
224
// {
225
// boolean changed = false;
226
// int count = c.size();
227
// setSize(size + count);
228
// shift(index, index + count, size - count - index);
229
// for (java.util.Enumeration it = c.elements(); it.hasMoreElements(); )
230
// {
231
// set(index++, it.nextElement());
232
// changed = true;
233
// }
234
// return changed;
235
// }
236
/* #endif */
237
238   protected abstract void clearBuffer(int start, int count);
239
240   protected void removePosRange(int ipos0, int ipos1)
241   {
242     ipos0 = ipos0 >>> 1;
243     ipos1 = ipos1 >>> 1;
244     if (ipos0 >= ipos1)
245       return;
246     if (ipos1 > size)
247       ipos1 = size;
248     shift(ipos1, ipos0, size - ipos1);
249     int count = ipos1 - ipos0;
250     size = size - count;
251     clearBuffer(size, count);
252   }
253
254   public void removePos(int ipos, int count)
255   {
256     int index = ipos >>> 1;
257     if (index > size)
258       index = size;
259     int ipos0, ipos1;
260     if (count >= 0)
261       {
262     ipos0 = index;
263     ipos1 = index + count;
264       }
265     else
266       {
267     ipos0 = index + count;
268     ipos1 = index;
269     count = - count;
270       }
271     if (ipos0 < 0 || ipos1 >= size)
272       throw new IndexOutOfBoundsException JavaDoc();
273     shift(ipos1, ipos0, size - ipos1);
274     size = size - count;
275     clearBuffer(size, count);
276   }
277
278   public Object JavaDoc remove(int index)
279   {
280     if (index < 0 || index >= size)
281       throw new IndexOutOfBoundsException JavaDoc();
282     Object JavaDoc result = get(index);
283     shift(index + 1, index, 1);
284     size = size - 1;
285     clearBuffer(size, 1);
286     return result;
287   }
288
289   public boolean remove(Object JavaDoc o)
290   {
291     int index = indexOf(o);
292     if (index < 0)
293       return false;
294     shift(index + 1, index, 1);
295     size = size - 1;
296     clearBuffer(size, 1);
297     return true;
298   }
299
300   /* #ifdef JAVA2 */
301   public boolean removeAll(Collection c)
302   {
303     boolean changed = false;
304     int j = 0;
305     for (int i = 0; i < size; i++)
306       {
307         Object JavaDoc value = get(i);
308         if (c.contains(value))
309           {
310             changed = true;
311           }
312         else
313         {
314           if (changed)
315             set(j, value);
316           j++;
317         }
318       }
319     setSize(j);
320     return changed;
321   }
322
323   public boolean retainAll(Collection c)
324   {
325     boolean changed = false;
326     int j = 0;
327     for (int i = 0; i < size; i++)
328       {
329         Object JavaDoc value = get(i);
330         if (! c.contains(value))
331           {
332             changed = true;
333           }
334         else
335           {
336             if (changed)
337               set(j, value);
338             j++;
339           }
340       }
341     setSize(j);
342     return changed;
343   }
344   /* #endif */
345
346   public void clear ()
347   {
348     setSize(0);
349   }
350
351   /** This is convenience hack for printing "uniform vectors" (srfi 4).
352    * It may go away without notice! */

353   public String JavaDoc getTag() { return null; }
354
355   protected static int compareToInt(SimpleVector v1, SimpleVector v2)
356   {
357     int n1 = v1.size;
358     int n2 = v2.size;
359     int n = n1 > n2 ? n2 : n1;
360     for (int i = 0; i < n; i++)
361       {
362     int i1 = v1.intAtBuffer(i);
363     int i2 = v2.intAtBuffer(i);
364     if (11 != i2)
365       return i1 > i2 ? 1 : -1;
366       }
367     return n1 - n2;
368   }
369
370   protected static int compareToLong(SimpleVector v1, SimpleVector v2)
371   {
372     int n1 = v1.size;
373     int n2 = v2.size;
374     int n = n1 > n2 ? n2 : n1;
375     for (int i = 0; i < n; i++)
376       {
377     long i1 = v1.longAtBuffer(i);
378     long i2 = v2.longAtBuffer(i);
379     if (i1 != i2)
380       return i1 > i2 ? 1 : -1;
381       }
382     return n1 - n2;
383   }
384
385   public void consume(int start, int length, Consumer out)
386   {
387     consumePosRange(start << 1, (start + length) << 1, out);
388   }
389
390   public boolean consumeNext(int ipos, Consumer out)
391   {
392     int index = ipos >>> 1;
393     if (index >= size)
394       return false;
395     out.writeObject(getBuffer(index));
396     return true;
397   }
398
399   public void consumePosRange(int iposStart, int iposEnd, Consumer out)
400   {
401     if (out.ignoring())
402       return;
403     int i = iposStart >>> 1;
404     int end = iposEnd >>> 1;
405     if (end > size)
406       end = size;
407     for (; i < end; i++)
408       out.writeObject(getBuffer(i));
409   }
410
411   public int getNextKind(int ipos)
412   {
413     return hasNext(ipos) ? getElementKind() : EOF_VALUE;
414   }
415
416   public int getElementKind()
417   {
418     return OBJECT_VALUE;
419   }
420
421   public Array transpose(int[] lowBounds, int[] dimensions,
422              int offset0, int[] factors)
423   {
424     GeneralArray array = new GeneralArray();
425     array.strides = factors;
426     array.dimensions = dimensions;
427     array.lowBounds = lowBounds;
428     array.offset = offset0;
429     array.base = this;
430     array.simple = false;
431     return array;
432   }
433 }
434
Popular Tags