/** * Copyright 2008 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 org.waveprotocol.wave.model.util; /** * A list which indexes objects by offsets. The objects being indexed are stored * in containers in this list. Each container has a size, and the offset of each * container is the sum of the sizes of all containers before it. * * * @param <T> The type of data contained in the data structure. */ public interface OffsetList<T> extends Iterable<T> { /** * A container for holding data. * * @param <T> The type of data contained in the container. */ public interface Container<T> { /** * Gets the container preceding this container. * * @return The container preceding this container. */ Container<T> getPreviousContainer(); /** * Gets the container following this container. * * @return The container following this container. */ Container<T> getNextContainer(); /** * Gets the value contained in this container. * * @return The value contained in this container. */ T getValue(); /** * Sets the value contained in this container. * * @param value The value to be contained in this container. */ void setValue(T value); /** * Returns the offset of this container in the <code>OffsetList</code> to * which it belongs. * * @return The offset of this container in the <code>OffsetList</code> to * which it belongs. */ int offset(); /** * Gets the size of this container. * * @return The size of this container. */ int size(); /** * Inserts a new container with the given value and size before this * container. * * @param newValue The new value to insert. * @param valueSize The size of the new container to insert. * @return The new container. */ Container<T> insertBefore(T newValue, int valueSize); /** * Removes this container from its <code>OffsetList</code>. * * The container will no longer be usable (i.e. all references from this * container to other containers will be null). */ void remove(); /** * Splits this container. The sum of the sizes of the two resulting * containers will be the same as the size of the container being split. * This container will become the first of the two resulting containers, and * the second of the two resulting containers will be returned. * * @param offset The offset at which to perform the split. The size of this * container will be set to the value of this offset, and the size of * the new container will be the difference between the old size of * this container and the value of this offset. * @param newValue The value that is to be contained in the new container, * which will be the second of the two containers in the result of * the split. * @return The new container. */ Container<T> split(int offset, T newValue); /** * Increases the size of this container by the given amount. * * @param sizeDelta The amount by which to increase this container's size. * This may be negative. */ void increaseSize(int sizeDelta); } /** * An action that can be performed at a location in an * <code>OffsetList</code>. * * @param <T> The type of the values stored in this <code>OffsetList</code>. * @param <R> The type of the return value from performing this action. */ public interface LocationAction<T, R> { /** * Performs an action on a given location. * * @param container The container that contains the location. * @param offset The offset of the location within the container. * @return The return value of this action. */ R performAction(Container<T> container, int offset); } /** * Gets the first container in this offset list. * * @return The first container in this offset list. */ Container<T> firstContainer(); /** * Gets the sentinel container of this offset list. The sentinel is not * considered to be part of the offset list's data and its contents will not * be returned by any iterators over this offset list. The sentinel is capable * of containing a value, however, if a sentinel value is ever useful. Calling * <code>getPreviousContainer()</code> on the first container in this offset * list or <code>getNextContainer()</code> on the last container in this * offset list will return the sentinel container. The offset of the sentinel * container is the offset directly following the last container in this * offset list. * * @return The sentinel container. */ Container<T> sentinel(); /** * @return The total size of the list (i.e., the sum of the sizes of all its * non-sentinel containers). */ int size(); /** * Performs an action at a given offset. * * @param <R> The return type of the action. * @param offset The offset at which to perform the action. * @param locationAction The action to perform. * @return The value returned from performing the action. */ <R> R performActionAt(int offset, LocationAction<T, R> locationAction); }