001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (http://h2database.com/html/license.html).
004: * Initial Developer: H2 Group
005: */
006: package org.h2.index;
007:
008: import java.sql.SQLException;
009:
010: import org.h2.engine.Session;
011: import org.h2.result.Row;
012: import org.h2.result.SearchRow;
013: import org.h2.store.DataPage;
014: import org.h2.store.DiskFile;
015: import org.h2.store.Record;
016: import org.h2.table.Column;
017: import org.h2.util.ObjectArray;
018: import org.h2.value.Value;
019:
020: /**
021: * An abstract b-tree page.
022: */
023: public abstract class BtreePage extends Record {
024: // TODO btree: make sure the indexed data is at most half this size!
025: // (and find a solution to work around this problem!)
026: // TODO memory: the btree page needs a lot of memory (in the cache) -
027: // probably better not use ObjectArray but array;
028: // not Row but ValueList / Value (for single key index), int array for row
029: // pos
030:
031: protected static final int BLOCKS_PER_PAGE = 1024 / DiskFile.BLOCK_SIZE;
032:
033: protected BtreeIndex index;
034: protected ObjectArray pageData;
035: protected boolean root;
036:
037: /**
038: * Add a row to the index.
039: *
040: * @param row the row
041: * @param session the session
042: * @return the split point of this page, or 0 if no split is required
043: */
044: abstract int add(Row row, Session session) throws SQLException;
045:
046: /**
047: * Remove a row from the page.
048: *
049: * @param session the session
050: * @param row the row
051: * @return the new first row in the list; null if no change; the deleted row
052: * if not empty
053: */
054: abstract SearchRow remove(Session session, Row row)
055: throws SQLException;
056:
057: abstract BtreePage split(Session session, int splitPoint)
058: throws SQLException;
059:
060: abstract boolean findFirst(BtreeCursor cursor, SearchRow row,
061: boolean bigger) throws SQLException;
062:
063: abstract SearchRow getFirst(Session session) throws SQLException;
064:
065: abstract SearchRow getLast(Session session) throws SQLException;
066:
067: abstract void next(BtreeCursor cursor, int i) throws SQLException;
068:
069: abstract void first(BtreeCursor cursor) throws SQLException;
070:
071: abstract int getRealByteCount() throws SQLException;
072:
073: BtreePage(BtreeIndex index) {
074: this .index = index;
075: }
076:
077: SearchRow getData(int i) throws SQLException {
078: return (SearchRow) pageData.get(i);
079: }
080:
081: public int getByteCount(DataPage dummy) throws SQLException {
082: return DiskFile.BLOCK_SIZE * BLOCKS_PER_PAGE;
083: }
084:
085: int getSplitPoint() throws SQLException {
086: if (pageData.size() == 1) {
087: return 0;
088: }
089: int size = getRealByteCount();
090: if (size >= DiskFile.BLOCK_SIZE * BLOCKS_PER_PAGE) {
091: return pageData.size() / 2;
092: }
093: return 0;
094: }
095:
096: public boolean isEmpty() {
097: return false;
098: }
099:
100: int getRowSize(DataPage dummy, SearchRow row) throws SQLException {
101: int rowsize = dummy.getIntLen();
102: Column[] columns = index.getColumns();
103: for (int j = 0; j < columns.length; j++) {
104: Value v = row.getValue(columns[j].getColumnId());
105: rowsize += dummy.getValueLen(v);
106: }
107: return rowsize;
108: }
109:
110: void setRoot(boolean root) {
111: this .root = root;
112: }
113:
114: public boolean isPinned() {
115: return root;
116: }
117:
118: }
|