/src/com/google/appengine/datanucleus/Longs.java
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}