|
|
|
|
|
|
|
*/ |
|
/* |
|
* 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. |
|
*/ |
|
|
|
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; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
final class ChunkedIntArray |
|
{ |
|
final int slotsize=4; |
|
// 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; |
|
static final int chunkalloc=1<<lowbits; |
|
static final int lowmask=chunkalloc-1; |
|
|
|
ChunksVector chunks=new ChunksVector(); |
|
final int fastArray[] = new int[chunkalloc]; |
|
int lastUsed=0; |
|
|
|
|
|
|
|
|
|
*/ |
|
ChunkedIntArray(int slotsize) |
|
{ |
|
if(this.slotsize<slotsize) |
|
throw new ArrayIndexOutOfBoundsException(XMLMessages.createXMLMessage(XMLErrorResources.ER_CHUNKEDINTARRAY_NOT_SUPPORTED, new Object[]{Integer.toString(slotsize)})); |
|
else if (this.slotsize>slotsize) |
|
System.out.println("*****WARNING: ChunkedIntArray("+slotsize+") wasting "+(this.slotsize-slotsize)+" words per slot"); |
|
chunks.addElement(fastArray); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
int appendSlot(int w0, int w1, int w2, int w3) |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
{ |
|
final int slotsize=4; |
|
int newoffset = (lastUsed+1)*slotsize; |
|
int chunkpos = newoffset >> lowbits; |
|
int slotpos = (newoffset & lowmask); |
|
|
|
|
|
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; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
int readEntry(int position, int offset) throws ArrayIndexOutOfBoundsException |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
{ |
|
|
|
if (offset>=slotsize) |
|
throw new ArrayIndexOutOfBoundsException(XMLMessages.createXMLMessage(XMLErrorResources.ER_OFFSET_BIGGER_THAN_SLOT, null)); |
|
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. |
|
// |
|
|
|
int specialFind(int startPos, int position) |
|
{ |
|
// We have to look all the way up the ancestor chain |
|
|
|
int ancestor = startPos; |
|
while(ancestor > 0) |
|
{ |
|
|
|
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 |
|
|
|
ancestor = chunk[slotpos + 1]; |
|
|
|
if(ancestor == position) |
|
break; |
|
} |
|
|
|
if (ancestor <= 0) |
|
{ |
|
return position; |
|
} |
|
return -1; |
|
} |
|
|
|
|
|
|
|
*/ |
|
int slotsUsed() |
|
{ |
|
return lastUsed; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
void discardLast() |
|
{ |
|
--lastUsed; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
void writeEntry(int position, int offset, int value) throws ArrayIndexOutOfBoundsException |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
{ |
|
if (offset >= slotsize) |
|
throw new ArrayIndexOutOfBoundsException(XMLMessages.createXMLMessage(XMLErrorResources.ER_OFFSET_BIGGER_THAN_SLOT, null)); |
|
position*=slotsize; |
|
int chunkpos = position >> lowbits; |
|
int slotpos = position & lowmask; |
|
int[] chunk = chunks.elementAt(chunkpos); |
|
chunk[slotpos + offset] = value; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
void writeSlot(int position, int w0, int w1, int w2, int w3) |
|
{ |
|
position *= slotsize; |
|
int chunkpos = position >> lowbits; |
|
int slotpos = (position & lowmask); |
|
|
|
|
|
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; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
void readSlot(int position, int[] buffer) |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
{ |
|
|
|
position *= slotsize; |
|
int chunkpos = position >> lowbits; |
|
int slotpos = (position & lowmask); |
|
|
|
|
|
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 |
|
|
|
m_map[pos] = value; |
|
pos++; |
|
} |
|
|
|
final int[] elementAt(int pos) |
|
{ |
|
return m_map[pos]; |
|
} |
|
} |
|
} |