From 364584d16a48230e6dadc20d7f90fa910333de85 Mon Sep 17 00:00:00 2001 From: James Ahlborn Date: Mon, 22 Sep 2014 03:12:58 +0000 Subject: only need to generate index row values once per lookup iteration git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@883 f203690c-595d-4dc9-a70b-905162fa7fd2 --- .../jackcess/impl/CursorImpl.java | 48 +++++++++++++++++----- .../jackcess/impl/IndexCursorImpl.java | 29 ++++++++++--- 2 files changed, 61 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/CursorImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/CursorImpl.java index 89b1883..71c66e7 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/CursorImpl.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/CursorImpl.java @@ -456,7 +456,8 @@ public abstract class CursorImpl implements Cursor throws IOException { return findAnotherRow(columnPattern, valuePattern, true, MOVE_FORWARD, - _columnMatcher); + _columnMatcher, + prepareSearchInfo(columnPattern, valuePattern)); } public boolean findNextRow(Column columnPattern, Object valuePattern) @@ -469,12 +470,13 @@ public abstract class CursorImpl implements Cursor throws IOException { return findAnotherRow(columnPattern, valuePattern, false, MOVE_FORWARD, - _columnMatcher); + _columnMatcher, + prepareSearchInfo(columnPattern, valuePattern)); } protected boolean findAnotherRow(ColumnImpl columnPattern, Object valuePattern, boolean reset, boolean moveForward, - ColumnMatcher columnMatcher) + ColumnMatcher columnMatcher, Object searchInfo) throws IOException { PositionImpl curPos = _curPos; @@ -485,7 +487,7 @@ public abstract class CursorImpl implements Cursor reset(moveForward); } found = findAnotherRowImpl(columnPattern, valuePattern, moveForward, - columnMatcher, null); + columnMatcher, searchInfo); return found; } finally { if(!found) { @@ -500,18 +502,20 @@ public abstract class CursorImpl implements Cursor public boolean findFirstRow(Map rowPattern) throws IOException { - return findAnotherRow(rowPattern, true, MOVE_FORWARD, _columnMatcher); + return findAnotherRow(rowPattern, true, MOVE_FORWARD, _columnMatcher, + prepareSearchInfo(rowPattern)); } public boolean findNextRow(Map rowPattern) throws IOException { - return findAnotherRow(rowPattern, false, MOVE_FORWARD, _columnMatcher); + return findAnotherRow(rowPattern, false, MOVE_FORWARD, _columnMatcher, + prepareSearchInfo(rowPattern)); } protected boolean findAnotherRow(Map rowPattern, boolean reset, boolean moveForward, - ColumnMatcher columnMatcher) + ColumnMatcher columnMatcher, Object searchInfo) throws IOException { PositionImpl curPos = _curPos; @@ -521,7 +525,8 @@ public abstract class CursorImpl implements Cursor if(reset) { reset(moveForward); } - found = findAnotherRowImpl(rowPattern, moveForward, columnMatcher, null); + found = findAnotherRowImpl(rowPattern, moveForward, columnMatcher, + searchInfo); return found; } finally { if(!found) { @@ -640,6 +645,24 @@ public abstract class CursorImpl implements Cursor return false; } + /** + * Called before a search commences to allow for search specific data to be + * generated (which is cached for re-use by the iterators). + */ + protected Object prepareSearchInfo(ColumnImpl columnPattern, Object valuePattern) + { + return null; + } + + /** + * Called before a search commences to allow for search specific data to be + * generated (which is cached for re-use by the iterators). + */ + protected Object prepareSearchInfo(Map rowPattern) + { + return null; + } + /** * Called by findAnotherRowImpl to determine if the search should continue * after finding a row which does not match the current pattern. @@ -857,6 +880,7 @@ public abstract class CursorImpl implements Cursor { private final ColumnImpl _columnPattern; private final Object _valuePattern; + private final Object _searchInfo; private ColumnMatchIterator(Collection columnNames, ColumnImpl columnPattern, Object valuePattern, @@ -866,12 +890,13 @@ public abstract class CursorImpl implements Cursor super(columnNames, reset, moveForward, columnMatcher); _columnPattern = columnPattern; _valuePattern = valuePattern; + _searchInfo = prepareSearchInfo(columnPattern, valuePattern); } @Override protected boolean findNext() throws IOException { return findAnotherRow(_columnPattern, _valuePattern, false, _moveForward, - _colMatcher); + _colMatcher, _searchInfo); } } @@ -882,6 +907,7 @@ public abstract class CursorImpl implements Cursor private final class RowMatchIterator extends BaseIterator { private final Map _rowPattern; + private final Object _searchInfo; private RowMatchIterator(Collection columnNames, Map rowPattern, @@ -890,11 +916,13 @@ public abstract class CursorImpl implements Cursor { super(columnNames, reset, moveForward, columnMatcher); _rowPattern = rowPattern; + _searchInfo = prepareSearchInfo(rowPattern); } @Override protected boolean findNext() throws IOException { - return findAnotherRow(_rowPattern, false, _moveForward, _colMatcher); + return findAnotherRow(_rowPattern, false, _moveForward, _colMatcher, + _searchInfo); } } diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/IndexCursorImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/IndexCursorImpl.java index 4b8830a..479aa4b 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/IndexCursorImpl.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/IndexCursorImpl.java @@ -249,9 +249,7 @@ public class IndexCursorImpl extends CursorImpl implements IndexCursor ColumnMatcher columnMatcher, Object searchInfo) throws IOException { - // searching for the first match - Object[] rowValues = _entryCursor.getIndexData().constructIndexRow( - columnPattern.getName(), valuePattern); + Object[] rowValues = (Object[])searchInfo; if((rowValues == null) || !isAtBeginning(moveForward)) { // use the default table scan if we don't have index data or we are @@ -300,9 +298,7 @@ public class IndexCursorImpl extends CursorImpl implements IndexCursor ColumnMatcher columnMatcher, Object searchInfo) throws IOException { - // searching for the first match - IndexData indexData = _entryCursor.getIndexData(); - Object[] rowValues = indexData.constructIndexRow(rowPattern); + Object[] rowValues = (Object[])searchInfo; if((rowValues == null) || !isAtBeginning(moveForward)) { // use the default table scan if we don't have index data or we are @@ -318,6 +314,7 @@ public class IndexCursorImpl extends CursorImpl implements IndexCursor } // find actual matching row + IndexData indexData = _entryCursor.getIndexData(); Map indexRowPattern = null; if(rowPattern.size() == indexData.getColumns().size()) { // the rowPattern matches our index columns exactly, so we can @@ -390,14 +387,34 @@ public class IndexCursorImpl extends CursorImpl implements IndexCursor return true; } + @Override + protected Object prepareSearchInfo(ColumnImpl columnPattern, Object valuePattern) + { + // attempt to generate a lookup row for this index + return _entryCursor.getIndexData().constructIndexRow( + columnPattern.getName(), valuePattern); + } + + @Override + protected Object prepareSearchInfo(Map rowPattern) + { + // attempt to generate a lookup row for this index + return _entryCursor.getIndexData().constructIndexRow(rowPattern); + } + @Override protected boolean keepSearching(ColumnMatcher columnMatcher, Object searchInfo) throws IOException { if(searchInfo instanceof Object[]) { + // if we have a lookup row for this index, then we only need to continue + // searching while we are looking at rows which match the index lookup + // value(s). once we move past those rows, no other rows could possibly + // match. return currentRowMatchesEntryImpl((Object[])searchInfo, columnMatcher); } + // we are doing a full table scan return true; } -- cgit v1.2.3