aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/util
diff options
context:
space:
mode:
authorGravatar Klaas Boesche <klaasb@google.com>2015-10-05 14:39:50 +0000
committerGravatar Damien Martin-Guillerez <dmarting@google.com>2015-10-05 15:16:54 +0000
commit358db6450bdfcd80c6f3d11cc2010fce548a1bc1 (patch)
tree5349d4fa410df61106d428c4d51cb305583b081b /src/main/java/com/google/devtools/build/lib/util
parenta67ac5c6fc2b7b5c20a0fd87fe5b8c61fd346b7f (diff)
Refactor SkylarkStatistics to reduce size.
Does not save all Tasks anymore and generates TasksStatistics on the fly. Adds an ArrayList implementation for primitive longs to efficiently save a lot of task duration data. Necessary when loading lots of profile files. -- MOS_MIGRATED_REVID=104656311
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/util')
-rw-r--r--src/main/java/com/google/devtools/build/lib/util/LongArrayList.java285
1 files changed, 285 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/util/LongArrayList.java b/src/main/java/com/google/devtools/build/lib/util/LongArrayList.java
new file mode 100644
index 0000000000..d3ebb3cc18
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/util/LongArrayList.java
@@ -0,0 +1,285 @@
+// Copyright 2015 The Bazel Authors. All rights reserved.
+//
+// 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 com.google.devtools.build.lib.util;
+
+import com.google.common.base.Preconditions;
+
+import java.util.Arrays;
+
+/**
+ * A list of primitive long values.
+ *
+ * <p>Grows its backing array internally when necessary and such that constant amortized addition of
+ * elements is guaranteed.
+ *
+ * <p>Does not shrink its array except by explicit calls to {@link #trim}.
+ */
+public class LongArrayList {
+
+ private static final int DEFAULT_CAPACITY = 12;
+
+ private long[] array;
+ private int size;
+
+ /**
+ * Initialize a new LongArrayList with default capacity.
+ */
+ public LongArrayList() {
+ this.array = new long[DEFAULT_CAPACITY];
+ }
+
+ /**
+ * Initialize a new LongArrayList with space for elements equal to the given capacity.
+ * @throws IndexOutOfBoundsException if the capacity is negative
+ */
+ public LongArrayList(int capacity) {
+ Preconditions.checkArgument(capacity >= 0, "Initial capacity must not be negative.");
+ this.array = new long[capacity];
+ }
+
+ /**
+ * Create a new LongArrayList backed by the given array. No copy is made.
+ */
+ public LongArrayList(long[] array) {
+ Preconditions.checkNotNull(array);
+ this.array = array;
+ this.size = array.length;
+ }
+
+ /**
+ * Add a value at a specific position to this list. All elements at larger indices will
+ * shift to the right by one.
+ * @param position may be any index within the array or equal to the size, to append at the end
+ * @throws IndexOutOfBoundsException if the index is outside the interval [0, {@link #size()})
+ */
+ public void add(int position, long value) {
+ Preconditions.checkPositionIndex(position, size);
+ copyBackAndGrow(position, 1);
+ set(position, value);
+ }
+
+ /**
+ * Add a value to the end of this list.
+ */
+ public void add(long value) {
+ add(size, value);
+ }
+
+ /**
+ * Add all elements from another LongArrayList at the end of this one.
+ * @see #addAll(LongArrayList, int)
+ */
+ public boolean addAll(LongArrayList other) {
+ return addAll(other.array, 0, other.size, size);
+ }
+
+ /**
+ * Add all elements from another LongArrayList at a certain position within or at the end of
+ * this one.
+ * @param other
+ * @param position at which position to add these elements, adds at the end if equal to the size
+ * @return whether this list changed
+ * @throws IndexOutOfBoundsException if the index is outside the interval [0, {@link #size()}]
+ */
+ public boolean addAll(LongArrayList other, int position) {
+ return addAll(other.array, 0, other.size, position);
+ }
+
+ /**
+ * Add all elements from the given array to the end of this array.
+ * @see #addAll(long[], int, int, int)
+ */
+ public boolean addAll(long[] array) {
+ return addAll(array, 0, array.length, size);
+ }
+
+ /**
+ * Add certain elements from the given array to the end of this array.
+ * @see #addAll(long[], int, int, int)
+ */
+ public boolean addAll(long[] array, int fromIndex, int length) {
+ return addAll(array, fromIndex, length, size);
+ }
+
+ /**
+ * Add certain elements from the given array at a certain position in this list.
+ * @param array the array from which to take the elements
+ * @param fromIndex the position of the first element to add
+ * @param length how many elements to add
+ * @param position at which position to add these elements, adds at the end if equal to the size
+ * @return whether this list has changed
+ * @throws IndexOutOfBoundsException if fromIndex and length violate the boundaries of the given
+ * array or atIndex is not a valid index in this array or equal to the size
+ */
+ public boolean addAll(long[] array, int fromIndex, int length, int position) {
+ Preconditions.checkNotNull(array);
+ Preconditions.checkPositionIndex(fromIndex + length, array.length);
+ if (length == 0) {
+ return false;
+ }
+ // check other positions later to allow "adding" empty arrays anywhere within this array
+ Preconditions.checkElementIndex(fromIndex, array.length);
+ Preconditions.checkPositionIndex(position, size);
+ copyBackAndGrow(position, length);
+ System.arraycopy(array, fromIndex, this.array, position, length);
+ return true;
+ }
+
+ /**
+ * Resize the backing array to fit at least this many elements if necessary.
+ */
+ public void ensureCapacity(int capacity) {
+ if (capacity > array.length) {
+ long[] newArray = new long[growCapacity(capacity)];
+ System.arraycopy(array, 0, newArray, 0, size);
+ array = newArray;
+ }
+ }
+
+ /**
+ * @return the element at the specified index
+ * @throws IndexOutOfBoundsException if the index is outside the interval [0, {@link #size()})
+ */
+ public long get(int index) {
+ Preconditions.checkElementIndex(index, size);
+ return array[index];
+ }
+
+ /**
+ * Search for the first index at which the given value is found.
+ * @return -1 if the value is not found, the index at which it was found otherwise
+ */
+ public int indexOf(long value) {
+ for (int index = 0; index < size; index++) {
+ if (array[index] == value) {
+ return index;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Remove the element at the specified index and shift all elements at higher indices down by
+ * one.
+ * @return the removed element
+ * @throws IndexOutOfBoundsException if the index is outside the interval [0, {@link #size()})
+ */
+ public long remove(int index) {
+ Preconditions.checkElementIndex(index, size);
+ long previous = array[index];
+ System.arraycopy(array, index + 1, array, index, size - index - 1);
+ size--;
+ return previous;
+ }
+
+ /**
+ * Remove the first occurrence of a value and shift all elements at higher indices down by one.
+ * @return true, if the list changed and thus contained the value, false otherwise
+ */
+ public boolean remove(long value) {
+ int index = indexOf(value);
+ if (index == -1) {
+ return false;
+ }
+ remove(index);
+ return true;
+ }
+
+ /**
+ * Overwrites the element at a certain index with the given value and returns the previous
+ * element.
+ * @throws IndexOutOfBoundsException if the index is outside the interval [0, {@link #size()})
+ */
+ public long set(int index, long value) {
+ Preconditions.checkElementIndex(index, size);
+ long previous = array[index];
+ array[index] = value;
+ return previous;
+ }
+
+ /**
+ * @return the amount of elements in this list
+ */
+ public int size() {
+ return size;
+ }
+
+ /**
+ * Sort the list in ascending order.
+ */
+ public void sort() {
+ Arrays.sort(array, 0, size);
+ }
+
+ /**
+ * Sort the sub list from the first index (inclusive) to the second index (exclusive) in
+ * ascending order.
+ * @see Arrays#sort(long[], int, int)
+ * @throws IndexOutOfBoundsException if fromIndex is outside the interval [0, {@link #size()})
+ * or toIndex is outside [0, {@link #size()}]
+ */
+ public void sort(int fromIndex, int toIndex) {
+ Arrays.sort(array, fromIndex, toIndex);
+ }
+
+ /**
+ * Build a String of the form [0, 1, 2]
+ */
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("[");
+ String separator = "";
+ for (int index = 0; index < size; index++) {
+ sb.append(separator);
+ sb.append(array[index]);
+ separator = ", ";
+ }
+ sb.append("]");
+ return sb.toString();
+ }
+
+ /**
+ * Remove any excess capacity to save space.
+ */
+ public void trim() {
+ if (size < array.length) {
+ long[] newArray = new long[size];
+ System.arraycopy(array, 0, newArray, 0, size);
+ array = newArray;
+ }
+ }
+
+ /**
+ * Copy the end of the array from a certain index back to make room for length many items and
+ * adds length to the size.
+ *
+ * @param fromIndex may be equal to the current size, then no element needs to be copied, but the
+ * array may grow
+ */
+ private void copyBackAndGrow(int fromIndex, int length) {
+ int newSize = size + length;
+ ensureCapacity(newSize);
+ System.arraycopy(array, fromIndex, array, fromIndex + length, size - fromIndex);
+ size = newSize;
+ }
+
+ /**
+ * The new capacity when growing the array to contain at least newSize many elements.
+ * Uses a growth factor of 1.5.
+ */
+ private int growCapacity(int newSize) {
+ return newSize + newSize >> 1;
+ }
+}
+