• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GENERATED SOURCE. DO NOT MODIFY. */
2 // © 2016 and later: Unicode, Inc. and others.
3 // License & terms of use: http://www.unicode.org/copyright.html#License
4 /*
5  *******************************************************************************
6  * Copyright (C) 1996-2014, International Business Machines Corporation and    *
7  * others. All Rights Reserved.                                                *
8  *******************************************************************************
9  */
10 package ohos.global.icu.util;
11 import ohos.global.icu.impl.Utility;
12 
13 /**
14  * class CompactATypeArray : use only on primitive data types
15  * Provides a compact way to store information that is indexed by Unicode
16  * values, such as character properties, types, keyboard values, etc.This
17  * is very useful when you have a block of Unicode data that contains
18  * significant values while the rest of the Unicode data is unused in the
19  * application or when you have a lot of redundance, such as where all 21,000
20  * Han ideographs have the same value.  However, lookup is much faster than a
21  * hash table.
22  * A compact array of any primitive data type serves two purposes:
23  * <UL type = round>
24  *     <LI>Fast access of the indexed values.
25  *     <LI>Smaller memory footprint.
26  * </UL>
27  * A compact array is composed of a index array and value array.  The index
28  * array contains the indicies of Unicode characters to the value array.
29  *
30  * @see                CompactCharArray
31  * @author             Helena Shih
32  * @deprecated This API is ICU internal only.
33  * @hide exposed on OHOS
34  * @hide draft / provisional / internal are hidden on OHOS
35  */
36 @Deprecated
37 public final class CompactByteArray implements Cloneable {
38 
39     /**
40      * The total number of Unicode characters.
41      * @deprecated This API is ICU internal only.
42      * @hide draft / provisional / internal are hidden on OHOS
43      */
44     @Deprecated
45     public static  final int UNICODECOUNT =65536;
46 
47     /**
48      * Default constructor for CompactByteArray, the default value of the
49      * compact array is 0.
50      * @deprecated This API is ICU internal only.
51      * @hide draft / provisional / internal are hidden on OHOS
52      */
53     @Deprecated
CompactByteArray()54     public CompactByteArray()
55     {
56         this((byte)0);
57     }
58 
59     /**
60      * Constructor for CompactByteArray.
61      * @param defaultValue the default value of the compact array.
62      * @deprecated This API is ICU internal only.
63      * @hide draft / provisional / internal are hidden on OHOS
64      */
65     @Deprecated
CompactByteArray(byte defaultValue)66     public CompactByteArray(byte defaultValue)
67     {
68         int i;
69         values = new byte[UNICODECOUNT];
70         indices = new char[INDEXCOUNT];
71         hashes = new int[INDEXCOUNT];
72         for (i = 0; i < UNICODECOUNT; ++i) {
73             values[i] = defaultValue;
74         }
75         for (i = 0; i < INDEXCOUNT; ++i) {
76             indices[i] = (char)(i<<BLOCKSHIFT);
77             hashes[i] = 0;
78         }
79         isCompact = false;
80 
81         this.defaultValue = defaultValue;
82     }
83 
84     /**
85      * Constructor for CompactByteArray.
86      * @param indexArray the indicies of the compact array.
87      * @param newValues the values of the compact array.
88      * @exception IllegalArgumentException If the index is out of range.
89      * @deprecated This API is ICU internal only.
90      * @hide draft / provisional / internal are hidden on OHOS
91      */
92     @Deprecated
CompactByteArray(char indexArray[], byte newValues[])93     public CompactByteArray(char indexArray[],
94                             byte newValues[])
95     {
96         int i;
97         if (indexArray.length != INDEXCOUNT)
98             throw new IllegalArgumentException("Index out of bounds.");
99         for (i = 0; i < INDEXCOUNT; ++i) {
100             char index = indexArray[i];
101             if (index >= newValues.length+BLOCKCOUNT)
102                 throw new IllegalArgumentException("Index out of bounds.");
103         }
104         indices = indexArray;
105         values = newValues;
106         isCompact = true;
107     }
108 
109     /**
110      * Constructor for CompactByteArray.
111      *
112      * @param indexArray the RLE-encoded indicies of the compact array.
113      * @param valueArray the RLE-encoded values of the compact array.
114      *
115      * @throws IllegalArgumentException if the index or value array is
116      *          the wrong size.
117      * @deprecated This API is ICU internal only.
118      * @hide draft / provisional / internal are hidden on OHOS
119      */
120     @Deprecated
CompactByteArray(String indexArray, String valueArray)121     public CompactByteArray(String indexArray,
122                             String valueArray)
123     {
124         this( Utility.RLEStringToCharArray(indexArray),
125               Utility.RLEStringToByteArray(valueArray));
126     }
127 
128     /**
129      * Get the mapped value of a Unicode character.
130      * @param index the character to get the mapped value with
131      * @return the mapped value of the given character
132      * @deprecated This API is ICU internal only.
133      * @hide draft / provisional / internal are hidden on OHOS
134      */
135     @Deprecated
elementAt(char index)136     public byte elementAt(char index)
137     {
138         return (values[(indices[index >> BLOCKSHIFT] & 0xFFFF)
139                        + (index & BLOCKMASK)]);
140     }
141 
142     /**
143      * Set a new value for a Unicode character.
144      * Set automatically expands the array if it is compacted.
145      * @param index the character to set the mapped value with
146      * @param value the new mapped value
147      * @deprecated This API is ICU internal only.
148      * @hide draft / provisional / internal are hidden on OHOS
149      */
150     @Deprecated
setElementAt(char index, byte value)151     public void setElementAt(char index, byte value)
152     {
153         if (isCompact)
154             expand();
155         values[index] = value;
156         touchBlock(index >> BLOCKSHIFT, value);
157     }
158 
159     /**
160      * Set new values for a range of Unicode character.
161      *
162      * @param start the starting offset of the range
163      * @param end the ending offset of the range
164      * @param value the new mapped value
165      * @deprecated This API is ICU internal only.
166      * @hide draft / provisional / internal are hidden on OHOS
167      */
168     @Deprecated
setElementAt(char start, char end, byte value)169     public void setElementAt(char start, char end, byte value)
170     {
171         int i;
172         if (isCompact) {
173             expand();
174         }
175         for (i = start; i <= end; ++i) {
176             values[i] = value;
177             touchBlock(i >> BLOCKSHIFT, value);
178         }
179     }
180     /**
181      * Compact the array.
182      * @deprecated This API is ICU internal only.
183      * @hide draft / provisional / internal are hidden on OHOS
184      */
185     @Deprecated
compact()186     public void compact() {
187         compact(false);
188     }
189 
190     /**
191      * Compact the array.
192      * @deprecated This API is ICU internal only.
193      * @hide draft / provisional / internal are hidden on OHOS
194      */
195     @Deprecated
compact(boolean exhaustive)196     public void compact(boolean exhaustive)
197     {
198         if (!isCompact) {
199             int limitCompacted = 0;
200             int iBlockStart = 0;
201             char iUntouched = 0xFFFF;
202 
203             for (int i = 0; i < indices.length; ++i, iBlockStart += BLOCKCOUNT) {
204                 indices[i] = 0xFFFF;
205                 boolean touched = blockTouched(i);
206                 if (!touched && iUntouched != 0xFFFF) {
207                     // If no values in this block were set, we can just set its
208                     // index to be the same as some other block with no values
209                     // set, assuming we've seen one yet.
210                     indices[i] = iUntouched;
211                 } else {
212                     int jBlockStart = 0;
213                     int j = 0;
214                     for (j = 0; j < limitCompacted;
215                             ++j, jBlockStart += BLOCKCOUNT) {
216                         if (hashes[i] == hashes[j] &&
217                                 arrayRegionMatches(values, iBlockStart,
218                                 values, jBlockStart, BLOCKCOUNT)) {
219                             indices[i] = (char)jBlockStart;
220                             break;
221                         }
222                     }
223                     if (indices[i] == 0xFFFF) {
224                         // we didn't match, so copy & update
225                         System.arraycopy(values, iBlockStart,
226                             values, jBlockStart, BLOCKCOUNT);
227                         indices[i] = (char)jBlockStart;
228                         hashes[j] = hashes[i];
229                         ++limitCompacted;
230 
231                         if (!touched) {
232                             // If this is the first untouched block we've seen,
233                             // remember its index.
234                             iUntouched = (char)jBlockStart;
235                         }
236                     }
237                 }
238             }
239             // we are done compacting, so now make the array shorter
240             int newSize = limitCompacted*BLOCKCOUNT;
241             byte[] result = new byte[newSize];
242             System.arraycopy(values, 0, result, 0, newSize);
243             values = result;
244             isCompact = true;
245             hashes = null;
246         }
247     }
248 
249     /**
250      * Convenience utility to compare two arrays of doubles.
251      * @param len the length to compare.
252      * The start indices and start+len must be valid.
253      */
arrayRegionMatches(byte[] source, int sourceStart, byte[] target, int targetStart, int len)254     final static boolean arrayRegionMatches(byte[] source, int sourceStart,
255                                             byte[] target, int targetStart,
256                                             int len)
257     {
258         int sourceEnd = sourceStart + len;
259         int delta = targetStart - sourceStart;
260         for (int i = sourceStart; i < sourceEnd; i++) {
261             if (source[i] != target[i + delta])
262             return false;
263         }
264         return true;
265     }
266 
267     /**
268      * Remember that a specified block was "touched", i.e. had a value set.
269      * Untouched blocks can be skipped when compacting the array
270      */
touchBlock(int i, int value)271     private final void touchBlock(int i, int value) {
272         hashes[i] = (hashes[i] + (value<<1)) | 1;
273     }
274 
275     /**
276      * Query whether a specified block was "touched", i.e. had a value set.
277      * Untouched blocks can be skipped when compacting the array
278      */
blockTouched(int i)279     private final boolean blockTouched(int i) {
280         return hashes[i] != 0;
281     }
282 
283     /**
284      * For internal use only.  Do not modify the result, the behavior of
285      * modified results are undefined.
286      * @deprecated This API is ICU internal only.
287      * @hide draft / provisional / internal are hidden on OHOS
288      */
289     @Deprecated
getIndexArray()290     public char[] getIndexArray()
291     {
292         return indices;
293     }
294 
295     /**
296      * For internal use only.  Do not modify the result, the behavior of
297      * modified results are undefined.
298      * @deprecated This API is ICU internal only.
299      * @hide draft / provisional / internal are hidden on OHOS
300      */
301     @Deprecated
getValueArray()302     public byte[] getValueArray()
303     {
304         return values;
305     }
306 
307     /**
308      * Overrides Cloneable
309      * @deprecated This API is ICU internal only.
310      * @hide draft / provisional / internal are hidden on OHOS
311      */
312     @Override
313     @Deprecated
clone()314     public Object clone()
315     {
316         try {
317             CompactByteArray other = (CompactByteArray) super.clone();
318             other.values = values.clone();
319             other.indices = indices.clone();
320             if (hashes != null) other.hashes = hashes.clone();
321             return other;
322         } catch (CloneNotSupportedException e) {
323             throw new ICUCloneNotSupportedException(e);
324         }
325     }
326 
327     /**
328      * Compares the equality of two compact array objects.
329      * @param obj the compact array object to be compared with this.
330      * @return true if the current compact array object is the same
331      * as the compact array object obj; false otherwise.
332      * @deprecated This API is ICU internal only.
333      * @hide draft / provisional / internal are hidden on OHOS
334      */
335     @Override
336     @Deprecated
equals(Object obj)337     public boolean equals(Object obj) {
338         if (obj == null) return false;
339         if (this == obj)                      // quick check
340             return true;
341         if (getClass() != obj.getClass())         // same class?
342             return false;
343         CompactByteArray other = (CompactByteArray) obj;
344         for (int i = 0; i < UNICODECOUNT; i++) {
345             // could be sped up later
346             if (elementAt((char)i) != other.elementAt((char)i))
347                 return false;
348         }
349         return true; // we made it through the guantlet.
350     }
351 
352     /**
353      * Generates the hash code for the compact array object
354      * @deprecated This API is ICU internal only.
355      * @hide draft / provisional / internal are hidden on OHOS
356      */
357     @Override
358     @Deprecated
hashCode()359     public int hashCode() {
360         int result = 0;
361         int increment = Math.min(3, values.length/16);
362         for (int i = 0; i < values.length; i+= increment) {
363             result = result * 37 + values[i];
364         }
365         return result;
366     }
367 
368     // --------------------------------------------------------------
369     // private
370     // --------------------------------------------------------------
371 
372     /**
373      * Expanding takes the array back to a 65536 element array.
374      */
expand()375     private void expand()
376     {
377         int i;
378         if (isCompact) {
379             byte[]  tempArray;
380             hashes = new int[INDEXCOUNT];
381             tempArray = new byte[UNICODECOUNT];
382             for (i = 0; i < UNICODECOUNT; ++i) {
383                 byte value = elementAt((char)i);
384                 tempArray[i] = value;
385                 touchBlock(i >> BLOCKSHIFT, value);
386             }
387             for (i = 0; i < INDEXCOUNT; ++i) {
388                 indices[i] = (char)(i<<BLOCKSHIFT);
389             }
390             values = null;
391             values = tempArray;
392             isCompact = false;
393         }
394     }
395 
396     private static  final int BLOCKSHIFT =7;
397     private static  final int BLOCKCOUNT =(1<<BLOCKSHIFT);
398     private static  final int INDEXSHIFT =(16-BLOCKSHIFT);
399     private static  final int INDEXCOUNT =(1<<INDEXSHIFT);
400     private static  final int BLOCKMASK = BLOCKCOUNT - 1;
401 
402     private byte[] values;
403     private char indices[];
404     private int[] hashes;
405     private boolean isCompact;
406     byte defaultValue;
407 }
408