View Javadoc
1   package nl.tudelft.simulation.dsol.animation.graph;
2   
3   import java.io.Serializable;
4   import java.util.ArrayList;
5   import java.util.Iterator;
6   import java.util.List;
7   
8   /**
9    * FloatList is a random access list of float values to which values can only be appended. It stores the values as primitives
10   * rather than as wrapping Objects. For the rest, it behaves like a regular list, with the exception of the absence of the
11   * add(i, value) method and the remove methods.
12   * <p>
13   * Copyright (c) 2020-2023 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
14   * for project information <a href="https://simulation.tudelft.nl/dsol/manual/" target="_blank">DSOL Manual</a>. The DSOL
15   * project is distributed under a three-clause BSD-style license, which can be found at
16   * <a href="https://https://simulation.tudelft.nl/dsol/docs/latest/license.html" target="_blank">DSOL License</a>.
17   * </p>
18   * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
19   */
20  public class FloatAppendList implements Iterable<Float>, Serializable
21  {
22      /** */
23      private static final long serialVersionUID = 20210103L;
24  
25      /** the chunk size. */
26      private static final int CHUNK_SIZE = 256;
27  
28      /** the number of bits of the chunk size. */
29      private static final int CHUNK_BITS = 8;
30  
31      /** the mask for the rightmost CHUNK_BITS bits. */
32      private static final int CHUNK_MASK = CHUNK_SIZE - 1;
33  
34      /** the backing list with chunks. */
35      private final List<float[]> storage = new ArrayList<>();
36  
37      /** the current chunk, already stored in the List. */
38      private float[] currentChunk;
39  
40      /** the total number of elements. */
41      private int numElements;
42  
43      /** the current in-chunk counter that indicates the next value to be written. */
44      private int inChunkNext;
45  
46      /**
47       * Initialize the FloatAppendList.
48       */
49      public FloatAppendList()
50      {
51          this.numElements = 0;
52          this.inChunkNext = 0;
53          this.currentChunk = new float[CHUNK_SIZE];
54          this.storage.add(this.currentChunk);
55      }
56  
57      /**
58       * Add a value to the list.
59       * @param value float; the value to add
60       */
61      public void add(final float value)
62      {
63          if (this.inChunkNext == CHUNK_SIZE)
64          {
65              this.inChunkNext = 0;
66              this.currentChunk = new float[CHUNK_SIZE];
67              this.storage.add(this.currentChunk);
68          }
69          this.currentChunk[this.inChunkNext] = value;
70          this.inChunkNext++;
71          this.numElements++;
72      }
73  
74      /**
75       * Return the number of elements.
76       * @return int; the number of elements
77       */
78      public int size()
79      {
80          return this.numElements;
81      }
82  
83      /**
84       * Return the value at a position.
85       * @param i int; the position
86       * @return float; the value at the position
87       * @throws IndexOutOfBoundsException when i &lt; 0 or i &gt; number of values
88       */
89      public float get(final int i)
90      {
91          if (i < 0 || i >= this.numElements)
92          {
93              throw new IndexOutOfBoundsException("FloatAppendList.get(i) -- i out of bounds.");
94          }
95          return this.storage.get(i >> CHUNK_BITS)[i & CHUNK_MASK];
96      }
97  
98      /** {@inheritDoc} */
99      @Override
100     public Iterator<Float> iterator()
101     {
102         return new FloatAppendIterator(this);
103     }
104 
105     /**
106      * An iterator for the FloatAppendList.
107      */
108     class FloatAppendIterator implements Iterator<Float>
109     {
110         /** the list to iterate over. */
111         private final FloatAppendList list;
112 
113         /** the counter. */
114         private int counter;
115 
116         /**
117          * Make an iterator for the FloatAppendList.
118          * @param list FloatAppendList; the list to iterate over
119          */
120         FloatAppendIterator(final FloatAppendList list)
121         {
122             this.list = list;
123             this.counter = 0;
124         }
125 
126         /** {@inheritDoc} */
127         @Override
128         public boolean hasNext()
129         {
130             return this.counter < this.list.size();
131         }
132 
133         /** {@inheritDoc} */
134         @Override
135         public Float next()
136         {
137             return this.list.get(this.counter++);
138         }
139     }
140 
141 }