Skip to content

Commit

Permalink
Add extra array helper class.
Browse files Browse the repository at this point in the history
Change-Id: Ifa07e71e0b16ce063282138d6a499fabab9f3786
  • Loading branch information
dankurka committed Jul 10, 2015
1 parent c8a81f9 commit 6f26e54
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 109 deletions.
Expand Up @@ -38,15 +38,6 @@ public final class Array {
private static final int TYPE_PRIMITIVE_NUMBER = 7;
private static final int TYPE_PRIMITIVE_BOOLEAN = 8;

private static final int ARRAY_PROCESS_BATCH_SIZE = 10000;

/**
* Creates a copy of the specified array.
*/
public static <T> T[] clone(T[] array) {
return cloneSubrange(array, 0, array.length);
}

/**
* Creates a copy of a subrange of the specified array.
*/
Expand All @@ -58,13 +49,6 @@ public static <T> T[] cloneSubrange(T[] array, int fromIndex, int toIndex) {
return Array.<T> asArray(result);
}

/**
* Creates a new array of the exact same type and length as a given array.
*/
public static <T> T[] createFrom(T[] array) {
return createFrom(array, array.length);
}

/**
* Creates an empty array of the exact same type as a given array, with the
* specified length.
Expand Down Expand Up @@ -157,61 +141,6 @@ public static Object initValues(Class<?> arrayClass, JavaScriptObject castableTy
return array;
}

/**
* Copy an array using native Javascript. The destination array must be a real
* Java array (ie, already has the GWT type info on it). No error checking is performed -- the
* caller is expected to have verified everything first.
*
* @param src source array for copy
* @param srcOfs offset into source array
* @param dest destination array for copy
* @param destOfs offset into destination array
* @param len number of elements to copy
*/
public static void nativeArraycopy(Object src, int srcOfs, Object dest, int destOfs, int len) {
nativeArraySplice(src, srcOfs, dest, destOfs, len, true);
}

/**
* Insert one array into another native Javascript. The destination array must be a real
* Java array (ie, already has the GWT type info on it). No error checking is performed -- the
* caller is expected to have verified everything first.
*
* @param src source array where the data is taken from
* @param srcOfs offset into source array
* @param dest destination array for the data to be inserted
* @param destOfs offset into destination array
* @param len number of elements to insert
*/
public static void nativeArrayInsert(Object src, int srcOfs, Object dest, int destOfs,
int len) {
nativeArraySplice(src, srcOfs, dest, destOfs, len, false);
}

/**
* A replacement for Array.prototype.splice to overcome the limits imposed to the number of
* function parameters by browsers.
*/
private static native void nativeArraySplice(
Object src, int srcOfs, Object dest, int destOfs, int len, boolean overwrite) /*-{
// Work around function.prototype.apply call stack size limits:
// https://code.google.com/p/v8/issues/detail?id=2896
// Performance: http://jsperf.com/java-system-arraycopy/2
if (src === dest) {
// copying to the same array, make a copy first
src = src.slice(srcOfs, srcOfs + len);
srcOfs = 0;
}
for (var batchStart = srcOfs, end = srcOfs + len; batchStart < end;) { // increment in block
var batchEnd = Math.min(batchStart + @Array::ARRAY_PROCESS_BATCH_SIZE, end);
len = batchEnd - batchStart;
Array.prototype.splice.apply(dest, [destOfs, overwrite ? len : 0]
.concat(src.slice(batchStart, batchEnd)));
batchStart = batchEnd;
destOfs += len;
}
}-*/;

/**
* Performs an array assignment, after validating the type of the value being
* stored. The form of the type check depends on the value of elementTypeId and
Expand Down
72 changes: 72 additions & 0 deletions user/super/com/google/gwt/emul/java/internal/ArrayHelper.java
@@ -0,0 +1,72 @@
/*
* Copyright 2015 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package java.internal;

/**
* Forwards array operations to GWT's internal array class.
*/
public class ArrayHelper {

private static final int ARRAY_PROCESS_BATCH_SIZE = 10000;

public static native <T> T[] clone(T[] array, int fromIndex, int toIndex) /*-{
return @com.google.gwt.lang.Array::cloneSubrange(*)(array, fromIndex, toIndex);
}-*/;

public static native <T> T[] createFrom(T[] array, int length) /*-{
return @com.google.gwt.lang.Array::createFrom(*)(array, length);
}-*/;

public static void arrayCopy(Object src, int srcOfs, Object dest, int destOfs, int len) {
arraySplice(src, srcOfs, dest, destOfs, len, true);
}

public static void arrayInsert(Object src, int srcOfs, Object dest, int destOfs, int len) {
arraySplice(src, srcOfs, dest, destOfs, len, false);
}

/**
* A replacement for Array.prototype.splice to overcome the limits imposed to the number of
* function parameters by browsers.
*/
private static void arraySplice(
Object src, int srcOfs, Object dest, int destOfs, int len, boolean overwrite) {
if (src == dest) {
// copying to the same array, make a copy first
src = nativeArraySlice(src, srcOfs, srcOfs + len);
srcOfs = 0;
}
for (int batchStart = srcOfs, end = srcOfs + len; batchStart < end;) {
// increment in block
int batchEnd = Math.min(batchStart + ARRAY_PROCESS_BATCH_SIZE, end);
len = batchEnd - batchStart;
nativeArraySplice(
dest, destOfs, overwrite ? len : 0, nativeArraySlice(src, batchStart, batchEnd));
batchStart = batchEnd;
destOfs += len;
}
}

private static native Object nativeArraySlice(Object arrayToSclice, int start, int end) /*-{
return arrayToSclice.slice(start, end);
}-*/;

private static native Object nativeArraySplice(Object array, int index, int deleteCount,
Object arrayToAdd) /*-{
Array.prototype.splice.apply(array, [index, deleteCount].concat(arrayToAdd));
}-*/;
}

2 changes: 1 addition & 1 deletion user/super/com/google/gwt/emul/java/lang/String.java
Expand Up @@ -282,7 +282,7 @@ static native String __valueOf(char x[], int start, int end) /*-{
// Work around function.prototype.apply call stack size limits:
// https://code.google.com/p/v8/issues/detail?id=2896
// Performance: http://jsperf.com/string-fromcharcode-test/13
var batchSize = @com.google.gwt.lang.Array::ARRAY_PROCESS_BATCH_SIZE;
var batchSize = @java.internal.ArrayHelper::ARRAY_PROCESS_BATCH_SIZE;
var s = "";
for (var batchStart = start; batchStart < end;) { // increment in block
var batchEnd = Math.min(batchStart + batchSize, end);
Expand Down
10 changes: 5 additions & 5 deletions user/super/com/google/gwt/emul/java/lang/System.java
Expand Up @@ -15,13 +15,13 @@
*/
package java.lang;

import com.google.gwt.core.client.JsDate;
import com.google.gwt.core.client.impl.Impl;
import com.google.gwt.lang.Array;

import static java.internal.InternalPreconditions.checkArrayType;
import static java.internal.InternalPreconditions.checkNotNull;

import com.google.gwt.core.client.JsDate;
import com.google.gwt.core.client.impl.Impl;

import java.internal.ArrayHelper;
import java.io.PrintStream;

/**
Expand Down Expand Up @@ -85,7 +85,7 @@ public static void arraycopy(Object src, int srcOfs, Object dest, int destOfs, i
}
}
} else if (len > 0) {
Array.nativeArraycopy(src, srcOfs, dest, destOfs, len);
ArrayHelper.arrayCopy(src, srcOfs, dest, destOfs, len);
}
}

Expand Down
Expand Up @@ -15,10 +15,10 @@
*/
package java.util;

import com.google.gwt.lang.Array;

import static java.internal.InternalPreconditions.checkNotNull;

import java.internal.ArrayHelper;

/**
* Skeletal implementation of the Collection interface. <a
* href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/AbstractCollection.html">[Sun
Expand Down Expand Up @@ -128,7 +128,7 @@ public Object[] toArray() {
public <T> T[] toArray(T[] a) {
int size = size();
if (a.length < size) {
a = Array.createFrom(a, size);
a = ArrayHelper.createFrom(a, size);
}
Object[] result = a;
Iterator<E> it = iterator();
Expand Down
9 changes: 4 additions & 5 deletions user/super/com/google/gwt/emul/java/util/ArrayList.java
Expand Up @@ -15,13 +15,12 @@
*/
package java.util;

import com.google.gwt.lang.Array;

import static java.internal.InternalPreconditions.checkArgument;
import static java.internal.InternalPreconditions.checkElementIndex;
import static java.internal.InternalPreconditions.checkPositionIndex;
import static java.internal.InternalPreconditions.checkPositionIndexes;

import java.internal.ArrayHelper;
import java.io.Serializable;

/**
Expand Down Expand Up @@ -55,7 +54,7 @@ private static native void splice(Object[] array, int index, int deleteCount,
}-*/;

private void insertAt(int index, Object[] values) {
Array.nativeArrayInsert(values, 0, array, index, values.length);
ArrayHelper.arrayInsert(values, 0, array, index, values.length);
}

/**
Expand Down Expand Up @@ -188,7 +187,7 @@ public int size() {

@Override
public Object[] toArray() {
return Array.cloneSubrange(array, 0, array.length);
return ArrayHelper.clone(array, 0, array.length);
}

/*
Expand All @@ -199,7 +198,7 @@ public Object[] toArray() {
public <T> T[] toArray(T[] out) {
int size = array.length;
if (out.length < size) {
out = Array.createFrom(out, size);
out = ArrayHelper.createFrom(out, size);
}
for (int i = 0; i < size; ++i) {
out[i] = (T) array[i];
Expand Down
18 changes: 9 additions & 9 deletions user/super/com/google/gwt/emul/java/util/Arrays.java
Expand Up @@ -18,15 +18,15 @@

import static com.google.gwt.core.client.impl.Coercions.ensureInt;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.UnsafeNativeLong;
import com.google.gwt.lang.Array;

import static java.internal.InternalPreconditions.checkArgument;
import static java.internal.InternalPreconditions.checkArraySize;
import static java.internal.InternalPreconditions.checkElementIndex;
import static java.internal.InternalPreconditions.checkPositionIndexes;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.UnsafeNativeLong;

import java.internal.ArrayHelper;
import java.io.Serializable;

/**
Expand Down Expand Up @@ -78,7 +78,7 @@ public int size() {
*/
@Override
public Object[] toArray() {
return Array.clone(array);
return ArrayHelper.clone(array, 0, array.length);
}

/*
Expand All @@ -89,7 +89,7 @@ public Object[] toArray() {
public <T> T[] toArray(T[] out) {
int size = size();
if (out.length < size) {
out = Array.createFrom(out, size);
out = ArrayHelper.createFrom(out, size);
}
for (int i = 0; i < size; ++i) {
out[i] = (T) array[i];
Expand Down Expand Up @@ -502,7 +502,7 @@ public static short[] copyOfRange(short[] original, int from, int to) {

public static <T> T[] copyOfRange(T[] original, int from, int to) {
int newLength = getLengthFromRange(from, to);
T[] copy = Array.createFrom(original, newLength);
T[] copy = ArrayHelper.createFrom(original, newLength);
System.arraycopy(original, from, copy, 0,
Math.min(original.length - from, newLength));
return copy;
Expand Down Expand Up @@ -1428,7 +1428,7 @@ private static native void nativeLongSort(Object array, int fromIndex,
var temp = array.slice(fromIndex, toIndex);
temp.sort(@com.google.gwt.lang.LongLib::compare(Lcom/google/gwt/lang/LongLibBase$LongEmul;Lcom/google/gwt/lang/LongLibBase$LongEmul;));
var n = toIndex - fromIndex;
@com.google.gwt.lang.Array::nativeArraycopy(Ljava/lang/Object;ILjava/lang/Object;II)(
@java.internal.ArrayHelper::arrayCopy(Ljava/lang/Object;ILjava/lang/Object;II)(
temp, 0, array, fromIndex, n)
}-*/;

Expand All @@ -1451,7 +1451,7 @@ private static native void nativeNumberSort(Object array, int fromIndex,
return a - b;
});
var n = toIndex - fromIndex;
@com.google.gwt.lang.Array::nativeArraycopy(Ljava/lang/Object;ILjava/lang/Object;II)(
@java.internal.ArrayHelper::arrayCopy(Ljava/lang/Object;ILjava/lang/Object;II)(
temp, 0, array, fromIndex, n)
}-*/;

Expand Down
6 changes: 3 additions & 3 deletions user/super/com/google/gwt/emul/java/util/EnumMap.java
Expand Up @@ -15,11 +15,11 @@
*/
package java.util;

import com.google.gwt.lang.Array;

import static java.internal.InternalPreconditions.checkArgument;
import static java.internal.InternalPreconditions.checkState;

import java.internal.ArrayHelper;

/**
* A {@link java.util.Map} of {@link Enum}s. <a
* href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/EnumMap.html">[Sun
Expand Down Expand Up @@ -210,7 +210,7 @@ private void init(Class<K> type) {

private void init(EnumMap<K, ? extends V> m) {
keySet = m.keySet.clone();
values = Array.clone(m.values);
values = ArrayHelper.clone(m.values, 0, m.values.length);
}

private V set(int ordinal, V value) {
Expand Down

0 comments on commit 6f26e54

Please sign in to comment.