Search in sources :

Example 1 with PageIndex

use of org.h2.index.PageIndex in project h2database by h2database.

the class PageStore method getPage.

/**
 * Read a page from the store.
 *
 * @param pageId the page id
 * @return the page
 */
public synchronized Page getPage(int pageId) {
    Page p = (Page) cache.get(pageId);
    if (p != null) {
        return p;
    }
    Data data = createData();
    readPage(pageId, data);
    int type = data.readByte();
    if (type == Page.TYPE_EMPTY) {
        return null;
    }
    data.readShortInt();
    data.readInt();
    if (!checksumTest(data.getBytes(), pageId, pageSize)) {
        throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "wrong checksum");
    }
    switch(type & ~Page.FLAG_LAST) {
        case Page.TYPE_FREE_LIST:
            p = PageFreeList.read(this, data, pageId);
            break;
        case Page.TYPE_DATA_LEAF:
            {
                int indexId = data.readVarInt();
                PageIndex idx = metaObjects.get(indexId);
                if (idx == null) {
                    throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "index not found " + indexId);
                }
                if (!(idx instanceof PageDataIndex)) {
                    throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "not a data index " + indexId + " " + idx);
                }
                PageDataIndex index = (PageDataIndex) idx;
                if (statistics != null) {
                    statisticsIncrement(index.getTable().getName() + "." + index.getName() + " read");
                }
                p = PageDataLeaf.read(index, data, pageId);
                break;
            }
        case Page.TYPE_DATA_NODE:
            {
                int indexId = data.readVarInt();
                PageIndex idx = metaObjects.get(indexId);
                if (idx == null) {
                    throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "index not found " + indexId);
                }
                if (!(idx instanceof PageDataIndex)) {
                    throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "not a data index " + indexId + " " + idx);
                }
                PageDataIndex index = (PageDataIndex) idx;
                if (statistics != null) {
                    statisticsIncrement(index.getTable().getName() + "." + index.getName() + " read");
                }
                p = PageDataNode.read(index, data, pageId);
                break;
            }
        case Page.TYPE_DATA_OVERFLOW:
            {
                p = PageDataOverflow.read(this, data, pageId);
                if (statistics != null) {
                    statisticsIncrement("overflow read");
                }
                break;
            }
        case Page.TYPE_BTREE_LEAF:
            {
                int indexId = data.readVarInt();
                PageIndex idx = metaObjects.get(indexId);
                if (idx == null) {
                    throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "index not found " + indexId);
                }
                if (!(idx instanceof PageBtreeIndex)) {
                    throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "not a btree index " + indexId + " " + idx);
                }
                PageBtreeIndex index = (PageBtreeIndex) idx;
                if (statistics != null) {
                    statisticsIncrement(index.getTable().getName() + "." + index.getName() + " read");
                }
                p = PageBtreeLeaf.read(index, data, pageId);
                break;
            }
        case Page.TYPE_BTREE_NODE:
            {
                int indexId = data.readVarInt();
                PageIndex idx = metaObjects.get(indexId);
                if (idx == null) {
                    throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "index not found " + indexId);
                }
                if (!(idx instanceof PageBtreeIndex)) {
                    throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "not a btree index " + indexId + " " + idx);
                }
                PageBtreeIndex index = (PageBtreeIndex) idx;
                if (statistics != null) {
                    statisticsIncrement(index.getTable().getName() + "." + index.getName() + " read");
                }
                p = PageBtreeNode.read(index, data, pageId);
                break;
            }
        case Page.TYPE_STREAM_TRUNK:
            p = PageStreamTrunk.read(this, data, pageId);
            break;
        case Page.TYPE_STREAM_DATA:
            p = PageStreamData.read(this, data, pageId);
            break;
        default:
            throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "page=" + pageId + " type=" + type);
    }
    cache.put(p);
    return p;
}
Also used : PageDataIndex(org.h2.index.PageDataIndex) PageBtreeIndex(org.h2.index.PageBtreeIndex) CreateTableData(org.h2.command.ddl.CreateTableData) PageIndex(org.h2.index.PageIndex)

Example 2 with PageIndex

use of org.h2.index.PageIndex in project h2database by h2database.

the class PageStore method addMeta.

private void addMeta(Row row, Session session, boolean redo) {
    int id = row.getValue(0).getInt();
    int type = row.getValue(1).getInt();
    int parent = row.getValue(2).getInt();
    int rootPageId = row.getValue(3).getInt();
    String[] options = StringUtils.arraySplit(row.getValue(4).getString(), ',', false);
    String columnList = row.getValue(5).getString();
    String[] columns = StringUtils.arraySplit(columnList, ',', false);
    Index meta;
    if (trace.isDebugEnabled()) {
        trace.debug("addMeta id=" + id + " type=" + type + " root=" + rootPageId + " parent=" + parent + " columns=" + columnList);
    }
    if (redo && rootPageId != 0) {
        // ensure the page is empty, but not used by regular data
        writePage(rootPageId, createData());
        allocatePage(rootPageId);
    }
    metaRootPageId.put(id, rootPageId);
    if (type == META_TYPE_DATA_INDEX) {
        CreateTableData data = new CreateTableData();
        if (SysProperties.CHECK) {
            if (columns == null) {
                throw DbException.throwInternalError(row.toString());
            }
        }
        for (int i = 0, len = columns.length; i < len; i++) {
            Column col = new Column("C" + i, Value.INT);
            data.columns.add(col);
        }
        data.schema = metaSchema;
        data.tableName = "T" + id;
        data.id = id;
        data.temporary = options[2].equals("temp");
        data.persistData = true;
        data.persistIndexes = true;
        data.create = false;
        data.session = session;
        RegularTable table = new RegularTable(data);
        boolean binaryUnsigned = SysProperties.SORT_BINARY_UNSIGNED;
        if (options.length > 3) {
            binaryUnsigned = Boolean.parseBoolean(options[3]);
        }
        CompareMode mode = CompareMode.getInstance(options[0], Integer.parseInt(options[1]), binaryUnsigned);
        table.setCompareMode(mode);
        meta = table.getScanIndex(session);
    } else {
        Index p = metaObjects.get(parent);
        if (p == null) {
            throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "Table not found:" + parent + " for " + row + " meta:" + metaObjects);
        }
        RegularTable table = (RegularTable) p.getTable();
        Column[] tableCols = table.getColumns();
        int len = columns.length;
        IndexColumn[] cols = new IndexColumn[len];
        for (int i = 0; i < len; i++) {
            String c = columns[i];
            IndexColumn ic = new IndexColumn();
            int idx = c.indexOf('/');
            if (idx >= 0) {
                String s = c.substring(idx + 1);
                ic.sortType = Integer.parseInt(s);
                c = c.substring(0, idx);
            }
            ic.column = tableCols[Integer.parseInt(c)];
            cols[i] = ic;
        }
        IndexType indexType;
        if (options[3].equals("d")) {
            indexType = IndexType.createPrimaryKey(true, false);
            Column[] tableColumns = table.getColumns();
            for (IndexColumn indexColumn : cols) {
                tableColumns[indexColumn.column.getColumnId()].setNullable(false);
            }
        } else {
            indexType = IndexType.createNonUnique(true);
        }
        meta = table.addIndex(session, "I" + id, id, cols, indexType, false, null);
    }
    PageIndex index;
    if (meta instanceof MultiVersionIndex) {
        index = (PageIndex) ((MultiVersionIndex) meta).getBaseIndex();
    } else {
        index = (PageIndex) meta;
    }
    metaObjects.put(id, index);
}
Also used : Index(org.h2.index.Index) PageIndex(org.h2.index.PageIndex) PageDelegateIndex(org.h2.index.PageDelegateIndex) MultiVersionIndex(org.h2.index.MultiVersionIndex) PageBtreeIndex(org.h2.index.PageBtreeIndex) PageDataIndex(org.h2.index.PageDataIndex) ValueString(org.h2.value.ValueString) PageIndex(org.h2.index.PageIndex) CreateTableData(org.h2.command.ddl.CreateTableData) IndexColumn(org.h2.table.IndexColumn) IndexColumn(org.h2.table.IndexColumn) Column(org.h2.table.Column) MultiVersionIndex(org.h2.index.MultiVersionIndex) RegularTable(org.h2.table.RegularTable) CompareMode(org.h2.value.CompareMode) IndexType(org.h2.index.IndexType)

Example 3 with PageIndex

use of org.h2.index.PageIndex in project h2database by h2database.

the class PageStore method addMeta.

/**
 * Add the meta data of an index.
 *
 * @param index the index to add
 * @param session the session
 */
public void addMeta(PageIndex index, Session session) {
    Table table = index.getTable();
    if (SysProperties.CHECK) {
        if (!table.isTemporary()) {
            // the Database lock before we take the PageStore lock
            synchronized (database) {
                synchronized (this) {
                    database.verifyMetaLocked(session);
                }
            }
        }
    }
    synchronized (this) {
        int type = index instanceof PageDataIndex ? META_TYPE_DATA_INDEX : META_TYPE_BTREE_INDEX;
        IndexColumn[] columns = index.getIndexColumns();
        StatementBuilder buff = new StatementBuilder();
        for (IndexColumn col : columns) {
            buff.appendExceptFirst(",");
            int id = col.column.getColumnId();
            buff.append(id);
            int sortType = col.sortType;
            if (sortType != 0) {
                buff.append('/');
                buff.append(sortType);
            }
        }
        String columnList = buff.toString();
        CompareMode mode = table.getCompareMode();
        String options = mode.getName() + "," + mode.getStrength() + ",";
        if (table.isTemporary()) {
            options += "temp";
        }
        options += ",";
        if (index instanceof PageDelegateIndex) {
            options += "d";
        }
        options += "," + mode.isBinaryUnsigned();
        Row row = metaTable.getTemplateRow();
        row.setValue(0, ValueInt.get(index.getId()));
        row.setValue(1, ValueInt.get(type));
        row.setValue(2, ValueInt.get(table.getId()));
        row.setValue(3, ValueInt.get(index.getRootPageId()));
        row.setValue(4, ValueString.get(options));
        row.setValue(5, ValueString.get(columnList));
        row.setKey(index.getId() + 1);
        metaIndex.add(session, row);
    }
}
Also used : RegularTable(org.h2.table.RegularTable) Table(org.h2.table.Table) PageDelegateIndex(org.h2.index.PageDelegateIndex) PageDataIndex(org.h2.index.PageDataIndex) StatementBuilder(org.h2.util.StatementBuilder) CompareMode(org.h2.value.CompareMode) ValueString(org.h2.value.ValueString) Row(org.h2.result.Row) IndexColumn(org.h2.table.IndexColumn)

Example 4 with PageIndex

use of org.h2.index.PageIndex in project h2database by h2database.

the class PageStore method recover.

/**
 * Run recovery.
 *
 * @return whether the transaction log was empty
 */
private boolean recover() {
    trace.debug("log recover");
    recoveryRunning = true;
    boolean isEmpty = true;
    isEmpty &= log.recover(PageLog.RECOVERY_STAGE_UNDO);
    if (reservedPages != null) {
        for (int r : reservedPages.keySet()) {
            if (trace.isDebugEnabled()) {
                trace.debug("reserve " + r);
            }
            allocatePage(r);
        }
    }
    isEmpty &= log.recover(PageLog.RECOVERY_STAGE_ALLOCATE);
    openMetaIndex();
    readMetaData();
    isEmpty &= log.recover(PageLog.RECOVERY_STAGE_REDO);
    boolean setReadOnly = false;
    if (!database.isReadOnly()) {
        if (log.getInDoubtTransactions().isEmpty()) {
            log.recoverEnd();
            int firstUncommittedSection = getFirstUncommittedSection();
            log.removeUntil(firstUncommittedSection);
        } else {
            setReadOnly = true;
        }
    }
    PageDataIndex systemTable = (PageDataIndex) metaObjects.get(0);
    isNew = systemTable == null;
    for (PageIndex index : metaObjects.values()) {
        if (index.getTable().isTemporary()) {
            // temporary indexes are removed after opening
            if (tempObjects == null) {
                tempObjects = new HashMap<>();
            }
            tempObjects.put(index.getId(), index);
        } else {
            index.close(pageStoreSession);
        }
    }
    allocatePage(PAGE_ID_META_ROOT);
    writeIndexRowCounts();
    recoveryRunning = false;
    reservedPages = null;
    writeBack();
    // clear the cache because it contains pages with closed indexes
    cache.clear();
    freeLists.clear();
    metaObjects.clear();
    metaObjects.put(-1, metaIndex);
    if (setReadOnly) {
        database.setReadOnly(true);
    }
    trace.debug("log recover done");
    return isEmpty;
}
Also used : PageDataIndex(org.h2.index.PageDataIndex) PageIndex(org.h2.index.PageIndex)

Example 5 with PageIndex

use of org.h2.index.PageIndex in project h2database by h2database.

the class PageStore method removeMeta.

private void removeMeta(Row row) {
    int id = row.getValue(0).getInt();
    PageIndex index = metaObjects.get(id);
    index.getTable().removeIndex(index);
    if (index instanceof PageBtreeIndex || index instanceof PageDelegateIndex) {
        if (index.isTemporary()) {
            pageStoreSession.removeLocalTempTableIndex(index);
        } else {
            index.getSchema().remove(index);
        }
    }
    index.remove(pageStoreSession);
    metaObjects.remove(id);
}
Also used : PageDelegateIndex(org.h2.index.PageDelegateIndex) PageBtreeIndex(org.h2.index.PageBtreeIndex) PageIndex(org.h2.index.PageIndex)

Aggregations

PageIndex (org.h2.index.PageIndex)5 PageDataIndex (org.h2.index.PageDataIndex)4 PageBtreeIndex (org.h2.index.PageBtreeIndex)3 PageDelegateIndex (org.h2.index.PageDelegateIndex)3 CreateTableData (org.h2.command.ddl.CreateTableData)2 IndexColumn (org.h2.table.IndexColumn)2 RegularTable (org.h2.table.RegularTable)2 CompareMode (org.h2.value.CompareMode)2 ValueString (org.h2.value.ValueString)2 Index (org.h2.index.Index)1 IndexType (org.h2.index.IndexType)1 MultiVersionIndex (org.h2.index.MultiVersionIndex)1 Row (org.h2.result.Row)1 Column (org.h2.table.Column)1 Table (org.h2.table.Table)1 StatementBuilder (org.h2.util.StatementBuilder)1