/*
* Copyright (C) 2012 Facebook, 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 com.facebook.collections;
/**
* The idea here is to provide a uniform interface for arrays so that we may
* implement data structures on top of them seeming to use "Objects", with auto[un]boxing,
* but the backing storage may be primitive arrays in order to save memory
* (ex: hash tables implemented in terms of arrays)
*
* While this interface doesn't 100% enforce that implementations will be a class array,
* the implementation should have array-like properties in terms of memory usage and time
* of operations: get/setshould be O(1). resize should be O(n). append() should be O(1)
* amortized with set() calls in that it's basically an iterator walking towards the end, and will
* insert values in the first empty slot. A slot at it's ptr is not empty only if set was called,
* so you can see the # of total set/append calls to fill a list is O(N), 2N in the pathological
* case (call set on all values and leave the last empty; append will take O(N) time and then
* the array is full
*
* @param <T> type of the array. T = Long may in fact mean the backing storage
* could be long[] which saves 24 bytes per entry (the pointer + 2w overhead)
*
* Each implementation defines if it's thread safe or not
*/
public interface Array<T> extends Iterable<T>{
/**
* gets element at position i. For the love of all that is good and
* holy, please make this O(1) in all your implementations
*
* @param i position
* @return value at position i, null if empty
* @throws ArrayIndexOutOfBoundsException if array is too small, or i is negative
*/
public T get(int i) throws IndexOutOfBoundsException;
/**
* return size of array (# of elements)
*
* @return
*/
public int size();
/**
* return array capacity (size + empty slots)
* same as array.length in the case of built-in arrays
*
* @return
*/
public int capacity();
/**
* replace a value. i must be < capacity()
*
* @param i location
* @param value value to place, may NOT be null
* @return previous value, null if nada
* @throws IndexOutOfBoundsException i is >= size or i is negative
*/
public T set(int i, T value) throws IndexOutOfBoundsException;
/**
* add an element to the end of the array. Almost always shorthand for:
*
* <pre>simpleArray.set(simpleArray.size(), value) </pre>
* (with an exception, see below)
*
* this is useful when you want to use the array like queue or stack, and in practice some
* one-off impls of classes like this did "append" only.
*
* with the difference that if size() == capacity(), the array it is automatically grown
* to accommodate the new value
*
* In the case if a value has been set past the "end" of contiguous values, this will continue
* and skip over set values and set the first empty value
*
* @param value to add, may NOT be null
* @return position inserted at
*/
public int append(T value);
/**
* remove a value at position i
*
* @param i position between 0 and size-
* @return value at the position, null if it was empty
* @throws ArrayIndexOutOfBoundsException i is >= size or i is negative
*/
public T remove(int i) throws ArrayIndexOutOfBoundsException;
/**
* the idea here is that want to grow the array, and give a 'hint'. Note,
* underlying implementations may not be able to create an array of the exact size
* For example, asking for 2 * size() might result in a slightly different size.
*
* For shrinking: one should copy to a smaller array. Because shrinking would have unknown
* effects on the indices of values known to the caller, there is not much value in having
* the ability to shrink internalized
*
* @param sizeHint can be thought of as a new size to grow to, but implementations
* may not grow to exactly that size. The actual size is returned. Should be
* > 0
* @return actual size of new array
*/
public int resize(int sizeHint);
}