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