19f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/* 29f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one 39f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * or more contributor license agreements. See the NOTICE file 49f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed with this work for additional information 59f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * regarding copyright ownership. The ASF licenses this file 69f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * to you under the Apache License, Version 2.0 (the "License"); 79f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * you may not use this file except in compliance with the License. 89f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * You may obtain a copy of the License at 99f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Unless required by applicable law or agreed to in writing, software 139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * See the License for the specific language governing permissions and 169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * limitations under the License. 179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/* 199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * $Id: ChunkedIntArray.java 468653 2006-10-28 07:07:05Z minchau $ 209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpackage org.apache.xml.dtm.ref; 229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.res.XMLErrorResources; 249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.res.XMLMessages; 259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/** 279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <code>ChunkedIntArray</code> is an extensible array of blocks of integers. 289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * (I'd consider Vector, but it's unable to handle integers except by 299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * turning them into Objects.) 309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>Making this a separate class means some call-and-return overhead. But 329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * doing it all inline tends to be fragile and expensive in coder time, 339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * not to mention driving up code size. If you want to inline it, feel free. 349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * The Java text suggest that private and Final methods may be inlined, 359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * and one can argue that this beast need not be made subclassable...</p> 369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>%REVIEW% This has strong conceptual overlap with the IntVector class. 389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * It would probably be a good thing to merge the two, when time permits.<p> 399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonfinal class ChunkedIntArray 419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson{ 429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson final int slotsize=4; // Locked, MUST be power of two in current code 439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Debugging tip: Cranking lowbits down to 4 or so is a good 449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // way to pound on the array addressing code. 459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson static final int lowbits=10; // How many bits address within chunks 469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson static final int chunkalloc=1<<lowbits; 479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson static final int lowmask=chunkalloc-1; 489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ChunksVector chunks=new ChunksVector(); 509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson final int fastArray[] = new int[chunkalloc]; 519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int lastUsed=0; 529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Create a new CIA with specified record size. Currently record size MUST 559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * be a power of two... and in fact is hardcoded to 4. 569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ChunkedIntArray(int slotsize) 589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(this.slotsize<slotsize) 609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new ArrayIndexOutOfBoundsException(XMLMessages.createXMLMessage(XMLErrorResources.ER_CHUNKEDINTARRAY_NOT_SUPPORTED, new Object[]{Integer.toString(slotsize)})); //"ChunkedIntArray("+slotsize+") not currently supported"); 619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else if (this.slotsize>slotsize) 629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson System.out.println("*****WARNING: ChunkedIntArray("+slotsize+") wasting "+(this.slotsize-slotsize)+" words per slot"); 639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson chunks.addElement(fastArray); 649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Append a 4-integer record to the CIA, starting with record 1. (Since 679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * arrays are initialized to all-0, 0 has been reserved as the "unknown" 689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * value in DTM.) 699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return the index at which this record was inserted. 709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int appendSlot(int w0, int w1, int w2, int w3) 729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /* 749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try 759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int newoffset = (lastUsed+1)*slotsize; 779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fastArray[newoffset] = w0; 789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fastArray[newoffset+1] = w1; 799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fastArray[newoffset+2] = w2; 809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fastArray[newoffset+3] = w3; 819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return ++lastUsed; 829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson catch(ArrayIndexOutOfBoundsException aioobe) 849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson final int slotsize=4; 879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int newoffset = (lastUsed+1)*slotsize; 889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int chunkpos = newoffset >> lowbits; 899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int slotpos = (newoffset & lowmask); 909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Grow if needed 929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (chunkpos > chunks.size() - 1) 939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson chunks.addElement(new int[chunkalloc]); 949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int[] chunk = chunks.elementAt(chunkpos); 959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson chunk[slotpos] = w0; 969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson chunk[slotpos+1] = w1; 979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson chunk[slotpos+2] = w2; 989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson chunk[slotpos+3] = w3; 999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return ++lastUsed; 1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Retrieve an integer from the CIA by record number and column within 1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * the record, both 0-based (though position 0 is reserved for special 1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * purposes). 1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param position int Record number 1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param slotpos int Column number 1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int readEntry(int position, int offset) throws ArrayIndexOutOfBoundsException 1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /* 1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try 1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return fastArray[(position*slotsize)+offset]; 1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson catch(ArrayIndexOutOfBoundsException aioobe) 1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // System.out.println("Using slow read (1)"); 1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (offset>=slotsize) 1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new ArrayIndexOutOfBoundsException(XMLMessages.createXMLMessage(XMLErrorResources.ER_OFFSET_BIGGER_THAN_SLOT, null)); //"Offset bigger than slot"); 1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson position*=slotsize; 1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int chunkpos = position >> lowbits; 1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int slotpos = position & lowmask; 1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int[] chunk = chunks.elementAt(chunkpos); 1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return chunk[slotpos + offset]; 1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Check that the node at index "position" is not an ancestor 1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // of the node at index "startPos". IF IT IS, DO NOT ACCEPT IT AND 1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // RETURN -1. If position is NOT an ancestor, return position. 1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Special case: The Document node (position==0) is acceptable. 1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // This test supports DTM.getNextPreceding. 1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int specialFind(int startPos, int position) 1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // We have to look all the way up the ancestor chain 1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // to make sure we don't have an ancestor. 1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int ancestor = startPos; 1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson while(ancestor > 0) 1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Get the node whose index == ancestor 1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ancestor*=slotsize; 1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int chunkpos = ancestor >> lowbits; 1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int slotpos = ancestor & lowmask; 1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int[] chunk = chunks.elementAt(chunkpos); 1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Get that node's parent (Note that this assumes w[1] 1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // is the parent node index. That's really a DTM feature 1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // rather than a ChunkedIntArray feature.) 1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ancestor = chunk[slotpos + 1]; 1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(ancestor == position) 1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson break; 1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (ancestor <= 0) 1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return position; 1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return -1; 1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return int index of highest-numbered record currently in use 1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int slotsUsed() 1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return lastUsed; 1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** Disard the highest-numbered record. This is used in the string-buffer 1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson CIA; when only a single characters() chunk has been recieved, its index 1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson is moved into the Text node rather than being referenced by indirection 1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson into the text accumulator. 1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson void discardLast() 1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson --lastUsed; 1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Overwrite the integer found at a specific record and column. 1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Used to back-patch existing records, most often changing their 1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * "next sibling" reference from 0 (unknown) to something meaningful 1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param position int Record number 1899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param offset int Column number 1909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param value int New contents 1919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson void writeEntry(int position, int offset, int value) throws ArrayIndexOutOfBoundsException 1939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /* 1959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try 1969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fastArray[( position*slotsize)+offset] = value; 1989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson catch(ArrayIndexOutOfBoundsException aioobe) 2009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 2019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (offset >= slotsize) 2039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new ArrayIndexOutOfBoundsException(XMLMessages.createXMLMessage(XMLErrorResources.ER_OFFSET_BIGGER_THAN_SLOT, null)); //"Offset bigger than slot"); 2049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson position*=slotsize; 2059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int chunkpos = position >> lowbits; 2069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int slotpos = position & lowmask; 2079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int[] chunk = chunks.elementAt(chunkpos); 2089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson chunk[slotpos + offset] = value; // ATOMIC! 2099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 2139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Overwrite an entire (4-integer) record at the specified index. 2149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Mostly used to create record 0, the Document node. 2159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param position integer Record number 2169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param w0 int 2179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param w1 int 2189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param w2 int 2199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param w3 int 2209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 2219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson void writeSlot(int position, int w0, int w1, int w2, int w3) 2229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson position *= slotsize; 2249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int chunkpos = position >> lowbits; 2259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int slotpos = (position & lowmask); 2269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Grow if needed 2289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (chunkpos > chunks.size() - 1) 2299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson chunks.addElement(new int[chunkalloc]); 2309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int[] chunk = chunks.elementAt(chunkpos); 2319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson chunk[slotpos] = w0; 2329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson chunk[slotpos + 1] = w1; 2339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson chunk[slotpos + 2] = w2; 2349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson chunk[slotpos + 3] = w3; 2359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 2389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Retrieve the contents of a record into a user-supplied buffer array. 2399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Used to reduce addressing overhead when code will access several 2409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * columns of the record. 2419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param position int Record number 2429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param buffer int[] Integer array provided by user, must be large enough 2439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * to hold a complete record. 2449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 2459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson void readSlot(int position, int[] buffer) 2469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /* 2489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try 2499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson System.arraycopy(fastArray, position*slotsize, buffer, 0, slotsize); 2519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson catch(ArrayIndexOutOfBoundsException aioobe) 2539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 2549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // System.out.println("Using slow read (2): "+position); 2569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson position *= slotsize; 2579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int chunkpos = position >> lowbits; 2589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int slotpos = (position & lowmask); 2599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Grow if needed 2619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (chunkpos > chunks.size() - 1) 2629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson chunks.addElement(new int[chunkalloc]); 2639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int[] chunk = chunks.elementAt(chunkpos); 2649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson System.arraycopy(chunk,slotpos,buffer,0,slotsize); 2659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson class ChunksVector 2699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson final int BLOCKSIZE = 64; 2719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int[] m_map[] = new int[BLOCKSIZE][]; 2729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int m_mapSize = BLOCKSIZE; 2739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int pos = 0; 2749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ChunksVector() 2769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson final int size() 2809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return pos; 2829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson void addElement(int[] value) 2859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(pos >= m_mapSize) 2879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int orgMapSize = m_mapSize; 2899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson while(pos >= m_mapSize) 2909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_mapSize+=BLOCKSIZE; 2919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int[] newMap[] = new int[m_mapSize][]; 2929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson System.arraycopy(m_map, 0, newMap, 0, orgMapSize); 2939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_map = newMap; 2949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // For now, just do a simple append. A sorted insert only 2969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // makes sense if we're doing an binary search or some such. 2979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson m_map[pos] = value; 2989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson pos++; 2999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson final int[] elementAt(int pos) 3029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return m_map[pos]; 3049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson} 307