12ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/* GENERATED SOURCE. DO NOT MODIFY. */ 2f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert// © 2016 and later: Unicode, Inc. and others. 3f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html#License 42ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/* 52ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ****************************************************************************** 62ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Copyright (C) 1996-2011, International Business Machines Corporation and * 72ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * others. All Rights Reserved. * 82ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ****************************************************************************** 92ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/** 122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Store bits (Unicode character properties) in bit set vectors. 13f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * 142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This is a port of the C++ class UPropsVectors from ICU4C 15f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * 162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @author Shaopeng Jia 17836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller * @hide draft / provisional / internal are hidden on Android 182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpackage android.icu.impl; 212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Arrays; 232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Comparator; 242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/** 262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Unicode Properties Vectors associated with code point ranges. 27f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * 282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Rows of primitive integers in a contiguous array store the range limits and 292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the properties vectors. 30f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * 312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * In each row, row[0] contains the start code point and row[1] contains the 322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * limit code point, which is the start of the next range. 33f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * 342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Initially, there is only one range [0..0x110000] with values 0. 35f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * 362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * It would be possible to store only one range boundary per row, but 372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * self-contained rows allow to later sort them by contents. 38836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller * @hide Only a subset of ICU is exposed in Android 392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpublic class PropsVectors { 412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private int v[]; 422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private int columns; // number of columns, plus two for start 432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // and limit values 442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private int maxRows; 452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private int rows; 462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private int prevRow; // search optimization: remember last row seen 472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private boolean isCompacted; 482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // internal function to compare elements in v and target. Return true iff 50f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert // elements in v starting from index1 to index1 + length - 1 512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // are exactly the same as elements in target 522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // starting from index2 to index2 + length - 1 53f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert private boolean areElementsSame(int index1, int[] target, int index2, 542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int length) { 552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0; i < length; ++i) { 562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (v[index1 + i] != target[index2 + i]) { 572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return false; 582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return true; 612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 62f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert 632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // internal function which given rangeStart, returns 642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // index where v[index]<=rangeStart<v[index+1]. 652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // The returned index is a multiple of columns, and therefore 662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // points to the start of a row. 672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private int findRow(int rangeStart) { 682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int index = 0; 692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // check the vicinity of the last-seen row (start 712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // searching with an unrolled loop) 722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller index = prevRow * columns; 742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (rangeStart >= v[index]) { 752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (rangeStart < v[index + 1]) { 762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // same row as last seen 772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return index; 782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller index += columns; 802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (rangeStart < v[index + 1]) { 812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++prevRow; 822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return index; 832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller index += columns; 852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (rangeStart < v[index + 1]) { 862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller prevRow += 2; 872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return index; 882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if ((rangeStart - v[index + 1]) < 10) { 892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // we are close, continue looping 902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller prevRow += 2; 912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller do { 922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++prevRow; 932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller index += columns; 942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } while (rangeStart >= v[index + 1]); 952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return index; 962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (rangeStart < v[1]) { 1002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // the very first row 1012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller prevRow = 0; 1022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return 0; 1032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // do a binary search for the start of the range 1062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int start = 0; 1072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int mid = 0; 1082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int limit = rows; 1092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (start < limit - 1) { 1102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller mid = (start + limit) / 2; 1112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller index = columns * mid; 1122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (rangeStart < v[index]) { 1132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller limit = mid; 1142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (rangeStart < v[index + 1]) { 1152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller prevRow = mid; 1162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return index; 1172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 1182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller start = mid; 1192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // must be found because all ranges together always cover 1232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // all of Unicode 1242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller prevRow = start; 1252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller index = start * columns; 1262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return index; 1272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 1302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Special pseudo code points for storing the initialValue and the 1312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * errorValue which are used to initialize a Trie or similar. 1322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public final static int FIRST_SPECIAL_CP = 0x110000; 1342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public final static int INITIAL_VALUE_CP = 0x110000; 1352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public final static int ERROR_VALUE_CP = 0x110001; 1362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public final static int MAX_CP = 0x110001; 1372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public final static int INITIAL_ROWS = 1 << 12; 1392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public final static int MEDIUM_ROWS = 1 << 16; 1402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public final static int MAX_ROWS = MAX_CP + 1; 1412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 1432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Constructor. 1442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param numOfColumns Number of value integers (32-bit int) per row. 1452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public PropsVectors(int numOfColumns) { 1472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (numOfColumns < 1) { 1482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalArgumentException("numOfColumns need to be no " 1492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller + "less than 1; but it is " + numOfColumns); 1502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller columns = numOfColumns + 2; // count range start and limit columns 1522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller v = new int[INITIAL_ROWS * columns]; 1532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller maxRows = INITIAL_ROWS; 1542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller rows = 2 + (MAX_CP - FIRST_SPECIAL_CP); 1552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller prevRow = 0; 1562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller isCompacted = false; 1572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller v[0] = 0; 1582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller v[1] = 0x110000; 1592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int index = columns; 1602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int cp = FIRST_SPECIAL_CP; cp <= MAX_CP; ++cp) { 1612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller v[index] = cp; 1622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller v[index + 1] = cp + 1; 1632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller index += columns; 1642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 1682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * In rows for code points [start..end], select the column, reset the mask 1692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * bits and set the value bits (ANDed with the mask). 170f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * 1712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @throws IllegalArgumentException 172f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * 1732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @throws IllegalStateException 174f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * 1752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @throws IndexOutOfBoundsException 1762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void setValue(int start, int end, int column, int value, int mask) { 1782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (start < 0 || start > end || end > MAX_CP || column < 0 1792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller || column >= (columns - 2)) { 1802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalArgumentException(); 1812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (isCompacted) { 1832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalStateException("Shouldn't be called after" 1842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller + "compact()!"); 1852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int firstRow, lastRow; 1882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int limit = end + 1; 1892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean splitFirstRow, splitLastRow; 1902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // skip range start and limit columns 1912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller column += 2; 1922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller value &= mask; 1932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // find the rows whose ranges overlap with the input range 1952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // find the first and last row, always successful 1962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller firstRow = findRow(start); 1972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller lastRow = findRow(end); 1982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 2002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Rows need to be split if they partially overlap with the input range 2012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * (only possible for the first and last rows) and if their value 2022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * differs from the input value. 2032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller splitFirstRow = (start != v[firstRow] && value != (v[firstRow + column] & mask)); 2052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller splitLastRow = (limit != v[lastRow + 1] && value != (v[lastRow + column] & mask)); 2062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // split first/last rows if necessary 2082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (splitFirstRow || splitLastRow) { 2092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int rowsToExpand = 0; 2102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (splitFirstRow) { 2112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++rowsToExpand; 2122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (splitLastRow) { 2142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++rowsToExpand; 2152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int newMaxRows = 0; 2172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ((rows + rowsToExpand) > maxRows) { 2182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (maxRows < MEDIUM_ROWS) { 2192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller newMaxRows = MEDIUM_ROWS; 2202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (maxRows < MAX_ROWS) { 2212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller newMaxRows = MAX_ROWS; 2222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 2232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IndexOutOfBoundsException( 2242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller "MAX_ROWS exceeded! Increase it to a higher value" + 2252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller "in the implementation"); 2262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int[] temp = new int[newMaxRows * columns]; 2282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller System.arraycopy(v, 0, temp, 0, rows * columns); 2292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller v = temp; 2302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller maxRows = newMaxRows; 2312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // count the number of row cells to move after the last row, 2342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // and move them 2352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int count = (rows * columns) - (lastRow + columns); 2362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count > 0) { 2372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller System.arraycopy(v, lastRow + columns, v, lastRow 2382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller + (1 + rowsToExpand) * columns, count); 2392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller rows += rowsToExpand; 2412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // split the first row, and move the firstRow pointer 2432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // to the second part 2442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (splitFirstRow) { 2452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // copy all affected rows up one and move the lastRow pointer 2462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller count = lastRow - firstRow + columns; 2472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller System.arraycopy(v, firstRow, v, firstRow + columns, count); 2482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller lastRow += columns; 2492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // split the range and move the firstRow pointer 2512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller v[firstRow + 1] = v[firstRow + columns] = start; 2522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller firstRow += columns; 2532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // split the last row 2562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (splitLastRow) { 2572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // copy the last row data 2582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller System.arraycopy(v, lastRow, v, lastRow + columns, columns); 2592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // split the range and move the firstRow pointer 2612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller v[lastRow + 1] = v[lastRow + columns] = limit; 2622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // set the "row last seen" to the last row for the range 2662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller prevRow = lastRow / columns; 2672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // set the input value in all remaining rows 2692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller firstRow += column; 2702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller lastRow += column; 2712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller mask = ~mask; 2722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (;;) { 2732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller v[firstRow] = (v[firstRow] & mask) | value; 2742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (firstRow == lastRow) { 2752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 2762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller firstRow += columns; 2782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 2822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Always returns 0 if called after compact(). 2832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int getValue(int c, int column) { 2852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (isCompacted || c < 0 || c > MAX_CP || column < 0 2862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller || column >= (columns - 2)) { 2872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return 0; 2882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int index = findRow(c); 2902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return v[index + 2 + column]; 2912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 2942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns an array which contains value elements 295f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * in row rowIndex. 2962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @throws IllegalStateException 2982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @throws IllegalArgumentException 2992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int[] getRow(int rowIndex) { 3012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (isCompacted) { 3022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalStateException( 3032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller "Illegal Invocation of the method after compact()"); 3042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (rowIndex < 0 || rowIndex > rows) { 3062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalArgumentException("rowIndex out of bound!"); 3072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int[] rowToReturn = new int[columns - 2]; 3092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller System.arraycopy(v, rowIndex * columns + 2, rowToReturn, 0, 3102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller columns - 2); 3112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return rowToReturn; 3122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 3152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns an int which is the start codepoint 3162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * in row rowIndex. 317f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * 3182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @throws IllegalStateException 319f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * 3202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @throws IllegalArgumentException 3212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int getRowStart(int rowIndex) { 3232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (isCompacted) { 3242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalStateException( 3252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller "Illegal Invocation of the method after compact()"); 3262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (rowIndex < 0 || rowIndex > rows) { 3282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalArgumentException("rowIndex out of bound!"); 3292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return v[rowIndex * columns]; 3312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 334f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * Returns an int which is the limit codepoint 3352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * minus 1 in row rowIndex. 336f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * 3372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @throws IllegalStateException 338f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * 3392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @throws IllegalArgumentException 3402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int getRowEnd(int rowIndex) { 3422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (isCompacted) { 3432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalStateException( 3442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller "Illegal Invocation of the method after compact()"); 3452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (rowIndex < 0 || rowIndex > rows) { 3472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalArgumentException("rowIndex out of bound!"); 3482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return v[rowIndex * columns + 1] - 1; 3502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 351f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert 3522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 3532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Compact the vectors: 3542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * - modify the memory 3552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * - keep only unique vectors 3562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * - store them contiguously from the beginning of the memory 357f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * - for each (non-unique) row, call the respective function in 3582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * CompactHandler 3592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 3602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The handler's rowIndex is the index of the row in the compacted 361f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * memory block. Therefore, it starts at 0 increases in increments of the 3622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * columns value. 3632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 3642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * In a first phase, only special values are delivered (each exactly once). 3652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Then CompactHandler::startRealValues() is called 3662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * where rowIndex is the length of the compacted array. 367f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * Then, in the second phase, the CompactHandler::setRowIndexForRange() is 3682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * called for each row of real values. 3692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void compact(CompactHandler compactor) { 3712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (isCompacted) { 3722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 3732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Set the flag now: Sorting and compacting destroys the builder 3762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // data structure. 3772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller isCompacted = true; 3782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int valueColumns = columns - 2; // not counting start & limit 3792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // sort the properties vectors to find unique vector values 3812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Integer[] indexArray = new Integer[rows]; 3822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0; i < rows; ++i) { 3832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller indexArray[i] = Integer.valueOf(columns * i); 3842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Arrays.sort(indexArray, new Comparator<Integer>() { 387f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 3882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int compare(Integer o1, Integer o2) { 3892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int indexOfRow1 = o1.intValue(); 3902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int indexOfRow2 = o2.intValue(); 3912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int count = columns; // includes start/limit columns 3922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // start comparing after start/limit 3942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // but wrap around to them 3952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int index = 2; 3962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller do { 3972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (v[indexOfRow1 + index] != v[indexOfRow2 + index]) { 3982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return v[indexOfRow1 + index] < v[indexOfRow2 + index] ? -1 3992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller : 1; 4002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (++index == columns) { 4022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller index = 0; 4032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } while (--count > 0); 4052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return 0; 4072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller }); 4092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 4112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Find and set the special values. This has to do almost the same work 4122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * as the compaction below, to find the indexes where the special-value 4132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * rows will move. 4142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 4152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int count = -valueColumns; 4162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0; i < rows; ++i) { 4172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int start = v[indexArray[i].intValue()]; 4182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // count a new values vector if it is different 4202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // from the current one 4212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count < 0 || !areElementsSame(indexArray[i].intValue() + 2, v, 4222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller indexArray[i-1].intValue() + 2, valueColumns)) { 4232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller count += valueColumns; 4242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (start == INITIAL_VALUE_CP) { 4272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller compactor.setRowIndexForInitialValue(count); 4282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (start == ERROR_VALUE_CP) { 4292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller compactor.setRowIndexForErrorValue(count); 4302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // count is at the beginning of the last vector, 4342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // add valueColumns to include that last vector 4352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller count += valueColumns; 4362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Call the handler once more to signal the start of 4382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // delivering real values. 4392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller compactor.startRealValues(count); 4402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 442f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * Move vector contents up to a contiguous array with only unique 4432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * vector values, and call the handler function for each vector. 444f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * 445f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * This destroys the Properties Vector structure and replaces it 4462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * with an array of just vector values. 4472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 4482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int[] temp = new int[count]; 4492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller count = -valueColumns; 4502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0; i < rows; ++i) { 4512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int start = v[indexArray[i].intValue()]; 4522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int limit = v[indexArray[i].intValue() + 1]; 4532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // count a new values vector if it is different 4552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // from the current one 456f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert if (count < 0 || !areElementsSame(indexArray[i].intValue() + 2, 4572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller temp, count, valueColumns)) { 4582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller count += valueColumns; 4592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller System.arraycopy(v, indexArray[i].intValue() + 2, temp, count, 4602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller valueColumns); 4612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (start < FIRST_SPECIAL_CP) { 4642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller compactor.setRowIndexForRange(start, limit - 1, count); 4652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller v = temp; 468f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert 4692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // count is at the beginning of the last vector, 4702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // add one to include that last vector 4712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller rows = count / valueColumns + 1; 4722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 4752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Get the vectors array after calling compact(). 476f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * 4772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @throws IllegalStateException 4782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 4792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int[] getCompactedArray() { 4802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!isCompacted) { 4812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalStateException( 4822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller "Illegal Invocation of the method before compact()"); 4832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return v; 4852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 4882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Get the number of rows for the compacted array. 489f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * 4902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @throws IllegalStateException 4912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 4922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int getCompactedRows() { 4932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!isCompacted) { 4942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalStateException( 4952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller "Illegal Invocation of the method before compact()"); 4962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return rows; 4982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 5012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Get the number of columns for the compacted array. 502f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * 5032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @throws IllegalStateException 5042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 5052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int getCompactedColumns() { 5062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!isCompacted) { 5072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalStateException( 5082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller "Illegal Invocation of the method before compact()"); 5092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return columns - 2; 5112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 5142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Call compact(), create a IntTrie with indexes into the compacted 5152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * vectors array. 5162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 5172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public IntTrie compactToTrieWithRowIndexes() { 5182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller PVecToTrieCompactHandler compactor = new PVecToTrieCompactHandler(); 5192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller compact(compactor); 5202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return compactor.builder.serialize(new DefaultGetFoldedValue( 5212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller compactor.builder), new DefaultGetFoldingOffset()); 5222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // inner class implementation of Trie.DataManipulate 5252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static class DefaultGetFoldingOffset implements Trie.DataManipulate { 526f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 5272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int getFoldingOffset(int value) { 5282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return value; 5292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // inner class implementation of TrieBuilder.DataManipulate 5332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static class DefaultGetFoldedValue implements 5342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller TrieBuilder.DataManipulate { 5352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private IntTrieBuilder builder; 5362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public DefaultGetFoldedValue(IntTrieBuilder inBuilder) { 5382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller builder = inBuilder; 5392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 541f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 5422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int getFoldedValue(int start, int offset) { 543f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert int initialValue = builder.m_initialValue_; 5442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int limit = start + 0x400; 5452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (start < limit) { 5462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean[] inBlockZero = new boolean[1]; 5472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int value = builder.getValue(start, inBlockZero); 5482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (inBlockZero[0]) { 5492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller start += TrieBuilder.DATA_BLOCK_LENGTH; 5502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (value != initialValue) { 5512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return offset; 5522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 5532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++start; 5542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return 0; 5572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 559f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert 5602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static interface CompactHandler { 5612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void setRowIndexForRange(int start, int end, int rowIndex); 5622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void setRowIndexForInitialValue(int rowIndex); 5632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void setRowIndexForErrorValue(int rowIndex); 5642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void startRealValues(int rowIndex); 5652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller}