Search in sources :

Example 1 with BTree

use of jetbrains.exodus.tree.btree.BTree in project xodus by JetBrains.

the class MetaTree method create.

static Pair<MetaTree, Integer> create(@NotNull final EnvironmentImpl env) {
    final Log log = env.getLog();
    LogTip logTip = log.getTip();
    if (logTip.highAddress > EMPTY_LOG_BOUND) {
        Loggable rootLoggable = log.getLastLoggableOfType(DatabaseRoot.DATABASE_ROOT_TYPE);
        while (rootLoggable != null) {
            final DatabaseRoot dbRoot = new DatabaseRoot(rootLoggable);
            final long root = dbRoot.getAddress();
            if (dbRoot.isValid()) {
                try {
                    final LogTip updatedTip = log.setHighAddress(logTip, root + dbRoot.length());
                    final BTree metaTree = env.loadMetaTree(dbRoot.getRootAddress(), updatedTip);
                    if (metaTree != null) {
                        // try to traverse meta tree
                        cloneTree(metaTree);
                        return new Pair<>(new MetaTree(metaTree, root, updatedTip), dbRoot.getLastStructureId());
                    }
                    logTip = updatedTip;
                } catch (ExodusException e) {
                    logTip = log.getTip();
                    EnvironmentImpl.loggerError("Failed to recover to valid root" + LogUtil.getWrongAddressErrorMessage(dbRoot.getAddress(), env.getEnvironmentConfig().getLogFileSize()), e);
                // XD-449: try next database root if we failed to traverse whole MetaTree
                // TODO: this check should become obsolete after XD-334 is implemented
                }
            }
            // continue recovery
            rootLoggable = log.getLastLoggableOfTypeBefore(DatabaseRoot.DATABASE_ROOT_TYPE, root, logTip);
        }
        // "abnormal program termination", "blue screen of doom"
        // Something quite strange with the database: it is not empty, but no valid
        // root has found. We can't just reset the database and lose all the contents,
        // we should have a chance to investigate the case. So failing...
        // 
        // It's extremely likely the database was ciphered with different/unknown cipher parameters.
        log.close();
        throw new InvalidCipherParametersException();
    }
    // no roots found: the database is empty
    log.setHighAddress(logTip, 0);
    final ITree resultTree = getEmptyMetaTree(env);
    final long root;
    log.beginWrite();
    final LogTip createdTip;
    try {
        final long rootAddress = resultTree.getMutableCopy().save();
        root = log.write(DatabaseRoot.DATABASE_ROOT_TYPE, Loggable.NO_STRUCTURE_ID, DatabaseRoot.asByteIterable(rootAddress, EnvironmentImpl.META_TREE_ID));
        log.flush();
        createdTip = log.endWrite();
    } catch (Throwable t) {
        // rollback log state
        log.abortWrite();
        throw new ExodusException("Can't init meta tree in log", t);
    }
    return new Pair<>(new MetaTree(resultTree, root, createdTip), EnvironmentImpl.META_TREE_ID);
}
Also used : BTree(jetbrains.exodus.tree.btree.BTree) InvalidCipherParametersException(jetbrains.exodus.crypto.InvalidCipherParametersException) ExodusException(jetbrains.exodus.ExodusException) Pair(jetbrains.exodus.core.dataStructures.Pair)

Example 2 with BTree

use of jetbrains.exodus.tree.btree.BTree in project xodus by JetBrains.

the class StoreImpl method openImmutableTree.

ITree openImmutableTree(@NotNull final MetaTree metaTree) {
    final int structureId = getStructureId();
    final long upToDateRootAddress = metaTree.getRootAddress(structureId);
    final boolean hasDuplicates = metaInfo.hasDuplicates();
    final boolean treeIsEmpty = upToDateRootAddress == Loggable.NULL_ADDRESS;
    final Log log = environment.getLog();
    final ITree result;
    if (!metaInfo.isKeyPrefixing()) {
        final BTreeBalancePolicy balancePolicy = environment.getBTreeBalancePolicy();
        result = treeIsEmpty ? new BTreeEmpty(log, balancePolicy, hasDuplicates, structureId) : new BTree(log, balancePolicy, upToDateRootAddress, hasDuplicates, structureId);
    } else {
        if (treeIsEmpty) {
            result = new PatriciaTreeEmpty(log, structureId, hasDuplicates);
        } else {
            result = hasDuplicates ? new PatriciaTreeWithDuplicates(log, upToDateRootAddress, structureId) : new PatriciaTree(log, upToDateRootAddress, structureId);
        }
    }
    return result;
}
Also used : PatriciaTree(jetbrains.exodus.tree.patricia.PatriciaTree) BTreeBalancePolicy(jetbrains.exodus.tree.btree.BTreeBalancePolicy) Log(jetbrains.exodus.log.Log) BTree(jetbrains.exodus.tree.btree.BTree) BTreeEmpty(jetbrains.exodus.tree.btree.BTreeEmpty) ITree(jetbrains.exodus.tree.ITree) PatriciaTreeEmpty(jetbrains.exodus.tree.patricia.PatriciaTreeEmpty) PatriciaTreeWithDuplicates(jetbrains.exodus.tree.patricia.PatriciaTreeWithDuplicates)

Example 3 with BTree

use of jetbrains.exodus.tree.btree.BTree in project xodus by JetBrains.

the class StoreImpl method openImmutableTree.

ITree openImmutableTree(@NotNull final MetaTreeImpl metaTree) {
    final int structureId = getStructureId();
    final long upToDateRootAddress = metaTree.getRootAddress(structureId);
    final boolean hasDuplicates = metaInfo.hasDuplicates();
    final boolean treeIsEmpty = upToDateRootAddress == Loggable.NULL_ADDRESS;
    final Log log = environment.getLog();
    final ITree result;
    if (!metaInfo.isKeyPrefixing()) {
        final BTreeBalancePolicy balancePolicy = environment.getBTreeBalancePolicy();
        result = treeIsEmpty ? new BTreeEmpty(log, balancePolicy, hasDuplicates, structureId) : new BTree(log, balancePolicy, upToDateRootAddress, hasDuplicates, structureId);
    } else {
        if (treeIsEmpty) {
            result = new PatriciaTreeEmpty(log, structureId, hasDuplicates);
        } else {
            result = hasDuplicates ? new PatriciaTreeWithDuplicates(log, upToDateRootAddress, structureId) : new PatriciaTree(log, upToDateRootAddress, structureId);
        }
    }
    return result;
}
Also used : PatriciaTree(jetbrains.exodus.tree.patricia.PatriciaTree) BTreeBalancePolicy(jetbrains.exodus.tree.btree.BTreeBalancePolicy) Log(jetbrains.exodus.log.Log) BTree(jetbrains.exodus.tree.btree.BTree) BTreeEmpty(jetbrains.exodus.tree.btree.BTreeEmpty) ITree(jetbrains.exodus.tree.ITree) PatriciaTreeEmpty(jetbrains.exodus.tree.patricia.PatriciaTreeEmpty) PatriciaTreeWithDuplicates(jetbrains.exodus.tree.patricia.PatriciaTreeWithDuplicates)

Example 4 with BTree

use of jetbrains.exodus.tree.btree.BTree in project xodus by JetBrains.

the class MetaTreeImpl method create.

static Pair<MetaTreeImpl, Integer> create(@NotNull final EnvironmentImpl env) {
    final Log log = env.getLog();
    LogTip logTip = log.getTip();
    if (logTip.highAddress > EMPTY_LOG_BOUND) {
        Loggable rootLoggable = log.getLastLoggableOfType(DatabaseRoot.DATABASE_ROOT_TYPE);
        while (rootLoggable != null) {
            final long root = rootLoggable.getAddress();
            // work around XD-692: load database root in try-catch block
            DatabaseRoot dbRoot = null;
            try {
                dbRoot = new DatabaseRoot(rootLoggable);
            } catch (ExodusException e) {
                EnvironmentImpl.loggerError("Failed to load database root at " + rootLoggable.getAddress(), e);
            }
            if (dbRoot != null && dbRoot.isValid()) {
                try {
                    final LogTip updatedTip = log.setHighAddress(logTip, root + dbRoot.length());
                    final BTree metaTree = env.loadMetaTree(dbRoot.getRootAddress(), updatedTip);
                    if (metaTree != null) {
                        // try to traverse meta tree
                        cloneTree(metaTree);
                        // flush potential file truncation
                        log.sync();
                        return new Pair<>(new MetaTreeImpl(metaTree, root, updatedTip), dbRoot.getLastStructureId());
                    }
                    logTip = updatedTip;
                } catch (ExodusException e) {
                    logTip = log.getTip();
                    EnvironmentImpl.loggerError("Failed to recover to valid root" + LogUtil.getWrongAddressErrorMessage(dbRoot.getAddress(), env.getEnvironmentConfig().getLogFileSize() * 1024L), e);
                // XD-449: try next database root if we failed to traverse whole MetaTree
                // TODO: this check should become obsolete after XD-334 is implemented
                }
            }
            // continue recovery
            rootLoggable = log.getLastLoggableOfTypeBefore(DatabaseRoot.DATABASE_ROOT_TYPE, root, logTip);
        }
        // "abnormal program termination", "blue screen of doom"
        // Something quite strange with the database: it is not empty, but no valid
        // root has found. We can't just reset the database and lose all the contents,
        // we should have a chance to investigate the case. So failing...
        // 
        // It's extremely likely the database was ciphered with different/unknown cipher parameters.
        log.close();
        throw new InvalidCipherParametersException();
    }
    // no roots found: the database is empty
    EnvironmentImpl.loggerDebug("No roots found: the database is empty");
    logTip = log.setHighAddress(logTip, 0);
    final ITree resultTree = getEmptyMetaTree(env);
    final long root;
    log.beginWrite();
    final LogTip createdTip;
    try {
        final long rootAddress = resultTree.getMutableCopy().save();
        root = log.write(DatabaseRoot.DATABASE_ROOT_TYPE, Loggable.NO_STRUCTURE_ID, DatabaseRoot.asByteIterable(rootAddress, EnvironmentImpl.META_TREE_ID));
        log.flush();
        createdTip = log.endWrite();
    } catch (Throwable t) {
        log.revertWrite(logTip);
        throw new ExodusException("Can't init meta tree in log", t);
    }
    return new Pair<>(new MetaTreeImpl(resultTree, root, createdTip), EnvironmentImpl.META_TREE_ID);
}
Also used : BTree(jetbrains.exodus.tree.btree.BTree) InvalidCipherParametersException(jetbrains.exodus.crypto.InvalidCipherParametersException) ExodusException(jetbrains.exodus.ExodusException) Pair(jetbrains.exodus.core.dataStructures.Pair)

Aggregations

BTree (jetbrains.exodus.tree.btree.BTree)4 ExodusException (jetbrains.exodus.ExodusException)2 Pair (jetbrains.exodus.core.dataStructures.Pair)2 InvalidCipherParametersException (jetbrains.exodus.crypto.InvalidCipherParametersException)2 Log (jetbrains.exodus.log.Log)2 ITree (jetbrains.exodus.tree.ITree)2 BTreeBalancePolicy (jetbrains.exodus.tree.btree.BTreeBalancePolicy)2 BTreeEmpty (jetbrains.exodus.tree.btree.BTreeEmpty)2 PatriciaTree (jetbrains.exodus.tree.patricia.PatriciaTree)2 PatriciaTreeEmpty (jetbrains.exodus.tree.patricia.PatriciaTreeEmpty)2 PatriciaTreeWithDuplicates (jetbrains.exodus.tree.patricia.PatriciaTreeWithDuplicates)2