+++ /dev/null
-/*
- * Copyright 2000-2010 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.openapi.vcs;
-
-import com.intellij.util.PairProcessor;
-
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-
-import static com.intellij.util.containers.ContainerUtil.newHashMap;
-import static com.intellij.util.containers.ContainerUtil.newLinkedList;
-import static java.util.Collections.binarySearch;
-
-public class AreaMap<Key extends Comparable<Key>, Val> {
- private final List<Key> myKeys = newLinkedList();
- private final Map<Key, Val> myMap = newHashMap();
-
- public void put(final Key key, final Val val) {
- myMap.put(key, val);
-
- if (myKeys.isEmpty()) {
- myKeys.add(key);
- }
- else {
- int idx = binarySearch(myKeys, key);
- if (idx < 0) {
- int insertionIdx = -idx - 1;
- myKeys.add(insertionIdx, key);
- }
- }
- }
-
- public void getSimiliar(Key key, PairProcessor<Key, Key> keysResemblance, PairProcessor<Key, Val> consumer) {
- int idx = binarySearch(myKeys, key);
- if (idx < 0) {
- int insertionIdx = -idx - 1;
- if (insertionIdx - 1 >= 0) {
- for (ListIterator<Key> iterator = myKeys.listIterator(insertionIdx); iterator.hasPrevious(); ) {
- Key candidate = iterator.previous();
- if (!keysResemblance.process(candidate, key)) continue;
- if (consumer.process(candidate, myMap.get(candidate))) break; // if need only a part of keys
- }
- }
- } else {
- consumer.process(key, myMap.get(key));
- }
- }
-}
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.SystemInfo;
-import com.intellij.openapi.vcs.AreaMap;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.util.PairProcessor;
import org.jetbrains.annotations.NotNull;
import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.File;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
import static com.intellij.openapi.util.io.FileUtil.getRelativePath;
import static com.intellij.openapi.util.io.FileUtil.toSystemIndependentName;
import static com.intellij.openapi.util.text.StringUtil.toUpperCase;
import static com.intellij.util.ObjectUtils.notNull;
import static com.intellij.util.containers.ContainerUtil.*;
+import static java.util.Collections.reverseOrder;
import static org.jetbrains.idea.svn.SvnUtil.ensureStartSlash;
import static org.jetbrains.idea.svn.mergeinfo.SvnMergeInfoCache.MergeCheckResult;
import static org.tmatesoft.svn.core.internal.util.SVNPathUtil.isAncestor;
@NotNull private final MergeContext myMergeContext;
@NotNull private final Map<Long, Collection<String>> myPartiallyMerged;
// subpath [file] (local) to (subpathURL - merged FROM - to ranges list)
- @NotNull private final AreaMap<String, Map<String, SVNMergeRangeList>> myMergeInfoMap;
+ @NotNull private final NavigableMap<String, Map<String, SVNMergeRangeList>> myMergeInfoMap;
@NotNull private final Object myMergeInfoLock;
public OneShotMergeInfoHelper(@NotNull MergeContext mergeContext) {
myMergeContext = mergeContext;
myPartiallyMerged = newHashMap();
myMergeInfoLock = new Object();
- // TODO: Rewrite without AreaMap usage
- myMergeInfoMap = new AreaMap<>();
+ myMergeInfoMap = new TreeMap<>(reverseOrder());
}
@Override
// TODO: SVNPathUtil.getRelativePath() is @NotNull - probably we need to check also isEmpty() here?
if (sourceRelativePath != null) {
InfoProcessor processor = new InfoProcessor(sourceRelativePath, myMergeContext.getRepositoryRelativeSourcePath(), revisionNumber);
+ String key = toKey(sourceRelativePath);
synchronized (myMergeInfoLock) {
- myMergeInfoMap.getSimiliar(
- toKey(sourceRelativePath),
- (parentUrl, childUrl) -> ".".equals(parentUrl) || isAncestor(ensureStartSlash(parentUrl), ensureStartSlash(childUrl)),
- processor);
+ Map<String, SVNMergeRangeList> mergeInfo = myMergeInfoMap.get(key);
+ if (mergeInfo != null) {
+ processor.process(key, mergeInfo);
+ }
+ else {
+ for (Map.Entry<String, Map<String, SVNMergeRangeList>> entry : myMergeInfoMap.tailMap(key).entrySet()) {
+ if (isUnder(entry.getKey(), key) && processor.process(entry.getKey(), entry.getValue())) {
+ break;
+ }
+ }
+ }
}
result = MergeCheckResult.getInstance(processor.isMerged());
return result;
}
+ private static boolean isUnder(@NotNull String parentUrl, @NotNull String childUrl) {
+ return ".".equals(parentUrl) || isAncestor(ensureStartSlash(parentUrl), ensureStartSlash(childUrl));
+ }
+
private static class InfoProcessor implements PairProcessor<String, Map<String, SVNMergeRangeList>> {
@NotNull private final String myRepositoryRelativeSourcePath;