[bug-65184] Improve performance of POFSMiniStore getBlockAt. Thanks to sits

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1887604 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
PJ Fanning 2021-03-13 18:09:13 +00:00
parent 5758145ce8
commit c70b649e73
1 changed files with 135 additions and 137 deletions

View File

@ -1,4 +1,3 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
@ -35,8 +34,7 @@ import org.apache.poi.poifs.storage.HeaderBlock;
* This class handles the MiniStream (small block store)
* in the NIO case for {@link POIFSFileSystem}
*/
public class POIFSMiniStore extends BlockStore
{
public class POIFSMiniStore extends BlockStore {
private final POIFSFileSystem _filesystem;
private POIFSStream _mini_stream;
private final List<BATBlock> _sbat_blocks;
@ -44,8 +42,7 @@ public class POIFSMiniStore extends BlockStore
private final RootProperty _root;
POIFSMiniStore(POIFSFileSystem filesystem, RootProperty root,
List<BATBlock> sbats, HeaderBlock header)
{
List<BATBlock> sbats, HeaderBlock header) {
this._filesystem = filesystem;
this._sbat_blocks = sbats;
this._header = header;
@ -65,11 +62,11 @@ public class POIFSMiniStore extends BlockStore
// Now locate the data block for it
Iterator<ByteBuffer> it = _mini_stream.getBlockIterator();
for(int i=0; i<bigBlockNumber; i++) {
for (int i = 0; i < bigBlockNumber; i++) {
it.next();
}
ByteBuffer dataBlock = it.next();
assert(dataBlock != null);
assert (dataBlock != null);
// Position ourselves, and take a slice
dataBlock.position(
@ -90,10 +87,11 @@ public class POIFSMiniStore extends BlockStore
}
// Try to get it without extending the stream
if (! firstInStore) {
if (!firstInStore) {
try {
return getBlockAt(offset);
} catch(NoSuchElementException ignored) {}
} catch (NoSuchElementException ignored) {
}
}
// Need to extend the stream
@ -112,10 +110,10 @@ public class POIFSMiniStore extends BlockStore
// Tack it onto the end of our chain
ChainLoopDetector loopDetector = _filesystem.getChainLoopDetector();
int block = _mini_stream.getStartBlock();
while(true) {
while (true) {
loopDetector.claim(block);
int next = _filesystem.getNextBlock(block);
if(next == POIFSConstants.END_OF_CHAIN) {
if (next == POIFSConstants.END_OF_CHAIN) {
break;
}
block = next;
@ -145,7 +143,7 @@ public class POIFSMiniStore extends BlockStore
*/
protected int getNextBlock(final int offset) {
BATBlockAndIndex bai = getBATBlockAndIndex(offset);
return bai.getBlock().getValueAt( bai.getIndex() );
return bai.getBlock().getValueAt(bai.getIndex());
}
/**
@ -195,7 +193,7 @@ public class POIFSMiniStore extends BlockStore
newSBAT.setOurBlockIndex(batForSBAT);
// Are we the first SBAT?
if(_header.getSBATCount() == 0) {
if (_header.getSBATCount() == 0) {
// Tell the header that we've got our first SBAT there
_header.setSBATStart(batForSBAT);
_header.setSBATBlockCount(1);
@ -203,10 +201,10 @@ public class POIFSMiniStore extends BlockStore
// Find the end of the SBAT stream, and add the sbat in there
ChainLoopDetector loopDetector = _filesystem.getChainLoopDetector();
int batOffset = _header.getSBATStart();
while(true) {
while (true) {
loopDetector.claim(batOffset);
int nextBat = _filesystem.getNextBlock(batOffset);
if(nextBat == POIFSConstants.END_OF_CHAIN) {
if (nextBat == POIFSConstants.END_OF_CHAIN) {
break;
}
batOffset = nextBat;
@ -231,7 +229,7 @@ public class POIFSMiniStore extends BlockStore
@Override
protected ChainLoopDetector getChainLoopDetector() {
return new ChainLoopDetector( _root.getSize() );
return new ChainLoopDetector(_root.getSize());
}
protected int getBlockStoreBlockSize() {