PageRenderTime 27ms CodeModel.GetById 8ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 0ms

/src/com/google/appengine/datanucleus/Longs.java

http://datanucleus-appengine.googlecode.com/
Java | 228 lines | 145 code | 24 blank | 59 comment | 28 complexity | d5a21ac368dd851bee39db3812b79978 MD5 | raw file
  1/**********************************************************************
  2Copyright (c) 2009 Google Inc.
  3
  4Licensed under the Apache License, Version 2.0 (the "License");
  5you may not use this file except in compliance with the License.
  6You may obtain a copy of the License at
  7
  8http://www.apache.org/licenses/LICENSE-2.0
  9
 10Unless required by applicable law or agreed to in writing, software
 11distributed under the License is distributed on an "AS IS" BASIS,
 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13See the License for the specific language governing permissions and
 14limitations under the License.
 15**********************************************************************/
 16package com.google.appengine.datanucleus;
 17
 18import java.io.Serializable;
 19import java.util.AbstractList;
 20import java.util.Arrays;
 21import java.util.Collection;
 22import java.util.Collections;
 23import java.util.List;
 24import java.util.RandomAccess;
 25
 26/**
 27 * Static utility methods pertaining to {@code long} primitives, that are not
 28 * already found in either {@link Long} or {@link Arrays}.
 29 *
 30 * @author Kevin Bourrillion
 31 */
 32final class Longs {
 33  private Longs() {}
 34
 35  /**
 36   * Returns a hash code for {@code value}; equal to the result of invoking
 37   * {@code ((Long) value).hashCode()}.
 38   *
 39   * @param value a primitive {@code long} value
 40   * @return a hash code for the value
 41   */
 42  private static int hashCode(long value) {
 43    return (int) (value ^ (value >>> 32));
 44  }
 45
 46  // TODO(kevinb): consider making this public
 47  private static int indexOf(long target, long[] array, int start, int end) {
 48    for (int i = start; i < end; i++) {
 49      if (array[i] == target) {
 50        return i;
 51      }
 52    }
 53    return -1;
 54  }
 55
 56  // TODO(kevinb): consider making this public
 57  private static int lastIndexOf(
 58      long target, long[] array, int start, int end) {
 59    for (int i = end - 1; i >= start; i--) {
 60      if (array[i] == target) {
 61        return i;
 62      }
 63    }
 64    return -1;
 65  }
 66
 67  /**
 68   * Copies a collection of {@code Long} instances into a new array of
 69   * primitive {@code long} values.
 70   *
 71   * @param collection a collection of {@code Long} objects
 72   * @return an array containing the same values as {@code collection}, in the
 73   *     same order, converted to primitives
 74   * @throws NullPointerException if {@code collection} or any of its elements
 75   *     are null
 76   */
 77  static long[] toArray(Collection<Long> collection) {
 78    if (collection instanceof LongArrayAsList) {
 79      return ((LongArrayAsList) collection).toLongArray();
 80    }
 81
 82    // TODO(kevinb): handle collection being concurrently modified
 83    int counter = 0;
 84    long[] array = new long[collection.size()];
 85    for (Long value : collection) {
 86      array[counter++] = value;
 87    }
 88    return array;
 89  }
 90
 91  /**
 92   * Returns a fixed-size list backed by the specified array, similar to {@link
 93   * Arrays#asList(Object[])}. The list supports {@link List#set(int, Object)},
 94   * but any attempt to set a value to {@code null} will result in a {@link
 95   * NullPointerException}.
 96   *
 97   * <p>The returned list maintains the values, but not the identities, of
 98   * {@code Long} objects written to or read from it.  For example, whether
 99   * {@code list.get(0) == list.get(0)} is true for the returned list is
100   * unspecified.
101   *
102   * @param backingArray the array to back the list
103   * @return a list view of the array
104   */
105  static List<Long> asList(long... backingArray) {
106    if (backingArray.length == 0) {
107      return Collections.emptyList();
108    }
109    return new LongArrayAsList(backingArray);
110  }
111
112  private static class LongArrayAsList extends AbstractList<Long>
113      implements RandomAccess, Serializable {
114    final long[] array;
115    final int start;
116    final int end;
117
118    LongArrayAsList(long[] array) {
119      this(array, 0, array.length);
120    }
121
122    LongArrayAsList(long[] array, int start, int end) {
123      this.array = array;
124      this.start = start;
125      this.end = end;
126    }
127
128    @Override public int size() {
129      return end - start;
130    }
131
132    @Override public boolean isEmpty() {
133      return false;
134    }
135
136    @Override public Long get(int index) {
137      return array[start + index];
138    }
139
140    @Override public boolean contains(Object target) {
141      // Overridden to prevent a ton of boxing
142      return (target instanceof Long)
143          && Longs.indexOf((Long) target, array, start, end) != -1;
144    }
145
146    @Override public int indexOf(Object target) {
147      // Overridden to prevent a ton of boxing
148      if (target instanceof Long) {
149        int i = Longs.indexOf((Long) target, array, start, end);
150        if (i >= 0) {
151          return i - start;
152        }
153      }
154      return -1;
155    }
156
157    @Override public int lastIndexOf(Object target) {
158      // Overridden to prevent a ton of boxing
159      if (target instanceof Long) {
160        int i = Longs.lastIndexOf((Long) target, array, start, end);
161        if (i >= 0) {
162          return i - start;
163        }
164      }
165      return -1;
166    }
167
168    @Override public Long set(int index, Long element) {
169      long oldValue = array[start + index];
170      array[start + index] = element;
171      return oldValue;
172    }
173
174    @Override public List<Long> subList(int fromIndex, int toIndex) {
175      if (fromIndex == toIndex) {
176        return Collections.emptyList();
177      }
178      return new LongArrayAsList(array, start + fromIndex, start + toIndex);
179    }
180
181    @Override public boolean equals(Object object) {
182      if (object == this) {
183        return true;
184      }
185      if (object instanceof LongArrayAsList) {
186        LongArrayAsList that = (LongArrayAsList) object;
187        int size = size();
188        if (that.size() != size) {
189          return false;
190        }
191        for (int i = 0; i < size; i++) {
192          if (array[start + i] != that.array[that.start + i]) {
193            return false;
194          }
195        }
196        return true;
197      }
198      return super.equals(object);
199    }
200
201    @Override public int hashCode() {
202      int result = 1;
203      for (int i = start; i < end; i++) {
204        result = 31 * result + Longs.hashCode(array[i]);
205      }
206      return result;
207    }
208
209    @Override public String toString() {
210      StringBuilder builder = new StringBuilder(size() * 10);
211      builder.append('[').append(array[start]);
212      for (int i = start + 1; i < end; i++) {
213        builder.append(", ").append(array[i]);
214      }
215      return builder.append(']').toString();
216    }
217
218    long[] toLongArray() {
219      // Arrays.copyOfRange() requires Java 6
220      int size = size();
221      long[] result = new long[size];
222      System.arraycopy(array, start, result, 0, size);
223      return result;
224    }
225
226    private static final long serialVersionUID = 0;
227  }
228}