All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.org.apache.xml.internal.dtm.ref.ChunkedIntArray Maven / Gradle / Ivy

The newest version!
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 *
 *
 * This file incorporates work covered by the following copyright and
 * permission notice:
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * $Id: ChunkedIntArray.java,v 1.8 2010-11-01 04:34:37 joehw Exp $
 */
package com.sun.org.apache.xml.internal.dtm.ref;
 
import com.sun.org.apache.xml.internal.res.XMLErrorResources;
import com.sun.org.apache.xml.internal.res.XMLMessages;

/**
 * ChunkedIntArray is an extensible array of blocks of integers.
 * (I'd consider Vector, but it's unable to handle integers except by
 * turning them into Objects.)

 * 

Making this a separate class means some call-and-return overhead. But * doing it all inline tends to be fragile and expensive in coder time, * not to mention driving up code size. If you want to inline it, feel free. * The Java text suggest that private and Final methods may be inlined, * and one can argue that this beast need not be made subclassable...

* *

%REVIEW% This has strong conceptual overlap with the IntVector class. * It would probably be a good thing to merge the two, when time permits.

*/ final class ChunkedIntArray { final int slotsize=4; // Locked, MUST be power of two in current code // Debugging tip: Cranking lowbits down to 4 or so is a good // way to pound on the array addressing code. static final int lowbits=10; // How many bits address within chunks static final int chunkalloc=1<slotsize) System.out.println("*****WARNING: ChunkedIntArray("+slotsize+") wasting "+(this.slotsize-slotsize)+" words per slot"); chunks.addElement(fastArray); } /** * Append a 4-integer record to the CIA, starting with record 1. (Since * arrays are initialized to all-0, 0 has been reserved as the "unknown" * value in DTM.) * @return the index at which this record was inserted. */ int appendSlot(int w0, int w1, int w2, int w3) { /* try { int newoffset = (lastUsed+1)*slotsize; fastArray[newoffset] = w0; fastArray[newoffset+1] = w1; fastArray[newoffset+2] = w2; fastArray[newoffset+3] = w3; return ++lastUsed; } catch(ArrayIndexOutOfBoundsException aioobe) */ { final int slotsize=4; int newoffset = (lastUsed+1)*slotsize; int chunkpos = newoffset >> lowbits; int slotpos = (newoffset & lowmask); // Grow if needed if (chunkpos > chunks.size() - 1) chunks.addElement(new int[chunkalloc]); int[] chunk = chunks.elementAt(chunkpos); chunk[slotpos] = w0; chunk[slotpos+1] = w1; chunk[slotpos+2] = w2; chunk[slotpos+3] = w3; return ++lastUsed; } } /** * Retrieve an integer from the CIA by record number and column within * the record, both 0-based (though position 0 is reserved for special * purposes). * @param position int Record number * @param slotpos int Column number */ int readEntry(int position, int offset) throws ArrayIndexOutOfBoundsException { /* try { return fastArray[(position*slotsize)+offset]; } catch(ArrayIndexOutOfBoundsException aioobe) */ { // System.out.println("Using slow read (1)"); if (offset>=slotsize) throw new ArrayIndexOutOfBoundsException(XMLMessages.createXMLMessage(XMLErrorResources.ER_OFFSET_BIGGER_THAN_SLOT, null)); //"Offset bigger than slot"); position*=slotsize; int chunkpos = position >> lowbits; int slotpos = position & lowmask; int[] chunk = chunks.elementAt(chunkpos); return chunk[slotpos + offset]; } } // Check that the node at index "position" is not an ancestor // of the node at index "startPos". IF IT IS, DO NOT ACCEPT IT AND // RETURN -1. If position is NOT an ancestor, return position. // Special case: The Document node (position==0) is acceptable. // // This test supports DTM.getNextPreceding. int specialFind(int startPos, int position) { // We have to look all the way up the ancestor chain // to make sure we don't have an ancestor. int ancestor = startPos; while(ancestor > 0) { // Get the node whose index == ancestor ancestor*=slotsize; int chunkpos = ancestor >> lowbits; int slotpos = ancestor & lowmask; int[] chunk = chunks.elementAt(chunkpos); // Get that node's parent (Note that this assumes w[1] // is the parent node index. That's really a DTM feature // rather than a ChunkedIntArray feature.) ancestor = chunk[slotpos + 1]; if(ancestor == position) break; } if (ancestor <= 0) { return position; } return -1; } /** * @return int index of highest-numbered record currently in use */ int slotsUsed() { return lastUsed; } /** Disard the highest-numbered record. This is used in the string-buffer CIA; when only a single characters() chunk has been recieved, its index is moved into the Text node rather than being referenced by indirection into the text accumulator. */ void discardLast() { --lastUsed; } /** * Overwrite the integer found at a specific record and column. * Used to back-patch existing records, most often changing their * "next sibling" reference from 0 (unknown) to something meaningful * @param position int Record number * @param offset int Column number * @param value int New contents */ void writeEntry(int position, int offset, int value) throws ArrayIndexOutOfBoundsException { /* try { fastArray[( position*slotsize)+offset] = value; } catch(ArrayIndexOutOfBoundsException aioobe) */ { if (offset >= slotsize) throw new ArrayIndexOutOfBoundsException(XMLMessages.createXMLMessage(XMLErrorResources.ER_OFFSET_BIGGER_THAN_SLOT, null)); //"Offset bigger than slot"); position*=slotsize; int chunkpos = position >> lowbits; int slotpos = position & lowmask; int[] chunk = chunks.elementAt(chunkpos); chunk[slotpos + offset] = value; // ATOMIC! } } /** * Overwrite an entire (4-integer) record at the specified index. * Mostly used to create record 0, the Document node. * @param position integer Record number * @param w0 int * @param w1 int * @param w2 int * @param w3 int */ void writeSlot(int position, int w0, int w1, int w2, int w3) { position *= slotsize; int chunkpos = position >> lowbits; int slotpos = (position & lowmask); // Grow if needed if (chunkpos > chunks.size() - 1) chunks.addElement(new int[chunkalloc]); int[] chunk = chunks.elementAt(chunkpos); chunk[slotpos] = w0; chunk[slotpos + 1] = w1; chunk[slotpos + 2] = w2; chunk[slotpos + 3] = w3; } /** * Retrieve the contents of a record into a user-supplied buffer array. * Used to reduce addressing overhead when code will access several * columns of the record. * @param position int Record number * @param buffer int[] Integer array provided by user, must be large enough * to hold a complete record. */ void readSlot(int position, int[] buffer) { /* try { System.arraycopy(fastArray, position*slotsize, buffer, 0, slotsize); } catch(ArrayIndexOutOfBoundsException aioobe) */ { // System.out.println("Using slow read (2): "+position); position *= slotsize; int chunkpos = position >> lowbits; int slotpos = (position & lowmask); // Grow if needed if (chunkpos > chunks.size() - 1) chunks.addElement(new int[chunkalloc]); int[] chunk = chunks.elementAt(chunkpos); System.arraycopy(chunk,slotpos,buffer,0,slotsize); } } class ChunksVector { final int BLOCKSIZE = 64; int[] m_map[] = new int[BLOCKSIZE][]; int m_mapSize = BLOCKSIZE; int pos = 0; ChunksVector() { } final int size() { return pos; } void addElement(int[] value) { if(pos >= m_mapSize) { int orgMapSize = m_mapSize; while(pos >= m_mapSize) m_mapSize+=BLOCKSIZE; int[] newMap[] = new int[m_mapSize][]; System.arraycopy(m_map, 0, newMap, 0, orgMapSize); m_map = newMap; } // For now, just do a simple append. A sorted insert only // makes sense if we're doing an binary search or some such. m_map[pos] = value; pos++; } final int[] elementAt(int pos) { return m_map[pos]; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy