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