svn: Refactored "SvnBranchPointsCalculator" - code simplified

This commit is contained in:
Konstantin Kolosovsky
2016-10-11 04:28:23 +03:00
parent 1685c53a4a
commit 3c1e43b53b
2 changed files with 69 additions and 109 deletions
@@ -354,8 +354,7 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
FrameStateManager.getInstance().addListener(myFrameStateListener);
myAuthNotifier.init();
mySvnBranchPointsCalculator = new SvnBranchPointsCalculator(myProject);
mySvnBranchPointsCalculator.activate();
mySvnBranchPointsCalculator = new SvnBranchPointsCalculator(this);
svnKitManager.activate();
@@ -17,13 +17,11 @@ package org.jetbrains.idea.svn.integrate;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.ThreadSafeTransparentlyFailedValue;
import com.intellij.openapi.vcs.changes.TransparentlyFailedValueI;
import com.intellij.openapi.vcs.persistent.SmallMapSerializer;
import com.intellij.util.Consumer;
import com.intellij.util.ThrowableConvertor;
import com.intellij.util.continuation.ContinuationContext;
import com.intellij.util.continuation.TaskDescriptor;
import com.intellij.util.continuation.Where;
@@ -43,39 +41,33 @@ import java.util.Map;
import java.util.NavigableMap;
import java.util.TreeMap;
import static com.intellij.util.containers.ContainerUtil.newTreeMap;
public class SvnBranchPointsCalculator {
private static final Logger LOG = Logger.getInstance(SvnBranchPointsCalculator.class);
private SmallMapSerializer<String, TreeMap<String, BranchCopyData>> myPersistentMap;
@NotNull private final SmallMapSerializer<String, TreeMap<String, BranchCopyData>> myPersistentMap;
@NotNull private final Object myPersistenceLock = new Object();
private File myFile;
private final Project myProject;
@NotNull private final SvnVcs myVcs;
public SvnBranchPointsCalculator(final Project project) {
myProject = project;
final File vcs = new File(PathManager.getSystemPath(), "vcs");
File file = new File(vcs, "svn_copy_sources");
file.mkdirs();
myFile = file;
myFile = new File(file, project.getLocationHash());
}
public void activate() {
synchronized (myPersistenceLock) {
myPersistentMap = new SmallMapSerializer<>(myFile, EnumeratorStringDescriptor.INSTANCE, new BranchDataExternalizer());
}
public SvnBranchPointsCalculator(@NotNull SvnVcs vcs) {
myVcs = vcs;
File directory = new File(new File(PathManager.getSystemPath(), "vcs"), "svn_copy_sources");
directory.mkdirs();
File file = new File(directory, myVcs.getProject().getLocationHash());
myPersistentMap = new SmallMapSerializer<>(file, EnumeratorStringDescriptor.INSTANCE, new BranchDataExternalizer());
}
@Nullable
public WrapperInvertor getBestHit(String repoUrl, String source, String target) {
public WrapperInvertor getBestHit(@NotNull String repoUrl, @NotNull String sourceUrl, @NotNull String targetUrl) {
synchronized (myPersistenceLock) {
WrapperInvertor result = null;
TreeMap<String, BranchCopyData> map = myPersistentMap.get(repoUrl);
if (map != null) {
BranchCopyData sourceData = getBranchData(map, source);
BranchCopyData targetData = getBranchData(map, target);
BranchCopyData sourceData = getBranchData(map, sourceUrl);
BranchCopyData targetData = getBranchData(map, targetUrl);
if (sourceData != null && targetData != null) {
boolean inverted = sourceData.getTargetRevision() > targetData.getTargetRevision();
@@ -89,7 +81,7 @@ public class SvnBranchPointsCalculator {
}
}
logCopyData(repoUrl, source, target, result);
logCopyData(repoUrl, sourceUrl, targetUrl, result);
return result;
}
@@ -98,57 +90,65 @@ public class SvnBranchPointsCalculator {
public void deactivate() {
synchronized (myPersistenceLock) {
myPersistentMap.force();
myPersistentMap = null;
}
}
private void persist(String uid, @NotNull BranchCopyData data) {
private void persist(@NotNull String repoUrl, @NotNull BranchCopyData data) {
// todo - rewrite of rather big piece; consider rewriting
synchronized (myPersistenceLock) {
TreeMap<String, BranchCopyData> map = myPersistentMap.get(uid);
TreeMap<String, BranchCopyData> map = myPersistentMap.get(repoUrl);
if (map == null) {
map = new TreeMap<>();
map = newTreeMap();
}
map.put(data.getTarget(), data);
myPersistentMap.put(uid, map);
myPersistentMap.put(repoUrl, map);
myPersistentMap.force();
}
}
@Nullable
private static BranchCopyData getBranchData(@NotNull NavigableMap<String, BranchCopyData> map, String url) {
private static BranchCopyData getBranchData(@NotNull NavigableMap<String, BranchCopyData> map, @NotNull String url) {
Map.Entry<String, BranchCopyData> branchData = map.floorEntry(url);
return branchData != null && url.startsWith(branchData.getKey()) ? branchData.getValue() : null;
}
private static class BranchDataExternalizer implements DataExternalizer<TreeMap<String, BranchCopyData>> {
public void save(@NotNull DataOutput out, TreeMap<String, BranchCopyData> value) throws IOException {
public void save(@NotNull DataOutput out, @NotNull TreeMap<String, BranchCopyData> value) throws IOException {
out.writeInt(value.size());
for (Map.Entry<String, BranchCopyData> entry : value.entrySet()) {
out.writeUTF(entry.getKey());
final BranchCopyData entryValue = entry.getValue();
out.writeUTF(entryValue.getSource());
out.writeUTF(entryValue.getTarget());
out.writeLong(entryValue.getSourceRevision());
out.writeLong(entryValue.getTargetRevision());
save(out, entry.getValue());
}
}
private static void save(@NotNull DataOutput out, @NotNull BranchCopyData value) throws IOException {
out.writeUTF(value.getSource());
out.writeUTF(value.getTarget());
out.writeLong(value.getSourceRevision());
out.writeLong(value.getTargetRevision());
}
@NotNull
public TreeMap<String, BranchCopyData> read(@NotNull DataInput in) throws IOException {
final TreeMap<String, BranchCopyData> result = new TreeMap<>();
TreeMap<String, BranchCopyData> result = newTreeMap();
int size = in.readInt();
final int num = in.readInt();
for (int i = 0; i < num; i++) {
final String key = in.readUTF();
final String source = in.readUTF();
final String target = in.readUTF();
final long sourceRevision = in.readLong();
final long targetRevision = in.readLong();
result.put(key, new BranchCopyData(source, sourceRevision, target, targetRevision));
for (int i = 0; i < size; i++) {
result.put(in.readUTF(), readCopyPoint(in));
}
return result;
}
@NotNull
private static BranchCopyData readCopyPoint(@NotNull DataInput in) throws IOException {
String sourceUrl = in.readUTF();
String targetUrl = in.readUTF();
long sourceRevision = in.readLong();
long targetRevision = in.readLong();
return new BranchCopyData(sourceUrl, sourceRevision, targetUrl, targetRevision);
}
}
public static class WrapperInvertor {
@@ -182,36 +182,24 @@ public class SvnBranchPointsCalculator {
}
}
private static class Loader implements ThrowableConvertor<KeyData, WrapperInvertor, VcsException> {
private SvnVcs myVcs;
@Nullable
public WrapperInvertor calculateCopyPoint(@NotNull String repoUrl, @NotNull String sourceUrl, @NotNull String targetUrl)
throws VcsException {
WrapperInvertor result = null;
CopyData copyData = new FirstInBranch(myVcs, repoUrl, targetUrl, sourceUrl).run();
private Loader(final Project project) {
myVcs = SvnVcs.getInstance(project);
if (copyData != null) {
BranchCopyData branchCopyData =
copyData.isTrunkSupposedCorrect()
? new BranchCopyData(sourceUrl, copyData.getCopySourceRevision(), targetUrl, copyData.getCopyTargetRevision())
: new BranchCopyData(targetUrl, copyData.getCopySourceRevision(), sourceUrl, copyData.getCopyTargetRevision());
result = new WrapperInvertor(!copyData.isTrunkSupposedCorrect(), branchCopyData);
}
@Override
public WrapperInvertor convert(final KeyData keyData) throws VcsException {
WrapperInvertor result = null;
CopyData copyData = new FirstInBranch(myVcs, keyData.getRepoUrl(), keyData.getTargetUrl(), keyData.getSourceUrl()).run();
logCopyData(repoUrl, sourceUrl, targetUrl, result);
if (copyData != null) {
final boolean correct = copyData.isTrunkSupposedCorrect();
final BranchCopyData branchCopyData;
if (correct) {
branchCopyData = new BranchCopyData(keyData.getSourceUrl(), copyData.getCopySourceRevision(), keyData.getTargetUrl(),
copyData.getCopyTargetRevision());
}
else {
branchCopyData = new BranchCopyData(keyData.getTargetUrl(), copyData.getCopySourceRevision(), keyData.getSourceUrl(),
copyData.getCopyTargetRevision());
}
result = new WrapperInvertor(!correct, branchCopyData);
}
logCopyData(keyData.getRepoUrl(), keyData.getSourceUrl(), keyData.getTargetUrl(), result);
return result;
}
return result;
}
private static void logCopyData(@NotNull String repoUrl,
@@ -223,35 +211,6 @@ public class SvnBranchPointsCalculator {
}
}
private static class KeyData {
private final String myRepoUrl;
private final String mySourceUrl;
private final String myTargetUrl;
public KeyData(final String repoUID, final String sourceUrl, final String targetUrl) {
myRepoUrl = repoUID;
mySourceUrl = sourceUrl;
myTargetUrl = targetUrl;
}
public String getRepoUrl() {
return myRepoUrl;
}
public String getSourceUrl() {
return mySourceUrl;
}
public String getTargetUrl() {
return myTargetUrl;
}
@Override
public String toString() {
return "repoURL: " + myRepoUrl + " sourceUrl:" + mySourceUrl + " targetUrl: " + myTargetUrl;
}
}
public static class BranchCopyData {
private final String mySource;
private final String myTarget;
@@ -291,18 +250,20 @@ public class SvnBranchPointsCalculator {
}
}
public TaskDescriptor getFirstCopyPointTask(final String repoUID, final String sourceUrl, final String targetUrl,
final Consumer<TransparentlyFailedValueI<WrapperInvertor, VcsException>> consumer) {
KeyData in = new KeyData(repoUID, sourceUrl, targetUrl);
@NotNull
public TaskDescriptor getFirstCopyPointTask(@NotNull String repoUrl,
@NotNull String sourceUrl,
@NotNull String targetUrl,
@NotNull Consumer<TransparentlyFailedValueI<WrapperInvertor, VcsException>> consumer) {
TransparentlyFailedValueI<WrapperInvertor, VcsException> value = new ThreadSafeTransparentlyFailedValue<>();
final TaskDescriptor pooled = new TaskDescriptor("Looking for branch origin", Where.POOLED) {
TaskDescriptor pooled = new TaskDescriptor("Looking for branch origin", Where.POOLED) {
@Override
public void run(ContinuationContext context) {
try {
WrapperInvertor calculatedValue = new Loader(myProject).convert(in);
WrapperInvertor calculatedValue = calculateCopyPoint(repoUrl, sourceUrl, targetUrl);
if (calculatedValue != null) {
persist(repoUID, calculatedValue.getWrapped());
persist(repoUrl, calculatedValue.getWrapped());
}
value.set(calculatedValue);
}
@@ -322,7 +283,7 @@ public class SvnBranchPointsCalculator {
@Override
public void run(ContinuationContext context) {
try {
value.set(getBestHit(repoUID, sourceUrl, targetUrl));
value.set(getBestHit(repoUrl, sourceUrl, targetUrl));
}
catch (Exception e) {
setException(value, e);
@@ -336,7 +297,7 @@ public class SvnBranchPointsCalculator {
};
}
private static void setException(TransparentlyFailedValueI<WrapperInvertor, VcsException> value, Exception e) {
private static void setException(@NotNull TransparentlyFailedValueI<WrapperInvertor, VcsException> value, @NotNull Exception e) {
if (e instanceof VcsException) {
value.fail((VcsException)e);
}