From: James Ahlborn Date: Sat, 5 Apr 2008 04:15:14 +0000 (+0000) Subject: refactor Index/SimpleIndex to move most of the add/remove entry handling logic back... X-Git-Tag: rel_1_1_14~37 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=12d9cde06fdb5db89b5e406a8c5101fb84307140;p=jackcess.git refactor Index/SimpleIndex to move most of the add/remove entry handling logic back into Index git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@310 f203690c-595d-4dc9-a70b-905162fa7fd2 --- diff --git a/src/java/com/healthmarketscience/jackcess/Index.java b/src/java/com/healthmarketscience/jackcess/Index.java index 84ed161..650f65d 100644 --- a/src/java/com/healthmarketscience/jackcess/Index.java +++ b/src/java/com/healthmarketscience/jackcess/Index.java @@ -277,10 +277,6 @@ public abstract class Index implements Comparable { return _rootPageNumber; } - protected void addedUniqueEntry() { - ++_uniqueEntryCount; - } - protected void setReadOnly() { _readOnly = true; } @@ -288,6 +284,25 @@ public abstract class Index implements Comparable { protected int getMaxPageEntrySize() { return _maxPageEntrySize; } + + /** + * Returns the number of index entries in the index. Only called by unit + * tests. + *

+ * Forces index initialization. + */ + protected int getEntryCount() + throws IOException + { + initialize(); + EntryCursor cursor = cursor(); + Entry endEntry = cursor.getLastEntry(); + int count = 0; + while(!endEntry.equals(cursor.getNextEntry())) { + ++count; + } + return count; + } /** * Forces initialization of this index (actual parsing of index pages). @@ -387,6 +402,47 @@ public abstract class Index implements Comparable { } } + /** + * Adds an entry to the correct index dataPage, maintaining the order. + */ + private boolean addEntry(Entry newEntry, boolean isNullEntry, Object[] row) + throws IOException + { + DataPage dataPage = findDataPage(newEntry); + int idx = dataPage.findEntry(newEntry); + if(idx < 0) { + // this is a new entry + idx = missingIndexToInsertionPoint(idx); + + Position newPos = new Position(dataPage, idx, newEntry, true); + Position nextPos = getNextPosition(newPos); + Position prevPos = getPreviousPosition(newPos); + + // determine if the addition of this entry would break the uniqueness + // constraint. See isUnique() for some notes about uniqueness as + // defined by Access. + boolean isDupeEntry = + (((nextPos != null) && + newEntry.equalsEntryBytes(nextPos.getEntry())) || + ((prevPos != null) && + newEntry.equalsEntryBytes(prevPos.getEntry()))); + if(isUnique() && !isNullEntry && isDupeEntry) + { + throw new IOException( + "New row " + Arrays.asList(row) + + " violates uniqueness constraint for index " + this); + } + + if(!isDupeEntry) { + ++_uniqueEntryCount; + } + + dataPage.addEntry(idx, newEntry); + return true; + } + return false; + } + /** * Removes a row from this index *

@@ -416,6 +472,45 @@ public abstract class Index implements Comparable { } } + /** + * Removes an entry from the relevant index dataPage, maintaining the order. + * Will search by RowId if entry is not found (in case a partial entry was + * provided). + */ + private boolean removeEntry(Entry oldEntry) + throws IOException + { + DataPage dataPage = findDataPage(oldEntry); + int idx = dataPage.findEntry(oldEntry); + boolean doRemove = false; + if(idx < 0) { + // the caller may have only read some of the row data, if this is the + // case, just search for the page/row numbers + // FIXME, we could force caller to get relevant values? + EntryCursor cursor = cursor(); + Position tmpPos = null; + Position endPos = cursor._lastPos; + while(!endPos.equals( + tmpPos = cursor.getAnotherPosition(Cursor.MOVE_FORWARD))) { + if(tmpPos.getEntry().getRowId().equals(oldEntry.getRowId())) { + dataPage = tmpPos.getDataPage(); + idx = tmpPos.getIndex(); + doRemove = true; + break; + } + } + } else { + doRemove = true; + } + + if(doRemove) { + // found it! + dataPage.removeEntry(idx); + } + + return doRemove; + } + /** * Gets a new cursor for this index. *

@@ -486,7 +581,7 @@ public abstract class Index implements Comparable { return new Position(dataPage, idx, entry, between); } - private Position getNextPosition(Position curPos, Position lastPos) + private Position getNextPosition(Position curPos) throws IOException { // get the next index (between-ness is handled internally) @@ -507,17 +602,15 @@ public abstract class Index implements Comparable { } if(nextDataPage != null) { nextPos = new Position(nextDataPage, nextIdx); - } else { - nextPos = lastPos; } } - if(nextPos.compareTo(lastPos) >= 0) { - nextPos = lastPos; - } return nextPos; } - - private Position getPreviousPosition(Position curPos, Position firstPos) + + /** + * Returns the Position before the given one, or {@code null} if none. + */ + private Position getPreviousPosition(Position curPos) throws IOException { // get the previous index (between-ness is handled internally) @@ -539,13 +632,8 @@ public abstract class Index implements Comparable { if(prevDataPage != null) { prevPos = new Position(prevDataPage, (prevDataPage.getEntries().size() - 1)); - } else { - prevPos = firstPos; } } - if(prevPos.compareTo(firstPos) <= 0) { - prevPos = firstPos; - } return prevPos; } @@ -868,14 +956,6 @@ public abstract class Index implements Comparable { return bout.toByteArray(); } - /** - * Returns the number of index entries in the index. Only called by unit - * tests. - *

- * Forces index initialization. - */ - protected abstract int getEntryCount() throws IOException; - /** * Writes the current index state to the database. Index has already been * initialized. @@ -887,21 +967,6 @@ public abstract class Index implements Comparable { */ protected abstract void readIndexEntries() throws IOException; - - /** - * Adds an entry to the _entries list, maintaining the order. - */ - protected abstract boolean addEntry(Entry newEntry, boolean isNullEntry, - Object[] row) - throws IOException; - - /** - * Removes an entry from the _entries list, maintaining the order. Will - * search by RowId if entry is not found in case a partial entry was - * provided. - */ - protected abstract boolean removeEntry(Entry oldEntry) - throws IOException; /** * Finds the data page for the given entry. @@ -1811,7 +1876,7 @@ public abstract class Index implements Comparable { * {@code #getLastEntry} otherwise */ public Entry getNextEntry() throws IOException { - return getAnotherEntry(Cursor.MOVE_FORWARD); + return getAnotherPosition(Cursor.MOVE_FORWARD).getEntry(); } /** @@ -1819,7 +1884,7 @@ public abstract class Index implements Comparable { * {@code #getFirstEntry} otherwise */ public Entry getPreviousEntry() throws IOException { - return getAnotherEntry(Cursor.MOVE_REVERSE); + return getAnotherPosition(Cursor.MOVE_REVERSE).getEntry(); } /** @@ -1855,7 +1920,7 @@ public abstract class Index implements Comparable { /** * Gets another entry in the given direction, returning the new entry. */ - private Entry getAnotherEntry(boolean moveForward) + private Position getAnotherPosition(boolean moveForward) throws IOException { DirHandler handler = getDirHandler(moveForward); @@ -1865,7 +1930,7 @@ public abstract class Index implements Comparable { // drop through and retry moving to another entry } else { // at end, no more - return _curPos.getEntry(); + return _curPos; } } @@ -1873,7 +1938,7 @@ public abstract class Index implements Comparable { _prevPos = _curPos; _curPos = handler.getAnotherPosition(_curPos); - return _curPos.getEntry(); + return _curPos; } /** @@ -1951,7 +2016,11 @@ public abstract class Index implements Comparable { public Position getAnotherPosition(Position curPos) throws IOException { - return getNextPosition(curPos, _lastPos); + Position newPos = getNextPosition(curPos); + if((newPos == null) || (newPos.compareTo(_lastPos) >= 0)) { + newPos = _lastPos; + } + return newPos; } @Override public Position getBeginningPosition() { @@ -1971,7 +2040,11 @@ public abstract class Index implements Comparable { public Position getAnotherPosition(Position curPos) throws IOException { - return getPreviousPosition(curPos, _firstPos); + Position newPos = getPreviousPosition(curPos); + if((newPos == null) || (newPos.compareTo(_firstPos) <= 0)) { + newPos = _firstPos; + } + return newPos; } @Override public Position getBeginningPosition() { @@ -2109,6 +2182,9 @@ public abstract class Index implements Comparable { public abstract List getEntries(); public abstract void setEntries(List entries); + + public abstract void addEntry(int idx, Entry entry); + public abstract void removeEntry(int idx); public final int getCompressedEntrySize() { // when written to the index page, the entryPrefix bytes will only be diff --git a/src/java/com/healthmarketscience/jackcess/SimpleIndex.java b/src/java/com/healthmarketscience/jackcess/SimpleIndex.java index 119aaae..f3651c5 100644 --- a/src/java/com/healthmarketscience/jackcess/SimpleIndex.java +++ b/src/java/com/healthmarketscience/jackcess/SimpleIndex.java @@ -50,18 +50,6 @@ public class SimpleIndex extends Index { super(table, uniqueEntryCount, uniqueEntryCountOffset); } - private List getEntries() { - return _dataPage.getEntries(); - } - - @Override - protected int getEntryCount() - throws IOException - { - initialize(); - return getEntries().size(); - } - @Override protected void updateImpl() throws IOException { writeDataPage(_dataPage); @@ -128,73 +116,6 @@ public class SimpleIndex extends Index { } } - /** - * Finds the index of given entry in the entries list. - * @return the index if found, (- - 1) if not found - */ - private int findEntry(Entry entry) { - return Collections.binarySearch(getEntries(), entry); - } - - @Override - protected boolean addEntry(Entry newEntry, boolean isNullEntry, Object[] row) - throws IOException - { - int idx = findEntry(newEntry); - if(idx < 0) { - // this is a new entry - idx = missingIndexToInsertionPoint(idx); - - // determine if the addition of this entry would break the uniqueness - // constraint. See isUnique() for some notes about uniqueness as - // defined by Access. - boolean isDupeEntry = - (((idx > 0) && - newEntry.equalsEntryBytes(getEntries().get(idx - 1))) || - ((idx < getEntries().size()) && - newEntry.equalsEntryBytes(getEntries().get(idx)))); - if(isUnique() && !isNullEntry && isDupeEntry) - { - throw new IOException( - "New row " + Arrays.asList(row) + - " violates uniqueness constraint for index " + this); - } - - if(!isDupeEntry) { - addedUniqueEntry(); - } - - getEntries().add(idx, newEntry); - return true; - } - return false; - } - - @Override - protected boolean removeEntry(Entry oldEntry) - { - int idx = findEntry(oldEntry); - boolean removed = false; - if(idx < 0) { - // the caller may have only read some of the row data, if this is the - // case, just search for the page/row numbers - for(Iterator iter = getEntries().iterator(); iter.hasNext(); ) { - Entry entry = iter.next(); - if(entry.getRowId().equals(oldEntry.getRowId())) { - iter.remove(); - removed = true; - break; - } - } - } else { - // found it! - getEntries().remove(idx); - removed = true; - } - - return removed; - } - @Override protected DataPage findDataPage(Entry entry) throws IOException @@ -286,6 +207,16 @@ public class SimpleIndex extends Index { _entries = entries; } + + @Override + public void addEntry(int idx, Entry entry) { + _entries.add(idx, entry); + } + + public void removeEntry(int idx) { + _entries.remove(idx); + } + } }