From 94148f092f4b65b3abde48a38f80076c6d4f9f78 Mon Sep 17 00:00:00 2001 From: James Ahlborn Date: Sun, 21 Sep 2014 03:24:42 +0000 Subject: [PATCH] IndexCursor can early exit when searching based on indexed values, fixes 109 git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@881 f203690c-595d-4dc9-a70b-905162fa7fd2 --- src/changes/changes.xml | 5 +++ .../jackcess/impl/CursorImpl.java | 28 +++++++++--- .../jackcess/impl/IndexCursorImpl.java | 45 ++++++++++--------- 3 files changed, 52 insertions(+), 26 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index dba094a..affaa5c 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -4,6 +4,11 @@ Tim McCune + + + IndexCursor can early exit when searching based on indexed values. + + Add Cursor.findRow(RowId) for moving to a specific Table row using diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/CursorImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/CursorImpl.java index 1521e3b..89b1883 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/CursorImpl.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/CursorImpl.java @@ -315,7 +315,7 @@ public abstract class CursorImpl implements Cursor * {@code null} if there is not another row in the given direction. */ private Row getAnotherRow(Collection columnNames, - boolean moveForward) + boolean moveForward) throws IOException { if(moveToAnotherRow(moveForward)) { @@ -485,7 +485,7 @@ public abstract class CursorImpl implements Cursor reset(moveForward); } found = findAnotherRowImpl(columnPattern, valuePattern, moveForward, - columnMatcher); + columnMatcher, null); return found; } finally { if(!found) { @@ -521,7 +521,7 @@ public abstract class CursorImpl implements Cursor if(reset) { reset(moveForward); } - found = findAnotherRowImpl(rowPattern, moveForward, columnMatcher); + found = findAnotherRowImpl(rowPattern, moveForward, columnMatcher, null); return found; } finally { if(!found) { @@ -598,13 +598,16 @@ public abstract class CursorImpl implements Cursor */ protected boolean findAnotherRowImpl( ColumnImpl columnPattern, Object valuePattern, boolean moveForward, - ColumnMatcher columnMatcher) + ColumnMatcher columnMatcher, Object searchInfo) throws IOException { while(moveToAnotherRow(moveForward)) { if(currentRowMatchesImpl(columnPattern, valuePattern, columnMatcher)) { return true; } + if(!keepSearching(columnMatcher, searchInfo)) { + break; + } } return false; } @@ -622,17 +625,32 @@ public abstract class CursorImpl implements Cursor */ protected boolean findAnotherRowImpl(Map rowPattern, boolean moveForward, - ColumnMatcher columnMatcher) + ColumnMatcher columnMatcher, + Object searchInfo) throws IOException { while(moveToAnotherRow(moveForward)) { if(currentRowMatchesImpl(rowPattern, columnMatcher)) { return true; } + if(!keepSearching(columnMatcher, searchInfo)) { + break; + } } return false; } + /** + * Called by findAnotherRowImpl to determine if the search should continue + * after finding a row which does not match the current pattern. + */ + protected boolean keepSearching(ColumnMatcher columnMatcher, + Object searchInfo) + throws IOException + { + return true; + } + public int moveNextRows(int numRows) throws IOException { return moveSomeRows(numRows, MOVE_FORWARD); diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/IndexCursorImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/IndexCursorImpl.java index 68870d9..4b8830a 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/IndexCursorImpl.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/IndexCursorImpl.java @@ -246,23 +246,18 @@ public class IndexCursorImpl extends CursorImpl implements IndexCursor @Override protected boolean findAnotherRowImpl( ColumnImpl columnPattern, Object valuePattern, boolean moveForward, - ColumnMatcher columnMatcher) + ColumnMatcher columnMatcher, Object searchInfo) throws IOException { - if(!isAtBeginning(moveForward)) { - // use the default table scan for finding rows mid-cursor - return super.findAnotherRowImpl(columnPattern, valuePattern, moveForward, - columnMatcher); - } - // searching for the first match Object[] rowValues = _entryCursor.getIndexData().constructIndexRow( columnPattern.getName(), valuePattern); - if(rowValues == null) { - // bummer, use the default table scan + if((rowValues == null) || !isAtBeginning(moveForward)) { + // use the default table scan if we don't have index data or we are + // mid-cursor return super.findAnotherRowImpl(columnPattern, valuePattern, moveForward, - columnMatcher); + columnMatcher, rowValues); } // sweet, we can use our index @@ -300,23 +295,20 @@ public class IndexCursorImpl extends CursorImpl implements IndexCursor } @Override - protected boolean findAnotherRowImpl(Map rowPattern, - boolean moveForward, - ColumnMatcher columnMatcher) + protected boolean findAnotherRowImpl( + Map rowPattern, boolean moveForward, + ColumnMatcher columnMatcher, Object searchInfo) throws IOException { - if(!isAtBeginning(moveForward)) { - // use the default table scan for finding rows mid-cursor - return super.findAnotherRowImpl(rowPattern, moveForward, columnMatcher); - } - // searching for the first match IndexData indexData = _entryCursor.getIndexData(); Object[] rowValues = indexData.constructIndexRow(rowPattern); - if(rowValues == null) { - // bummer, use the default table scan - return super.findAnotherRowImpl(rowPattern, moveForward, columnMatcher); + if((rowValues == null) || !isAtBeginning(moveForward)) { + // use the default table scan if we don't have index data or we are + // mid-cursor + return super.findAnotherRowImpl(rowPattern, moveForward, columnMatcher, + rowValues); } // sweet, we can use our index @@ -398,6 +390,17 @@ public class IndexCursorImpl extends CursorImpl implements IndexCursor return true; } + @Override + protected boolean keepSearching(ColumnMatcher columnMatcher, + Object searchInfo) + throws IOException + { + if(searchInfo instanceof Object[]) { + return currentRowMatchesEntryImpl((Object[])searchInfo, columnMatcher); + } + return true; + } + private Object[] toRowValues(Object[] entryValues) { return _entryCursor.getIndexData().constructIndexRowFromEntry(entryValues); -- 2.39.5