From 2b2765b4e41063494374f2c6d1e901b7ceb161a8 Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Wed, 28 Sep 2016 17:10:57 +0300 Subject: [PATCH] svn: Refactored "SvnBranchPointsCalculator.PersistentHolder" - code simplified "myPersistentMap" already provides stored data as "TreeMap". So we just utilize it instead of implementing same logic using separate "myForSearchMap". --- .../integrate/SvnBranchPointsCalculator.java | 88 ++++++------------- 1 file changed, 28 insertions(+), 60 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SvnBranchPointsCalculator.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SvnBranchPointsCalculator.java index 55b22e7c1bcb..55baf0ca442a 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SvnBranchPointsCalculator.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/SvnBranchPointsCalculator.java @@ -25,7 +25,6 @@ import com.intellij.openapi.vcs.persistent.SmallMapSerializer; import com.intellij.util.Consumer; import com.intellij.util.ThrowableConvertor; import com.intellij.util.ValueHolder; -import com.intellij.util.containers.MultiMap; import com.intellij.util.continuation.ContinuationContext; import com.intellij.util.continuation.TaskDescriptor; import com.intellij.util.continuation.Where; @@ -41,7 +40,9 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.File; import java.io.IOException; -import java.util.*; +import java.util.Map; +import java.util.NavigableMap; +import java.util.TreeMap; public class SvnBranchPointsCalculator { @@ -149,33 +150,18 @@ public class SvnBranchPointsCalculator { } private static class PersistentHolder { - private final SmallMapSerializer> myPersistentMap; - private final MultiMap myForSearchMap; - private final Object myLock; + @NotNull private final SmallMapSerializer> myPersistentMap; + @NotNull private final Object myLock = new Object(); - PersistentHolder(final File file) { - myLock = new Object(); - myPersistentMap = new SmallMapSerializer<>( - file, EnumeratorStringDescriptor.INSTANCE, new BranchDataExternalizer()); - // list for values by default - myForSearchMap = new MultiMap<>(); - for (String s : myPersistentMap.keySet()) { - final TreeMap map = myPersistentMap.get(s); - if (map != null) { - myForSearchMap.put(s, new ArrayList<>(map.keySet())); - } - } - - for (String key : myForSearchMap.keySet()) { - Collections.sort((List) myForSearchMap.get(key)); - } + PersistentHolder(@NotNull File file) { + myPersistentMap = new SmallMapSerializer<>(file, EnumeratorStringDescriptor.INSTANCE, new BranchDataExternalizer()); } public void close() { myPersistentMap.force(); } - public void put(final String uid, final String target, final BranchCopyData data) { + public void put(String uid, String target, BranchCopyData data) { // todo - rewrite of rather big piece; consider rewriting synchronized (myLock) { TreeMap map = myPersistentMap.get(uid); @@ -184,58 +170,40 @@ public class SvnBranchPointsCalculator { } map.put(target, data); myPersistentMap.put(uid, map); - if (myForSearchMap.containsKey(uid)) { - final List list = (List)myForSearchMap.get(uid); - final int idx = Collections.binarySearch(list, target); - if (idx < 0) { - final int insertionIdx = - idx - 1; - list.add(insertionIdx, target); - } - } else { - myForSearchMap.putValue(uid, target); - } } myPersistentMap.force(); } @Nullable - public WrapperInvertor getBestHit(final String repoUrl, final String source, final String target) { - final List keys; + public WrapperInvertor getBestHit(String repoUrl, String source, String target) { synchronized (myLock) { - keys = (List) myForSearchMap.get(repoUrl); - } - // keys are never removed, so we can use 2 synchronized blocks - final String sourceMatching = getMatchingUrl(keys, source); - final String targetMatching = getMatchingUrl(keys, target); + WrapperInvertor result = null; + TreeMap map = myPersistentMap.get(repoUrl); - if (sourceMatching == null && targetMatching == null) return null; + if (map != null) { + BranchCopyData sourceData = getBranchData(map, source); + BranchCopyData targetData = getBranchData(map, target); - synchronized (myLock) { - final TreeMap map = myPersistentMap.get(repoUrl); - - final boolean sourceIsOut = sourceMatching == null; - if (sourceIsOut || targetMatching == null) { - // if found by "target" url - we correctly thought that target of copy is target - return sourceIsOut ? new WrapperInvertor(false, map.get(targetMatching)) : - new WrapperInvertor(true, map.get(sourceMatching)); + if (sourceData != null && targetData != null) { + boolean inverted = sourceData.getTargetRevision() > targetData.getTargetRevision(); + result = new WrapperInvertor(inverted, inverted ? sourceData : targetData); + } + else if (sourceData != null) { + result = new WrapperInvertor(true, sourceData); + } + else if (targetData != null) { + result = new WrapperInvertor(false, targetData); + } } - final BranchCopyData sourceData = map.get(sourceMatching); - final BranchCopyData targetData = map.get(targetMatching); - final boolean inverted = sourceData.getTargetRevision() > targetData.getTargetRevision(); - return new WrapperInvertor(inverted, inverted ? sourceData : targetData); + return result; } } @Nullable - private String getMatchingUrl(List keys, String source) { - final int idx = Collections.binarySearch(keys, source); - if (idx >= 0) return keys.get(idx); - final int beforeInsertionIdx = - idx - 2; - if (beforeInsertionIdx < 0) return null; - final String candidate = keys.get(beforeInsertionIdx); - if (source.startsWith(candidate)) return candidate; - return null; + private static BranchCopyData getBranchData(@NotNull NavigableMap map, String url) { + Map.Entry branchData = map.floorEntry(url); + return branchData != null && url.startsWith(branchData.getKey()) ? branchData.getValue() : null; } }