X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.acorn%2Fsrc%2Forg%2Fsimantics%2Facorn%2FClusterManager.java;h=40c5de37e8c1991e6e5ce846e2b90e7b651b6c5e;hb=32db32b8c6f1f0feba6905c3c68579f6b5891821;hp=22629d4e64237ab63c6fc89a12f0754087254edb;hpb=d09be9d2b8bf2e982ab7cf5760d39014e7ca4fa1;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.acorn/src/org/simantics/acorn/ClusterManager.java b/bundles/org.simantics.acorn/src/org/simantics/acorn/ClusterManager.java index 22629d4e6..40c5de37e 100644 --- a/bundles/org.simantics.acorn/src/org/simantics/acorn/ClusterManager.java +++ b/bundles/org.simantics.acorn/src/org/simantics/acorn/ClusterManager.java @@ -2,9 +2,11 @@ package org.simantics.acorn; import java.io.IOException; import java.math.BigInteger; +import java.nio.file.CopyOption; import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.StandardCopyOption; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -22,6 +24,7 @@ import org.simantics.acorn.lru.ClusterLRU; import org.simantics.acorn.lru.ClusterStreamChunk; import org.simantics.acorn.lru.FileInfo; import org.simantics.acorn.lru.LRU; +import org.simantics.databoard.file.RuntimeIOException; import org.simantics.db.ClusterCreator; import org.simantics.db.Database.Session.ClusterIds; import org.simantics.db.Database.Session.ResourceSegment; @@ -33,6 +36,7 @@ import org.simantics.db.impl.ClusterSupport; import org.simantics.db.procore.cluster.ClusterTraits; import org.simantics.db.service.ClusterSetsSupport; import org.simantics.db.service.ClusterUID; +import org.simantics.utils.FileUtils; import org.simantics.utils.threads.logger.ITask; import org.simantics.utils.threads.logger.ThreadLogger; import org.slf4j.Logger; @@ -134,6 +138,119 @@ public class ClusterManager { private AtomicBoolean safeToMakeSnapshot = new AtomicBoolean(true); private IllegalAcornStateException cause; + public synchronized void purge(ServiceLocator locator) throws IllegalAcornStateException { + + try { + + // Schedule writing of all data to disk + refreshHeadState(); + // Wait for files to be written + synchronizeWorkingDirectory(); + + String currentDir = workingDirectory.getFileName().toString(); + Path baseline = workingDirectory.resolveSibling(currentDir + "_baseline"); + + Files.createDirectories(baseline); + + for(String clusterKey : state.clusters) { + String[] parts1 = clusterKey.split("#"); + String[] parts = parts1[0].split("\\."); + String readDirName = parts1[1]; + if(!readDirName.equals(currentDir)) { + String fileName = parts[0] + "." + parts[1] + ".cluster"; + Path from = dbFolder.resolve(readDirName).resolve(fileName); + Path to = baseline.resolve(fileName); + System.err.println("purge copies " + from + " => " + to); + Files.copy(from, to, StandardCopyOption.COPY_ATTRIBUTES); + long first = new BigInteger(parts[0], 16).longValue(); + long second = new BigInteger(parts[1], 16).longValue(); + ClusterUID uuid = ClusterUID.make(first, second); + ClusterInfo info = clusterLRU.getWithoutMutex(uuid); + info.moveTo(baseline); + } + } + + for (String fileKey : state.files) { + String[] parts = fileKey.split("#"); + String readDirName = parts[1]; + if(!readDirName.equals(currentDir)) { + String fileName = parts[0] + ".extFile"; + Path from = dbFolder.resolve(readDirName).resolve(fileName); + Path to = baseline.resolve(fileName); + System.err.println("purge copies " + from + " => " + to); + Files.copy(from, to, StandardCopyOption.COPY_ATTRIBUTES); + FileInfo info = fileLRU.getWithoutMutex(parts[0]); + info.moveTo(baseline); + } + } + + for (String fileKey : state.stream) { + String[] parts = fileKey.split("#"); + String readDirName = parts[1]; + if(!readDirName.equals(currentDir)) { + ClusterStreamChunk chunk = streamLRU.purge(parts[0]); + System.err.println("purge removes " + chunk); + } + } + + // Change sets + for (String fileKey : state.cs) { + String[] parts = fileKey.split("#"); + String readDirName = parts[1]; + if(!readDirName.equals(currentDir)) { + Long revisionId = Long.parseLong(parts[0]); + ChangeSetInfo info = csLRU.purge(revisionId); + System.err.println("purge removes " + info); + } +// Path readDir = dbFolder.resolve(parts[1]); +// Long revisionId = Long.parseLong(parts[0]); +// int offset = Integer.parseInt(parts[2]); +// int length = Integer.parseInt(parts[3]); +// ChangeSetInfo info = new ChangeSetInfo(csLRU, readDir, revisionId, offset, length); +// csLRU.map(info); + } + + state.tailChangeSetId = state.headChangeSetId; + + makeSnapshot(locator, true); + + Files.walk(dbFolder, 1).filter(Files::isDirectory).forEach(f -> tryPurgeDirectory(f)); + + } catch (IllegalAcornStateException e) { + notSafeToMakeSnapshot(e); + throw e; + } catch (IOException e) { + IllegalAcornStateException e1 = new IllegalAcornStateException(e); + notSafeToMakeSnapshot(e1); + throw e1; + } catch (AcornAccessVerificationException e) { + IllegalAcornStateException e1 = new IllegalAcornStateException(e); + notSafeToMakeSnapshot(e1); + throw e1; + } + + } + + void tryPurgeDirectory(Path f) { + + + System.err.println("purge deletes " + f); + + String currentDir = f.getFileName().toString(); + if(currentDir.endsWith("db")) + return; + + if(currentDir.endsWith("_baseline")) + currentDir = currentDir.replace("_baseline", ""); + + int ordinal = Integer.parseInt(currentDir); + if(ordinal < mainState.headDir - 1) { + System.err.println("purge deletes " + f); + FileUtils.deleteDir(f.toFile()); + } + + } + public synchronized boolean makeSnapshot(ServiceLocator locator, boolean fullSave) throws IllegalAcornStateException { try { if (!safeToMakeSnapshot.get()) @@ -221,9 +338,13 @@ public class ClusterManager { csLRU.persist(state.cs); } - private void persistHeadState() throws IOException { + private void synchronizeWorkingDirectory() throws IOException { // Sync current working directory Files.walk(workingDirectory, 1).filter(Files::isRegularFile).forEach(FileIO::uncheckedSyncPath); + } + + private void persistHeadState() throws IOException { + synchronizeWorkingDirectory(); state.save(workingDirectory); mainState.headDir++; } @@ -583,4 +704,8 @@ public class ClusterManager { this.cause = t; } + public long getTailChangeSetId() { + return state.tailChangeSetId; + } + }