Преглед на файлове

flesh out some of the index page update operations

git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@313 f203690c-595d-4dc9-a70b-905162fa7fd2
tags/rel_1_1_14
James Ahlborn преди 16 години
родител
ревизия
095e6cc549
променени са 2 файла, в които са добавени 168 реда и са изтрити 57 реда
  1. 1
    1
      src/java/com/healthmarketscience/jackcess/Index.java
  2. 167
    56
      src/java/com/healthmarketscience/jackcess/IndexPageCache.java

+ 1
- 1
src/java/com/healthmarketscience/jackcess/Index.java Целия файл

@@ -1693,7 +1693,7 @@ public abstract class Index implements Comparable<Index> {
* Returns a copy of this entry as a node Entry with the given
* subPageNumber.
*/
Entry asNodeEntry(Integer subPageNumber) {
protected Entry asNodeEntry(Integer subPageNumber) {
return new NodeEntry(_entryBytes, _rowId, _type, subPageNumber);
}

+ 167
- 56
src/java/com/healthmarketscience/jackcess/IndexPageCache.java Целия файл

@@ -75,6 +75,8 @@ public class IndexPageCache

public void setRootPageNumber(int pageNumber) throws IOException {
_rootPage = getDataPage(pageNumber);
// root page has no parent
_rootPage.setParentPage(INVALID_INDEX_PAGE_NUMBER, false);
}
public void write()
@@ -105,6 +107,19 @@ public class IndexPageCache
DataPageMain main = getDataPage(pageNumber);
return((main != null) ? new CacheDataPage(main) : null);
}

private DataPageMain getChildDataPage(Integer childPageNumber,
DataPageMain parent,
boolean isTail)
throws IOException
{
DataPageMain child = getDataPage(childPageNumber);
if(child != null) {
// set the parent info for this child (if necessary)
child.setParentPage(parent._pageNumber, isTail);
}
return child;
}
private DataPageMain getDataPage(Integer pageNumber)
throws IOException
@@ -146,8 +161,8 @@ public class IndexPageCache
return cacheDataPage;
}

private void removeEntry(CacheDataPage cacheDataPage,
int entryIdx)
private void removeEntry(CacheDataPage cacheDataPage, int entryIdx)
throws IOException
{
DataPageMain dpMain = cacheDataPage._main;
DataPageExtra dpExtra = cacheDataPage._extra;
@@ -165,28 +180,10 @@ public class IndexPageCache
if(dpExtra._entries.isEmpty()) {
// this page is dead
if(dpMain.isRoot()) {
// clear out this page
dpMain._firstEntry = null;
dpMain._lastEntry = null;
dpExtra._entryPrefix = EMPTY_PREFIX;
if(dpExtra._totalEntrySize != 0) {
throw new IllegalStateException("Empty page but size is not 0?");
}
} else {
// FIXME, remove from parent
Entry oldParentEntry = oldEntry.asNodeEntry(dpMain._pageNumber);
// FIXME, update next/prev/childTail links
throw new UnsupportedOperationException();
}
deleteDataPage(cacheDataPage);
} else {
if(updateFirst) {
dpMain._firstEntry = dpExtra.getFirstEntry();
Entry oldParentEntry = oldEntry.asNodeEntry(dpMain._pageNumber);
Entry newParentEntry =
dpMain._firstEntry.asNodeEntry(dpMain._pageNumber);
// FIXME, need to update parent
throw new UnsupportedOperationException();
updateFirstEntry(cacheDataPage);
}
if(updateLast) {
dpMain._lastEntry = dpExtra.getLastEntry();
@@ -195,6 +192,120 @@ public class IndexPageCache
}

private void deleteDataPage(CacheDataPage cacheDataPage)
throws IOException
{
DataPageMain dpMain = cacheDataPage._main;
DataPageExtra dpExtra = cacheDataPage._extra;

if(dpMain.isRoot()) {
// clear out this page (we don't actually delete it)
dpMain._firstEntry = null;
dpMain._lastEntry = null;
dpExtra._entryPrefix = EMPTY_PREFIX;
if(dpExtra._totalEntrySize != 0) {
throw new IllegalStateException("Empty page but size is not 0? " +
cacheDataPage);
}
return;
}

// remove this page from it's parent page
removeFromParent(cacheDataPage);

// remove this page from any next/prev pages
removeFromPeers(cacheDataPage);

// FIXME, deallocate index page?
}

private void removeFromParent(CacheDataPage childDataPage)
throws IOException
{
DataPageMain childMain = childDataPage._main;
DataPageExtra childExtra = childDataPage._extra;

CacheDataPage parentDataPage =
new CacheDataPage(childMain.getParentPage());

setModified(parentDataPage);
DataPageMain parentMain = parentDataPage._main;
DataPageExtra parentExtra = parentDataPage._extra;

if(childMain.isTail()) {
parentMain._childTailPageNumber = INVALID_INDEX_PAGE_NUMBER;
} else {
Entry oldParentEntry = childMain._firstEntry.asNodeEntry(
childMain._pageNumber);
int idx = parentExtra.findEntry(oldParentEntry);
if(idx < 0) {
throw new IllegalStateException(
"Could not find child entry in parent; child " + childDataPage +
"; parent " + parentDataPage);
}
removeEntry(parentDataPage, idx);
}
}

private void removeFromPeers(CacheDataPage cacheDataPage)
throws IOException
{
DataPageMain dpMain = cacheDataPage._main;
DataPageExtra dpExtra = cacheDataPage._extra;

Integer prevPageNumber = dpMain._prevPageNumber;
Integer nextPageNumber = dpMain._nextPageNumber;
DataPageMain prevMain = dpMain.getPrevPage();
if(prevMain != null) {
setModified(new CacheDataPage(prevMain));
prevMain._nextPageNumber = nextPageNumber;
}

DataPageMain nextMain = dpMain.getNextPage();
if(nextMain != null) {
setModified(new CacheDataPage(nextMain));
nextMain._prevPageNumber = prevPageNumber;
}
}

private void updateFirstEntry(CacheDataPage cacheDataPage)
throws IOException
{
DataPageMain dpMain = cacheDataPage._main;
DataPageExtra dpExtra = cacheDataPage._extra;

Entry oldEntry = dpMain._firstEntry;
dpMain._firstEntry = dpExtra.getFirstEntry();
DataPageMain parentMain = dpMain.getParentPage();
if(parentMain != null) {
Entry oldParentEntry = oldEntry.asNodeEntry(dpMain._pageNumber);
Entry newParentEntry =
dpMain._firstEntry.asNodeEntry(dpMain._pageNumber);
updateParentEntry(new CacheDataPage(parentMain),
oldParentEntry, newParentEntry);
}
}
private void updateParentEntry(CacheDataPage parentDataPage,
Entry oldEntry, Entry newEntry)
throws IOException
{
DataPageMain parentMain = parentDataPage._main;
DataPageExtra parentExtra = parentDataPage._extra;

setModified(parentDataPage);

int idx = parentExtra.findEntry(oldEntry);
if(idx < 0) {
throw new IllegalStateException(
"Could not find child entry in parent; childEntry " + oldEntry +
"; parent " + parentDataPage);
}
replaceEntry(parentDataPage, idx, newEntry);
}
private void addEntry(CacheDataPage cacheDataPage,
int entryIdx,
Entry newEntry)
@@ -242,17 +353,7 @@ public class IndexPageCache
}
if(updateFirst) {
Entry oldFirstEntry = dpMain._firstEntry;
dpMain._firstEntry = newEntry;
if(!dpMain.isRoot()) {
// FIXME, handle null oldFirstEntry
Entry oldParentEntry = oldFirstEntry.asNodeEntry(
dpMain._pageNumber);
Entry newParentEntry =
dpMain._firstEntry.asNodeEntry(dpMain._pageNumber);
// FIXME, need to update parent
throw new UnsupportedOperationException();
}
updateFirstEntry(cacheDataPage);
}
if(updateLast) {
dpMain._lastEntry = newEntry;
@@ -281,7 +382,7 @@ public class IndexPageCache

// find first leaf
while(!curPage._leaf) {
curPage = getDataPage(curPage._firstEntry.getSubPageNumber());
curPage = curPage.getChildPage(curPage._firstEntry);
}
return new CacheDataPage(curPage);
@@ -294,7 +395,7 @@ public class IndexPageCache
(childTailPage.compareToPage(e) >= 0)) {
curPage = childTailPage;
} else {
curPage = getDataPage(curPage._lastEntry.getSubPageNumber());
curPage = curPage.getChildPage(curPage._lastEntry);
}
} else {
return new CacheDataPage(curPage);
@@ -322,7 +423,7 @@ public class IndexPageCache
}

Entry nodeEntry = extra._entries.get(idx);
curPage = getDataPage(nodeEntry.getSubPageNumber());
curPage = curPage.getChildPage(nodeEntry);
}
}
@@ -409,40 +510,48 @@ public class IndexPageCache
return(this == _rootPage);
}
public boolean isTail()
throws IOException
public boolean isTail() throws IOException
{
resolveParent();
return _tail;
}
public DataPageMain getParentPage()
throws IOException
public DataPageMain getParentPage() throws IOException
{
resolveParent();
return IndexPageCache.this.getDataPage(_parentPageNumber);
}

public void setParentPage(Integer parentPageNumber, boolean isTail) {
if(_parentPageNumber == null) {
_parentPageNumber = parentPageNumber;
_tail = isTail;
}
}
public DataPageMain getPrevPage()
throws IOException
public DataPageMain getPrevPage() throws IOException
{
return IndexPageCache.this.getDataPage(_prevPageNumber);
}
public DataPageMain getNextPage()
throws IOException
public DataPageMain getNextPage() throws IOException
{
return IndexPageCache.this.getDataPage(_nextPageNumber);
}
public DataPageMain getChildTailPage()
throws IOException
public DataPageMain getChildPage(Entry e) throws IOException
{
return IndexPageCache.this.getDataPage(_childTailPageNumber);
return IndexPageCache.this.getChildDataPage(
e.getSubPageNumber(), this, false);
}
public DataPageExtra getExtra()
throws IOException
public DataPageMain getChildTailPage() throws IOException
{
return IndexPageCache.this.getChildDataPage(
_childTailPageNumber, this, true);
}
public DataPageExtra getExtra() throws IOException
{
DataPageExtra extra = _extra.get();
if(extra == null) {
@@ -453,8 +562,7 @@ public class IndexPageCache
return extra;
}

public void setExtra(DataPageExtra extra, boolean isNew)
throws IOException
public void setExtra(DataPageExtra extra, boolean isNew) throws IOException
{

if(isNew) {
@@ -496,11 +604,14 @@ public class IndexPageCache
return _firstEntry.compareTo(other._firstEntry);
}

private void resolveParent() {
if((_parentPageNumber == null) && !isRoot()) {
// FIXME, writeme
// need to determine _parentPageNumber and _tail
throw new UnsupportedOperationException();
private void resolveParent() throws IOException {
if(_parentPageNumber == null) {
// the act of searching for the first entry should resolve any parent
// pages along the path
findCacheDataPage(_firstEntry);
if(_parentPageNumber == null) {
throw new IllegalStateException("Parent was not resolved");
}
}
}


Loading…
Отказ
Запис