src/java.base/share/classes/sun/text/UCompactIntArray.java
author godin
Tue, 20 Aug 2019 15:54:46 +0200
changeset 57814 699b8ef42f30
parent 47216 71c04702a3d5
permissions -rw-r--r--
8152467: remove uses of anachronistic array declarations for method return type Reviewed-by: shade, alanb Contributed-by: Evgeny Mandrikov <mandrikov@gmail.com>
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     2
 * Copyright (c) 2003, 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 sun.text;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
public final class UCompactIntArray implements Cloneable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
     * Default constructor for UCompactIntArray, the default value of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
     * compact array is 0.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
    public UCompactIntArray() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
        values = new int[16][];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
        indices = new short[16][];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
        blockTouched = new boolean[16][];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
        planeTouched = new boolean[16];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
    public UCompactIntArray(int defaultValue) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
        this();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
        this.defaultValue = defaultValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
     * Get the mapped value of a Unicode character.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
     * @param index the character to get the mapped value with
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
     * @return the mapped value of the given character
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
    public int elementAt(int index) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
        int plane = (index & PLANEMASK) >> PLANESHIFT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
        if (!planeTouched[plane]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
            return defaultValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
        index &= CODEPOINTMASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
        return values[plane][(indices[plane][index >> BLOCKSHIFT] & 0xFFFF)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
                       + (index & BLOCKMASK)];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
     * Set a new value for a Unicode character.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
     * Set automatically expands the array if it is compacted.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
     * @param index the character to set the mapped value with
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
     * @param value the new mapped value
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
    public void setElementAt(int index, int value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
        if (isCompact) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
            expand();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
        int plane = (index & PLANEMASK) >> PLANESHIFT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
        if (!planeTouched[plane]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
            initPlane(plane);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
        index &= CODEPOINTMASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
        values[plane][index] = value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
        blockTouched[plane][index >> BLOCKSHIFT] = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
     * Compact the array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    public void compact() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
        if (isCompact) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
        for (int plane = 0; plane < PLANECOUNT; plane++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
            if (!planeTouched[plane]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
            int limitCompacted = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
            int iBlockStart = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
            short iUntouched = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
            for (int i = 0; i < indices[plane].length; ++i, iBlockStart += BLOCKCOUNT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
                indices[plane][i] = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
                if (!blockTouched[plane][i] && iUntouched != -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
                    // If no values in this block were set, we can just set its
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
                    // index to be the same as some other block with no values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
                    // set, assuming we've seen one yet.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
                    indices[plane][i] = iUntouched;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
                    int jBlockStart = limitCompacted * BLOCKCOUNT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
                    if (i > limitCompacted) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
                        System.arraycopy(values[plane], iBlockStart,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
                                         values[plane], jBlockStart, BLOCKCOUNT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
                    if (!blockTouched[plane][i]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
                        // If this is the first untouched block we've seen, remember it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
                        iUntouched = (short)jBlockStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
                    indices[plane][i] = (short)jBlockStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
                    limitCompacted++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
            // we are done compacting, so now make the array shorter
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
            int newSize = limitCompacted * BLOCKCOUNT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
            int[] result = new int[newSize];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
            System.arraycopy(values[plane], 0, result, 0, newSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
            values[plane] = result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
            blockTouched[plane] = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
        isCompact = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    // --------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
    // private
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    // --------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
     * Expanded takes the array back to a 0x10ffff element array
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
    private void expand() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
        int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
        if (isCompact) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
            int[]   tempArray;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
            for (int plane = 0; plane < PLANECOUNT; plane++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
                if (!planeTouched[plane]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
                    continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
                blockTouched[plane] = new boolean[INDEXCOUNT];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
                tempArray = new int[UNICODECOUNT];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
                for (i = 0; i < UNICODECOUNT; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
                    tempArray[i] = values[plane][indices[plane][i >> BLOCKSHIFT]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
                                                & 0xffff + (i & BLOCKMASK)];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
                    blockTouched[plane][i >> BLOCKSHIFT] = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
                for (i = 0; i < INDEXCOUNT; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
                    indices[plane][i] = (short)(i<<BLOCKSHIFT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
                values[plane] = tempArray;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
            isCompact = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    private void initPlane(int plane) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
        values[plane] = new int[UNICODECOUNT];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        indices[plane] = new short[INDEXCOUNT];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        blockTouched[plane] = new boolean[INDEXCOUNT];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
        planeTouched[plane] = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
        if (planeTouched[0] && plane != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
            System.arraycopy(indices[0], 0, indices[plane], 0, INDEXCOUNT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
            for (int i = 0; i < INDEXCOUNT; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
                indices[plane][i] = (short)(i<<BLOCKSHIFT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
        for (int i = 0; i < UNICODECOUNT; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
            values[plane][i] = defaultValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
    public int getKSize() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
        int size = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
        for (int plane = 0; plane < PLANECOUNT; plane++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
            if (planeTouched[plane]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
                size += (values[plane].length * 4 + indices[plane].length * 2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        return size / 1024;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
    private static final int PLANEMASK = 0x30000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
    private static final int PLANESHIFT = 16;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
    private static final int PLANECOUNT = 0x10;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
    private static final int CODEPOINTMASK  = 0xffff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
    private static final int UNICODECOUNT = 0x10000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
    private static final int BLOCKSHIFT = 7;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
    private static final int BLOCKCOUNT = (1<<BLOCKSHIFT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
    private static final int INDEXSHIFT = (16-BLOCKSHIFT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
    private static final int INDEXCOUNT = (1<<INDEXSHIFT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
    private static final int BLOCKMASK = BLOCKCOUNT - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    private int defaultValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
    private int values[][];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    private short indices[][];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
    private boolean isCompact;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
    private boolean[][] blockTouched;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
    private boolean[] planeTouched;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
};