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);
}
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;
}
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();
}
}
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();
}
}
}
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);
}
}
Aggregations