Search in sources :

Example 6 with ExodusException

use of jetbrains.exodus.ExodusException 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 7 with ExodusException

use of jetbrains.exodus.ExodusException in project xodus by JetBrains.

the class ReadWriteTransaction method getMutableTree.

@NotNull
ITreeMutable getMutableTree(@NotNull final StoreImpl store) {
    checkIsFinished();
    final Thread creatingThread = getCreatingThread();
    if (!creatingThread.equals(Thread.currentThread())) {
        throw new ExodusException("Can't create mutable tree in a thread different from the one which transaction was created in");
    }
    final int structureId = store.getStructureId();
    ITreeMutable result = mutableTrees.get(structureId);
    if (result == null) {
        result = getTree(store).getMutableCopy();
        mutableTrees.put(structureId, result);
    }
    return result;
}
Also used : ITreeMutable(jetbrains.exodus.tree.ITreeMutable) ExodusException(jetbrains.exodus.ExodusException) NotNull(org.jetbrains.annotations.NotNull)

Example 8 with ExodusException

use of jetbrains.exodus.ExodusException in project xodus by JetBrains.

the class ReentrantTransactionDispatcher method releaseTransaction.

/**
 * Release transaction that was acquired in a thread with specified permits.
 */
void releaseTransaction(@NotNull final Thread thread, final int permits) {
    try (CriticalSection ignored = criticalSection.enter()) {
        int currentThreadPermits = getThreadPermits(thread);
        if (permits > currentThreadPermits) {
            throw new ExodusException("Can't release more permits than it was acquired");
        }
        acquiredPermits -= permits;
        currentThreadPermits -= permits;
        if (currentThreadPermits == 0) {
            threadPermits.remove(thread);
        } else {
            threadPermits.put(thread, currentThreadPermits);
        }
        notifyNextWaiters();
    }
}
Also used : CriticalSection(jetbrains.exodus.core.execution.locks.CriticalSection) ExodusException(jetbrains.exodus.ExodusException)

Example 9 with ExodusException

use of jetbrains.exodus.ExodusException in project xodus by JetBrains.

the class ReentrantTransactionDispatcher method downgradeTransaction.

/**
 * Downgrade transaction (making it holding only 1 permit) that was acquired in a thread with specified permits.
 */
void downgradeTransaction(@NotNull final Thread thread, final int permits) {
    if (permits > 1) {
        try (CriticalSection ignored = criticalSection.enter()) {
            int currentThreadPermits = getThreadPermits(thread);
            if (permits > currentThreadPermits) {
                throw new ExodusException("Can't release more permits than it was acquired");
            }
            acquiredPermits -= (permits - 1);
            currentThreadPermits -= (permits - 1);
            threadPermits.put(thread, currentThreadPermits);
            notifyNextWaiters();
        }
    }
}
Also used : CriticalSection(jetbrains.exodus.core.execution.locks.CriticalSection) ExodusException(jetbrains.exodus.ExodusException)

Example 10 with ExodusException

use of jetbrains.exodus.ExodusException in project meghanada-server by mopemope.

the class ProjectDatabase method open.

private void open() {
    try {
        if (isNull(this.environment)) {
            Config config = Config.load();
            String dir = config.getProjectSettingDir();
            File root = new File(dir);
            if (!config.isCacheInProject()) {
                String cacheRoot = config.getCacheRoot();
                root = new File(cacheRoot);
            }
            if (root.exists() && root.isFile()) {
                root = root.getParentFile();
            }
            if (!root.exists() && !root.mkdirs()) {
                log.warn("{} mkdirs fail", root);
            }
            String rootDir = Config.getProjectRoot();
            String name = new File(rootDir).getName();
            String hash = Hashing.sha256().newHasher().putString(Main.getVersion(), StandardCharsets.UTF_8).putString(config.getJavaVersion(), StandardCharsets.UTF_8).putString(config.getJavaHomeDir(), StandardCharsets.UTF_8).putString(dir, StandardCharsets.UTF_8).hash().toString();
            File base = new File(root, name + '_' + hash.substring(0, 16));
            File[] files = root.listFiles();
            if (nonNull(files)) {
                for (File file : files) {
                    if (file.isDirectory() && file.getName().startsWith(name) && !file.equals(base)) {
                        org.apache.commons.io.FileUtils.deleteDirectory(file);
                    }
                }
            }
            try {
                this.environment = Environments.newInstance(base);
            } catch (ExodusException ex) {
                // try re-create
                org.apache.commons.io.FileUtils.deleteDirectory(base);
                this.environment = Environments.newInstance(base);
            }
            this.entityStore = PersistentEntityStores.newInstance(environment, STORE_NAME);
            String location = this.environment.getLocation();
            String projectRoot = Config.getProjectRoot();
            this.projectRoot = projectRoot;
            log.debug("open project database {}", location);
        }
    } catch (IOException e) {
        throw new UncheckedIOException(e);
    }
}
Also used : Config(meghanada.config.Config) UncheckedIOException(java.io.UncheckedIOException) IOException(java.io.IOException) UncheckedIOException(java.io.UncheckedIOException) File(java.io.File) ExodusException(jetbrains.exodus.ExodusException)

Aggregations

ExodusException (jetbrains.exodus.ExodusException)21 File (java.io.File)6 IOException (java.io.IOException)6 RandomAccessFile (java.io.RandomAccessFile)3 CriticalSection (jetbrains.exodus.core.execution.locks.CriticalSection)3 ByteIterable (jetbrains.exodus.ByteIterable)2 CompoundByteIterable (jetbrains.exodus.CompoundByteIterable)2 Job (jetbrains.exodus.core.execution.Job)2 EnvironmentImpl (jetbrains.exodus.env.EnvironmentImpl)2 FileDataReader (jetbrains.exodus.io.FileDataReader)2 FileDataWriter (jetbrains.exodus.io.FileDataWriter)2 SharedRandomAccessFile (jetbrains.exodus.util.SharedRandomAccessFile)2 UncheckedIOException (java.io.UncheckedIOException)1 ClosedChannelException (java.nio.channels.ClosedChannelException)1 FileChannel (java.nio.channels.FileChannel)1 Map (java.util.Map)1 Condition (java.util.concurrent.locks.Condition)1 Pair (jetbrains.exodus.core.dataStructures.Pair)1 LongHashMap (jetbrains.exodus.core.dataStructures.hash.LongHashMap)1 LongSet (jetbrains.exodus.core.dataStructures.hash.LongSet)1