jdk/src/share/classes/javax/swing/SizeSequence.java
author ohair
Wed, 06 Apr 2011 22:06:11 -0700
changeset 9035 1255eb81cc2f
parent 7959 2e05332a8f5c
child 20157 cafca01a8e28
permissions -rw-r--r--
7033660: Update copyright year to 2011 on any files changed in 2011 Reviewed-by: dholmes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
9035
1255eb81cc2f 7033660: Update copyright year to 2011 on any files changed in 2011
ohair
parents: 7959
diff changeset
     2
 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package javax.swing;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
 * A <code>SizeSequence</code> object
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
 * efficiently maintains an ordered list
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
 * of sizes and corresponding positions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
 * One situation for which <code>SizeSequence</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
 * might be appropriate is in a component
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
 * that displays multiple rows of unequal size.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 * In this case, a single <code>SizeSequence</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 * object could be used to track the heights
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * and Y positions of all rows.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * Another example would be a multi-column component,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * such as a <code>JTable</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * in which the column sizes are not all equal.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * The <code>JTable</code> might use a single
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * <code>SizeSequence</code> object
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * to store the widths and X positions of all the columns.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * The <code>JTable</code> could then use the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * <code>SizeSequence</code> object
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * to find the column corresponding to a certain position.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * The <code>JTable</code> could update the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * <code>SizeSequence</code> object
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * whenever one or more column sizes changed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * The following figure shows the relationship between size and position data
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * for a multi-column component.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 * <center>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 * <img src="doc-files/SizeSequence-1.gif" width=384 height = 100
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 * alt="The first item begins at position 0, the second at the position equal
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 to the size of the previous item, and so on.">
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 * </center>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 * In the figure, the first index (0) corresponds to the first column,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 * the second index (1) to the second column, and so on.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 * The first column's position starts at 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 * and the column occupies <em>size<sub>0</sub></em> pixels,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 * where <em>size<sub>0</sub></em> is the value returned by
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 * <code>getSize(0)</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 * Thus, the first column ends at <em>size<sub>0</sub></em> - 1.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 * The second column then begins at
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 * the position <em>size<sub>0</sub></em>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 * and occupies <em>size<sub>1</sub></em> (<code>getSize(1)</code>) pixels.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
 * Note that a <code>SizeSequence</code> object simply represents intervals
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 * along an axis.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
 * In our examples, the intervals represent height or width in pixels.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
 * However, any other unit of measure (for example, time in days)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
 * could be just as valid.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
 * <h4>Implementation Notes</h4>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
 * Normally when storing the size and position of entries,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
 * one would choose between
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
 * storing the sizes or storing their positions
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
 * instead. The two common operations that are needed during
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
 * rendering are: <code>getIndex(position)</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
 * and <code>setSize(index, size)</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
 * Whichever choice of internal format is made one of these
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
 * operations is costly when the number of entries becomes large.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
 * If sizes are stored, finding the index of the entry
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
 * that encloses a particular position is linear in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
 * number of entries. If positions are stored instead, setting
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
 * the size of an entry at a particular index requires updating
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
 * the positions of the affected entries, which is also a linear
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
 * calculation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
 * Like the above techniques this class holds an array of N integers
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
 * internally but uses a hybrid encoding, which is halfway
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
 * between the size-based and positional-based approaches.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
 * The result is a data structure that takes the same space to store
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
 * the information but can perform most operations in Log(N) time
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
 * instead of O(N), where N is the number of entries in the list.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
 * Two operations that remain O(N) in the number of entries are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
 * the <code>insertEntries</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
 * and <code>removeEntries</code> methods, both
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
 * of which are implemented by converting the internal array to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
 * a set of integer sizes, copying it into the new array, and then
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
 * reforming the hybrid representation in place.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
 * @author Philip Milne
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
 * @since 1.3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
 *   Each method is implemented by taking the minimum and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
 *   maximum of the range of integers that need to be operated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
 *   upon. All the algorithms work by dividing this range
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
 *   into two smaller ranges and recursing. The recursion
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
 *   is terminated when the upper and lower bounds are equal.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
public class SizeSequence {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    private static int[] emptyArray = new int[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    private int a[];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
     * Creates a new <code>SizeSequence</code> object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
     * that contains no entries.  To add entries, you
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
     * can use <code>insertEntries</code> or <code>setSizes</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
     * @see #insertEntries
7959
2e05332a8f5c 6589952: Swing: dead links in API documentation
rupashka
parents: 5506
diff changeset
   135
     * @see #setSizes(int[])
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    public SizeSequence() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
        a = emptyArray;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
     * Creates a new <code>SizeSequence</code> object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     * that contains the specified number of entries,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
     * all initialized to have size 0.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
     * @param numEntries  the number of sizes to track
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
     * @exception NegativeArraySizeException if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
     *    <code>numEntries < 0</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
    public SizeSequence(int numEntries) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
        this(numEntries, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
     * Creates a new <code>SizeSequence</code> object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
     * that contains the specified number of entries,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
     * all initialized to have size <code>value</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
     * @param numEntries  the number of sizes to track
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
     * @param value       the initial value of each size
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
    public SizeSequence(int numEntries, int value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
        this();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
        insertEntries(0, numEntries, value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
     * Creates a new <code>SizeSequence</code> object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
     * that contains the specified sizes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
     * @param sizes  the array of sizes to be contained in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
     *               the <code>SizeSequence</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
    public SizeSequence(int[] sizes) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        this();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        setSizes(sizes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
     * Resets the size sequence to contain <code>length</code> items
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
     * all with a size of <code>size</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
    void setSizes(int length, int size) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        if (a.length != length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
            a = new int[length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
        setSizes(0, length, size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
    private int setSizes(int from, int to, int size) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
        if (to <= from) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
            return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
        int m = (from + to)/2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
        a[m] = size + setSizes(from, m, size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        return a[m] + setSizes(m + 1, to, size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
     * Resets this <code>SizeSequence</code> object,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
     * using the data in the <code>sizes</code> argument.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
     * This method reinitializes this object so that it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
     * contains as many entries as the <code>sizes</code> array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
     * Each entry's size is initialized to the value of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
     * corresponding item in <code>sizes</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
     * @param sizes  the array of sizes to be contained in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
     *               this <code>SizeSequence</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
    public void setSizes(int[] sizes) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
        if (a.length != sizes.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
            a = new int[sizes.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
        setSizes(0, a.length, sizes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
    private int setSizes(int from, int to, int[] sizes) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
        if (to <= from) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
            return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
        int m = (from + to)/2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
        a[m] = sizes[m] + setSizes(from, m, sizes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
        return a[m] + setSizes(m + 1, to, sizes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
     * Returns the size of all entries.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
     * @return  a new array containing the sizes in this object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
    public int[] getSizes() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
        int n = a.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
        int[] sizes = new int[n];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        getSizes(0, n, sizes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
        return sizes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
    private int getSizes(int from, int to, int[] sizes) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
        if (to <= from) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
            return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
        int m = (from + to)/2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        sizes[m] = a[m] - getSizes(from, m, sizes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
        return a[m] + getSizes(m + 1, to, sizes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
     * Returns the start position for the specified entry.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
     * For example, <code>getPosition(0)</code> returns 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
     * <code>getPosition(1)</code> is equal to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
     *   <code>getSize(0)</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
     * <code>getPosition(2)</code> is equal to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
     *   <code>getSize(0)</code> + <code>getSize(1)</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
     * and so on.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
     * <p>Note that if <code>index</code> is greater than
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
     * <code>length</code> the value returned may
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
     * be meaningless.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
     * @param index  the index of the entry whose position is desired
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
     * @return       the starting position of the specified entry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
    public int getPosition(int index) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
        return getPosition(0, a.length, index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
    private int getPosition(int from, int to, int index) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
        if (to <= from) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
            return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
        int m = (from + to)/2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
        if (index <= m) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
            return getPosition(from, m, index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
            return a[m] + getPosition(m + 1, to, index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
     * Returns the index of the entry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
     * that corresponds to the specified position.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
     * For example, <code>getIndex(0)</code> is 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
     * since the first entry always starts at position 0.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
     * @param position  the position of the entry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
     * @return  the index of the entry that occupies the specified position
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
    public int getIndex(int position) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
        return getIndex(0, a.length, position);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
    private int getIndex(int from, int to, int position) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
        if (to <= from) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
            return from;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
        int m = (from + to)/2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        int pivot = a[m];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
        if (position < pivot) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
           return getIndex(from, m, position);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
            return getIndex(m + 1, to, position - pivot);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
     * Returns the size of the specified entry.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
     * If <code>index</code> is out of the range
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
     * <code>(0 <= index < getSizes().length)</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
     * the behavior is unspecified.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
     * @param index  the index corresponding to the entry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
     * @return  the size of the entry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
    public int getSize(int index) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
        return getPosition(index + 1) - getPosition(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
     * Sets the size of the specified entry.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
     * Note that if the value of <code>index</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
     * does not fall in the range:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
     * <code>(0 <= index < getSizes().length)</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
     * the behavior is unspecified.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
     * @param index  the index corresponding to the entry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
     * @param size   the size of the entry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
    public void setSize(int index, int size) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
        changeSize(0, a.length, index, size - getSize(index));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
    private void changeSize(int from, int to, int index, int delta) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
        if (to <= from) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
        int m = (from + to)/2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
        if (index <= m) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
            a[m] += delta;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
            changeSize(from, m, index, delta);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
            changeSize(m + 1, to, index, delta);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
     * Adds a contiguous group of entries to this <code>SizeSequence</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
     * Note that the values of <code>start</code> and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
     * <code>length</code> must satisfy the following
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
     * conditions:  <code>(0 <= start < getSizes().length)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
     * AND (length >= 0)</code>.  If these conditions are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
     * not met, the behavior is unspecified and an exception
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
     * may be thrown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
     * @param start   the index to be assigned to the first entry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
     *                in the group
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
     * @param length  the number of entries in the group
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
     * @param value   the size to be assigned to each new entry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
     * @exception ArrayIndexOutOfBoundsException if the parameters
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
     *   are outside of the range:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
     *   (<code>0 <= start < (getSizes().length)) AND (length >= 0)</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
    public void insertEntries(int start, int length, int value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
        int sizes[] = getSizes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
        int end = start + length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
        int n = a.length + length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
        a = new int[n];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
        for (int i = 0; i < start; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
            a[i] = sizes[i] ;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
        for (int i = start; i < end; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
            a[i] = value ;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
        for (int i = end; i < n; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
            a[i] = sizes[i-length] ;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
        setSizes(a);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
     * Removes a contiguous group of entries
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
     * from this <code>SizeSequence</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
     * Note that the values of <code>start</code> and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
     * <code>length</code> must satisfy the following
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
     * conditions:  <code>(0 <= start < getSizes().length)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
     * AND (length >= 0)</code>.  If these conditions are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
     * not met, the behavior is unspecified and an exception
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
     * may be thrown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
     * @param start   the index of the first entry to be removed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
     * @param length  the number of entries to be removed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
    public void removeEntries(int start, int length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
        int sizes[] = getSizes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
        int end = start + length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
        int n = a.length - length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
        a = new int[n];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
        for (int i = 0; i < start; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
            a[i] = sizes[i] ;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
        for (int i = start; i < n; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
            a[i] = sizes[i+length] ;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
        setSizes(a);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
}