View Javadoc

1   package org.jscsi.target.util;
2   
3   /**
4    * Instances of this class can serve as a source for byte arrays of specified lengths. Up to {@link #capacity} arrays of
5    * different lengths can be stored, quickly retrievable with the {@link #getArray(int)} method. Frequently requested
6    * arrays will be returned faster, less frequently used arrays might have to be initialized first and are more likely to
7    * be removed.
8    * 
9    * @author Andreas Ergenzinger
10   */
11  public final class FastByteArrayProvider {
12  
13      /**
14       * Contains the stored byte arrays.
15       */
16      final byte[][] arrays;
17  
18      /**
19       * The maximum number of array that can be stored.
20       */
21      final int capacity;
22  
23      /**
24       * The total number of stored arrays.
25       */
26      int size = 0;
27  
28      /**
29       * A temporary byte array reference used by {@link #getArray(int)};
30       */
31      byte[] tmp;
32  
33      /**
34       * The constructor.
35       * 
36       * @param capacity the {@link #capacity} of the created object.
37       */
38      public FastByteArrayProvider (final int capacity) {
39          this.capacity = capacity;
40          arrays = new byte[capacity][];
41      }
42  
43      /**
44       * Returns a byte array of the specified length.
45       * <p>
46       * Note that the returned array may have been used before and therefore the array's values are not guaranteed to be
47       * <code>0</code>.
48       * <p>
49       * The method consecutively checks {@link #arrays} for an array of the correct length. If such an array exists, it
50       * will be moved to one index position closer to the front of the array (if possible), speeding up future retrievals
51       * of the same array.
52       * 
53       * @param length the length of the returned array
54       * @return a byte array of the specified length
55       */
56      public byte[] getArray (final int length) {
57          for (int i = 0; i < size; ++i) {
58              if (length == arrays[i].length) {
59                  // swap (if not already at the front) and return
60                  if (i > 0) {
61                      tmp = arrays[i];
62                      arrays[i] = arrays[i - 1];
63                      arrays[i - 1] = tmp;
64                      return tmp;
65                  }
66                  // no swapping, so element was and still is at the front of the
67                  // list
68                  return arrays[0];
69              }
70          }
71          // requested array does not exist, add to tail of queue,
72          tmp = new byte[length];
73          if (size == capacity) --size;// replace last element
74          arrays[size] = tmp;
75          ++size;
76          return tmp;
77      }
78  
79      /**
80       * Returns all stored byte arrays.
81       * <p>
82       * This method's primary purpose is to enable testing of byte array storing and reordering.
83       * 
84       * @return {@link #arrays}.
85       */
86      public byte[][] getAll () {
87          return arrays;
88      }
89  }