for(Iterator<CacheDataPage> iter = _modifiedPages.iterator();
iter.hasNext(); ) {
CacheDataPage cacheDataPage = iter.next();
- if(cacheDataPage.isEmpty()) {
+ if(cacheDataPage._extra._entryView.isEmpty()) {
if(!cacheDataPage._main.isRoot()) {
deleteDataPage(cacheDataPage);
} else {
private void writeDataPages() throws IOException
{
for(CacheDataPage cacheDataPage : _modifiedPages) {
- if(cacheDataPage.isEmpty()) {
+ if(cacheDataPage._extra._entryView.isEmpty()) {
throw new IllegalStateException("Unexpected empty page " +
cacheDataPage);
}
// there's only one entry on the page, and it's the tail. make it a
// normal entry
DataPageMain dpMain = cacheDataPage._main;
+ DataPageExtra dpExtra = cacheDataPage._extra;
DataPageMain tailMain = dpMain.getChildTailPage();
CacheDataPage tailDataPage = new CacheDataPage(tailMain);
- removeParentEntry(tailDataPage);
+
+ // note, we can't just call removeParentEntry here cause that will attempt
+ // to delete the parent page (since it would be empty), so we have to
+ // remove the parent entry manually
+ updateParentTail(cacheDataPage, tailDataPage, UpdateType.REMOVE);
+ dpExtra._entryView.clear();
tailMain.setParentPage(dpMain._pageNumber, false);
int childTailPageNumber = dpMain._childTailPageNumber;
if(dpMain._leaf) {
if(childTailPageNumber != INVALID_INDEX_PAGE_NUMBER) {
- throw new IllegalStateException("Leaf page has tail");
+ throw new IllegalStateException("Leaf page has tail " + dpMain);
}
return;
}
+ if((dpExtra._entryView.size() == 1) && dpMain.hasChildTail()) {
+ throw new IllegalStateException("Single child is tail " + dpMain);
+ }
for(Entry e : dpExtra._entryView) {
validateEntryForPage(dpMain, e);
Integer subPageNumber = e.getSubPageNumber();
_extra = extra;
}
+ private List<Entry> getEntries() {
+ return _extra._entries;
+ }
+
@Override
public int size() {
- int size = _extra._entries.size();
+ int size = getEntries().size();
if(hasChildTail()) {
++size;
}
public Entry get(int idx) {
return (isCurrentChildTailIndex(idx) ?
_childTailEntry :
- _extra._entries.get(idx));
+ getEntries().get(idx));
}
@Override
public Entry set(int idx, Entry newEntry) {
return (isCurrentChildTailIndex(idx) ?
setChildTailEntry(newEntry) :
- _extra._entries.set(idx, newEntry));
+ getEntries().set(idx, newEntry));
}
@Override
if(isNewChildTailIndex(idx)) {
setChildTailEntry(newEntry);
} else {
- _extra._entries.add(idx, newEntry);
+ getEntries().add(idx, newEntry);
}
}
public Entry remove(int idx) {
return (isCurrentChildTailIndex(idx) ?
setChildTailEntry(null) :
- _extra._entries.remove(idx));
+ getEntries().remove(idx));
}
+ @Override
+ public void clear() {
+ getEntries().clear();
+ _childTailEntry = null;
+ }
+
public Entry setChildTailEntry(Entry newEntry) {
Entry old = _childTailEntry;
_childTailEntry = newEntry;
}
private boolean isCurrentChildTailIndex(int idx) {
- return(idx == _extra._entries.size());
+ return(idx == getEntries().size());
}
private boolean isNewChildTailIndex(int idx) {
- return(idx == (_extra._entries.size() + 1));
+ return(idx == (getEntries().size() + 1));
}
public Entry getLast() {
return(hasChildTail() ? _childTailEntry :
- (!_extra._entries.isEmpty() ?
- _extra._entries.get(_extra._entries.size() - 1) : null));
+ (!getEntries().isEmpty() ?
+ getEntries().get(getEntries().size() - 1) : null));
}
public int find(Entry e) {
System.out.println("BigIndexTest: Index type: " + index.getClass());
- // add 10,000 (pseudo) random entries to the table
+ // add 2,000 (pseudo) random entries to the table
Random rand = new Random(13L);
for(int i = 0; i < 2000; ++i) {
int nextInt = rand.nextInt(Integer.MAX_VALUE);
assertFalse(cursor.moveToNextRow());
assertFalse(cursor.moveToPreviousRow());
+ ((BigIndex)index).validate();
+
+ // add 50 (pseudo) random entries to the table
+ rand = new Random(42L);
+ for(int i = 0; i < 50; ++i) {
+ int nextInt = rand.nextInt(Integer.MAX_VALUE);
+ String nextVal = "" + nextInt + extraText;
+ if(((i + 1) % 3333) == 0) {
+ nextVal = null;
+ }
+ t.addRow(nextVal, "this is some row data " + nextInt);
+ }
+
+ ((BigIndex)index).validate();
+
+ cursor = Cursor.createIndexCursor(t, index);
+ while(cursor.moveToNextRow()) {
+ cursor.deleteCurrentRow();
+ }
+
((BigIndex)index).validate();
db.close();