diff --git a/java/java-impl/src/com/intellij/openapi/vcs/contentAnnotation/VcsContentAnnotationExceptionFilter.java b/java/java-impl/src/com/intellij/openapi/vcs/contentAnnotation/VcsContentAnnotationExceptionFilter.java index b3b653dea8c1..d554321af76b 100644 --- a/java/java-impl/src/com/intellij/openapi/vcs/contentAnnotation/VcsContentAnnotationExceptionFilter.java +++ b/java/java-impl/src/com/intellij/openapi/vcs/contentAnnotation/VcsContentAnnotationExceptionFilter.java @@ -33,6 +33,7 @@ import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.Trinity; import com.intellij.openapi.vcs.changes.ChangeListManager; +import com.intellij.openapi.vcs.history.VcsRevisionNumber; import com.intellij.openapi.vcs.impl.UpToDateLineNumberProviderImpl; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; @@ -103,8 +104,9 @@ public class VcsContentAnnotationExceptionFilter implements Filter, FilterMixin }); if (worker.getResult() != null) { VirtualFile vf = worker.getFile().getVirtualFile(); + final VcsRevisionNumber recentChangeRevision = vcsContentAnnotation.fileRecentlyChanged(vf); if (localChangesCorrector.isFileAlreadyIdentifiedAsChanged(vf) || ChangeListManager.isFileChanged(myProject, vf) || - vcsContentAnnotation.fileRecentlyChanged(vf)) { + recentChangeRevision != null) { final Document document = getDocumentForFile(worker); if (document == null) return; @@ -123,7 +125,7 @@ public class VcsContentAnnotationExceptionFilter implements Filter, FilterMixin break; } final TextRange correctedRange = localChangesCorrector.getCorrectedRange(vf, document, range); - if (vcsContentAnnotation.intervalRecentlyChanged(vf, correctedRange)) { + if (vcsContentAnnotation.intervalRecentlyChanged(vf, correctedRange, recentChangeRevision)) { methodChanged = true; break; } @@ -198,9 +200,6 @@ public class VcsContentAnnotationExceptionFilter implements Filter, FilterMixin }); } - /* final UpToDateLineNumberProvider getUpToDateLineNumber = new UpToDateLineNumberProviderImpl(editor.getDocument(), project, upToDateContent); - /**/ - // line numbers private List findMethodRange(final ExceptionWorker worker, final Document document, final Trinity previousLineResult) { return ApplicationManager.getApplication().runReadAction(new Computable>() { diff --git a/platform/platform-resources/src/componentSets/VCS.xml b/platform/platform-resources/src/componentSets/VCS.xml index 4b06ef8b184e..c7db2cf25a53 100644 --- a/platform/platform-resources/src/componentSets/VCS.xml +++ b/platform/platform-resources/src/componentSets/VCS.xml @@ -111,5 +111,7 @@ com.intellij.openapi.vcs.contentAnnotation.VcsContentAnnotation com.intellij.openapi.vcs.contentAnnotation.VcsContentAnnotationImpl + com.intellij.openapi.vcs.contentAnnotation.ContentAnnotationCache + com.intellij.openapi.vcs.contentAnnotation.ContentAnnotationCacheImpl diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/annotate/FileAnnotation.java b/platform/vcs-api/src/com/intellij/openapi/vcs/annotate/FileAnnotation.java index e6acc734770e..f2039a5a783e 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/annotate/FileAnnotation.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/annotate/FileAnnotation.java @@ -104,4 +104,6 @@ public interface FileAnnotation { @Nullable AnnotationSourceSwitcher getAnnotationSourceSwitcher(); + + int getLineCount(); } diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/contentAnnotation/ContentAnnotationCache.java b/platform/vcs-api/src/com/intellij/openapi/vcs/contentAnnotation/ContentAnnotationCache.java new file mode 100644 index 000000000000..3f78ce193efa --- /dev/null +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/contentAnnotation/ContentAnnotationCache.java @@ -0,0 +1,38 @@ +/* + * Copyright 2000-2011 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.contentAnnotation; + +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.vcs.VcsKey; +import com.intellij.openapi.vcs.annotate.FileAnnotation; +import com.intellij.openapi.vcs.history.VcsRevisionNumber; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.ThreeState; +import org.jetbrains.annotations.Nullable; + +/** + * Created by IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 8/8/11 + * Time: 8:14 PM + * To change this template use File | Settings | File Templates. + */ +public interface ContentAnnotationCache { + @Nullable + ThreeState isRecent(VirtualFile vf, VcsKey vcsKey, VcsRevisionNumber number, TextRange range, long boundTime); + + void register(VirtualFile vf, VcsKey vcsKey, VcsRevisionNumber number, FileAnnotation fa); +} diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/contentAnnotation/ContentAnnotationCacheImpl.java b/platform/vcs-api/src/com/intellij/openapi/vcs/contentAnnotation/ContentAnnotationCacheImpl.java new file mode 100644 index 000000000000..42749a4b96b3 --- /dev/null +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/contentAnnotation/ContentAnnotationCacheImpl.java @@ -0,0 +1,92 @@ +/* + * Copyright 2000-2011 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.contentAnnotation; + +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.vcs.VcsKey; +import com.intellij.openapi.vcs.actions.VcsContextFactory; +import com.intellij.openapi.vcs.annotate.FileAnnotation; +import com.intellij.openapi.vcs.history.HistoryCacheWithRevisionKey; +import com.intellij.openapi.vcs.history.VcsRevisionNumber; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.ThreeState; +import com.intellij.util.containers.SLRUMap; +import org.jetbrains.annotations.Nullable; + +import java.util.Date; +import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; + +/** +* Created by IntelliJ IDEA. +* User: Irina.Chernushina +* Date: 8/8/11 +* Time: 8:26 PM +*/ +public class ContentAnnotationCacheImpl implements ContentAnnotationCache { + private final SLRUMap> myCache; + private final Object myLock; + + public ContentAnnotationCacheImpl() { + myLock = new Object(); + myCache = new SLRUMap>(50, 50); + } + + @Override + @Nullable + public ThreeState isRecent(final VirtualFile vf, + final VcsKey vcsKey, + final VcsRevisionNumber number, + final TextRange range, + final long boundTime) { + TreeMap treeMap; + synchronized (myLock) { + treeMap = myCache.get(new HistoryCacheWithRevisionKey(VcsContextFactory.SERVICE.getInstance().createFilePathOn(vf), vcsKey, number)); + } + if (treeMap != null) { + Map.Entry last = treeMap.floorEntry(range.getEndOffset()); + if (last == null || last.getKey() < range.getStartOffset()) return ThreeState.NO; + Map.Entry first = treeMap.ceilingEntry(range.getStartOffset()); + assert first != null; + final SortedMap interval = treeMap.subMap(first.getKey(), last.getKey()); + for (Map.Entry entry : interval.entrySet()) { + if (entry.getValue() >= boundTime) return ThreeState.YES; + } + return ThreeState.NO; + } + return ThreeState.UNSURE; + } + + @Override + public void register(final VirtualFile vf, final VcsKey vcsKey, final VcsRevisionNumber number, final FileAnnotation fa) { + final HistoryCacheWithRevisionKey key = new HistoryCacheWithRevisionKey(VcsContextFactory.SERVICE.getInstance().createFilePathOn(vf), vcsKey, number); + synchronized (myLock) { + if (myCache.get(key) != null) return; + } + final long absoluteLimit = System.currentTimeMillis() - VcsContentAnnotationSettings.ourAbsoluteLimit; + final TreeMap map = new TreeMap(); + final int lineCount = fa.getLineCount(); + for (int i = 0; i < lineCount; i++) { + Date lineDate = fa.getLineDate(i); + if (lineDate == null) return; + if (lineDate.getTime() >= absoluteLimit) map.put(i, lineDate.getTime()); + } + synchronized (myLock) { + myCache.put(key, map); + } + } +} diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/contentAnnotation/VcsContentAnnotation.java b/platform/vcs-api/src/com/intellij/openapi/vcs/contentAnnotation/VcsContentAnnotation.java index b39340ba32da..ae25aee2be5e 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/contentAnnotation/VcsContentAnnotation.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/contentAnnotation/VcsContentAnnotation.java @@ -15,9 +15,9 @@ */ package com.intellij.openapi.vcs.contentAnnotation; -import com.intellij.openapi.util.Getter; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vcs.RichTextItem; +import com.intellij.openapi.vcs.history.VcsRevisionNumber; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.Nullable; @@ -30,13 +30,11 @@ import java.util.List; * Time: 12:50 PM */ public interface VcsContentAnnotation { - boolean fileRecentlyChanged(final VirtualFile vf); - - boolean intervalRecentlyChanged(VirtualFile file, final TextRange lineInterval); - @Nullable - Details annotateLine(final VirtualFile vf, final Getter enclosingRange, final int lineNumber); - + VcsRevisionNumber fileRecentlyChanged(final VirtualFile vf); + + boolean intervalRecentlyChanged(VirtualFile file, final TextRange lineInterval, VcsRevisionNumber currentRevisionNumber); + class Details { private final boolean myLineChanged; // meaningful enclosing structure diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/contentAnnotation/VcsContentAnnotationImpl.java b/platform/vcs-api/src/com/intellij/openapi/vcs/contentAnnotation/VcsContentAnnotationImpl.java index f8394311bc54..18e680a7b2f7 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/contentAnnotation/VcsContentAnnotationImpl.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/contentAnnotation/VcsContentAnnotationImpl.java @@ -18,7 +18,6 @@ package com.intellij.openapi.vcs.contentAnnotation; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Getter; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vcs.AbstractVcs; import com.intellij.openapi.vcs.ProjectLevelVcsManager; @@ -26,7 +25,9 @@ import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.annotate.FileAnnotation; import com.intellij.openapi.vcs.diff.DiffMixin; import com.intellij.openapi.vcs.history.VcsRevisionDescription; +import com.intellij.openapi.vcs.history.VcsRevisionNumber; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.ThreeState; import org.jetbrains.annotations.Nullable; import java.util.Date; @@ -40,28 +41,31 @@ import java.util.Date; public class VcsContentAnnotationImpl implements VcsContentAnnotation { private final Project myProject; private final VcsContentAnnotationSettings mySettings; + private final ContentAnnotationCache myContentAnnotationCache; private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.contentAnnotation.VcsContentAnnotationImpl"); public static VcsContentAnnotation getInstance(final Project project) { return ServiceManager.getService(project, VcsContentAnnotation.class); } - public VcsContentAnnotationImpl(Project project, VcsContentAnnotationSettings settings) { + public VcsContentAnnotationImpl(Project project, VcsContentAnnotationSettings settings, final ContentAnnotationCache contentAnnotationCache) { myProject = project; mySettings = settings; + myContentAnnotationCache = contentAnnotationCache; } + @Nullable @Override - public boolean fileRecentlyChanged(VirtualFile vf) { + public VcsRevisionNumber fileRecentlyChanged(VirtualFile vf) { final ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(myProject); final AbstractVcs vcs = vcsManager.getVcsFor(vf); - if (vcs == null) return false; + if (vcs == null) return null; if (vcs.getDiffProvider() instanceof DiffMixin) { final VcsRevisionDescription description = ((DiffMixin)vcs.getDiffProvider()).getCurrentRevisionDescription(vf); final Date date = description.getRevisionDate(); - return isRecent(date); + return isRecent(date) ? description.getRevisionNumber() : null; } - return false; + return null; } private boolean isRecent(Date date) { @@ -69,10 +73,18 @@ public class VcsContentAnnotationImpl implements VcsContentAnnotation { } @Override - public boolean intervalRecentlyChanged(VirtualFile file, TextRange lineInterval) { + public boolean intervalRecentlyChanged(VirtualFile file, TextRange lineInterval, VcsRevisionNumber currentRevisionNumber) { final ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(myProject); final AbstractVcs vcs = vcsManager.getVcsFor(file); if (vcs == null) return false; + if (currentRevisionNumber == null) { + currentRevisionNumber = vcs.getDiffProvider().getCurrentRevision(file); + assert currentRevisionNumber != null; + } + final ThreeState isRecent = myContentAnnotationCache.isRecent(file, vcs.getKeyInstanceMethod(), currentRevisionNumber, lineInterval, + System.currentTimeMillis() - mySettings.getLimit()); + if (! ThreeState.UNSURE.equals(isRecent)) return ThreeState.YES.equals(isRecent); + final FileAnnotation fileAnnotation; try { fileAnnotation = vcs.getCachingAnnotationProvider().annotate(file); @@ -81,29 +93,11 @@ public class VcsContentAnnotationImpl implements VcsContentAnnotation { LOG.info(e); return false; } + myContentAnnotationCache.register(file, vcs.getKeyInstanceMethod(), currentRevisionNumber, fileAnnotation); for (int i = lineInterval.getStartOffset(); i <= lineInterval.getEndOffset(); i++) { Date lineDate = fileAnnotation.getLineDate(i); if (lineDate != null && isRecent(lineDate)) return true; } return false; } - - @Nullable - @Override - public Details annotateLine(final VirtualFile vf, final Getter enclosingRange, final int lineNumber) { - final ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(myProject); - final AbstractVcs vcs = vcsManager.getVcsFor(vf); - if (vcs == null) return null; - if (vcs.getDiffProvider() instanceof DiffMixin) { - boolean fileRecent = false; - final VcsRevisionDescription description = ((DiffMixin)vcs.getDiffProvider()).getCurrentRevisionDescription(vf); - final Date date = description.getRevisionDate(); - if (isRecent(date)) { - fileRecent = true; - enclosingRange.get(); - } - return new Details(false, false, fileRecent, null); - } - return null; - } } diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/history/HistoryCacheBaseKey.java b/platform/vcs-api/src/com/intellij/openapi/vcs/history/HistoryCacheBaseKey.java new file mode 100644 index 000000000000..f788e1ab0969 --- /dev/null +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/history/HistoryCacheBaseKey.java @@ -0,0 +1,63 @@ +/* + * Copyright 2000-2011 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.history; + +import com.intellij.openapi.vcs.FilePath; +import com.intellij.openapi.vcs.VcsKey; + +/** +* Created by IntelliJ IDEA. +* User: Irina.Chernushina +* Date: 8/8/11 +* Time: 7:01 PM +*/ +public class HistoryCacheBaseKey { + private final FilePath myFilePath; + private final VcsKey myVcsKey; + + public HistoryCacheBaseKey(FilePath filePath, VcsKey vcsKey) { + myFilePath = filePath; + myVcsKey = vcsKey; + } + + public FilePath getFilePath() { + return myFilePath; + } + + public VcsKey getVcsKey() { + return myVcsKey; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + HistoryCacheBaseKey baseKey = (HistoryCacheBaseKey)o; + + if (!myFilePath.equals(baseKey.myFilePath)) return false; + if (!myVcsKey.equals(baseKey.myVcsKey)) return false; + + return true; + } + + @Override + public int hashCode() { + int result = myFilePath.hashCode(); + result = 31 * result + myVcsKey.hashCode(); + return result; + } +} diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/history/HistoryCacheWithRevisionKey.java b/platform/vcs-api/src/com/intellij/openapi/vcs/history/HistoryCacheWithRevisionKey.java new file mode 100644 index 000000000000..e020885dceb2 --- /dev/null +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/history/HistoryCacheWithRevisionKey.java @@ -0,0 +1,59 @@ +/* + * Copyright 2000-2011 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.history; + +import com.intellij.openapi.vcs.FilePath; +import com.intellij.openapi.vcs.VcsKey; +import org.jetbrains.annotations.NotNull; + +/** +* Created by IntelliJ IDEA. +* User: Irina.Chernushina +* Date: 8/8/11 +* Time: 7:01 PM +*/ +public class HistoryCacheWithRevisionKey extends HistoryCacheBaseKey { + private final VcsRevisionNumber myRevisionNumber; + + public HistoryCacheWithRevisionKey(FilePath filePath, VcsKey vcsKey, @NotNull VcsRevisionNumber revisionNumber) { + super(filePath, vcsKey); + myRevisionNumber = revisionNumber; + } + + public VcsRevisionNumber getRevisionNumber() { + return myRevisionNumber; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + HistoryCacheWithRevisionKey that = (HistoryCacheWithRevisionKey)o; + + if (!myRevisionNumber.equals(that.myRevisionNumber)) return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + myRevisionNumber.hashCode(); + return result; + } +} diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/history/VcsHistoryCache.java b/platform/vcs-api/src/com/intellij/openapi/vcs/history/VcsHistoryCache.java index e659636de80c..b81b2bdd6e56 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/history/VcsHistoryCache.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/history/VcsHistoryCache.java @@ -34,15 +34,15 @@ import java.util.Map; */ public class VcsHistoryCache { private final Object myLock; - private final SLRUMap myHistoryCache; - private final SLRUMap myAnnotationCache; - //private final SLRUMap myContentCache; + private final SLRUMap myHistoryCache; + private final SLRUMap myAnnotationCache; + //private final SLRUMap myContentCache; public VcsHistoryCache() { myLock = new Object(); - myHistoryCache = new SLRUMap(10, 10); - myAnnotationCache = new SLRUMap(10, 5); - //myContentCache = new SLRUMap(20, 20); + myHistoryCache = new SLRUMap(10, 10); + myAnnotationCache = new SLRUMap(10, 5); + //myContentCache = new SLRUMap(20, 20); } public void put(final FilePath filePath, @@ -52,7 +52,7 @@ public class VcsHistoryCache { @NotNull final VcsCacheableHistorySessionFactory factory, boolean isFull) { synchronized (myLock) { - myHistoryCache.put(new BaseKey(filePath, vcsKey), + myHistoryCache.put(new HistoryCacheBaseKey(filePath, vcsKey), new CachedHistory(correctedPath != null ? correctedPath : filePath, session.getRevisionList(), session.getCurrentRevisionNumber(), factory.getAddinionallyCachedData(session), isFull)); } @@ -62,7 +62,7 @@ public class VcsHistoryCache { public T getFull(final FilePath filePath, final VcsKey vcsKey, @NotNull final VcsCacheableHistorySessionFactory factory) { synchronized (myLock) { - final CachedHistory cachedHistory = myHistoryCache.get(new BaseKey(filePath, vcsKey)); + final CachedHistory cachedHistory = myHistoryCache.get(new HistoryCacheBaseKey(filePath, vcsKey)); if (cachedHistory == null || ! cachedHistory.isIsFull()) { return null; } @@ -75,7 +75,7 @@ public class VcsHistoryCache { public T getMaybePartial(final FilePath filePath, final VcsKey vcsKey, @NotNull final VcsCacheableHistorySessionFactory factory) { synchronized (myLock) { - final CachedHistory cachedHistory = myHistoryCache.get(new BaseKey(filePath, vcsKey)); + final CachedHistory cachedHistory = myHistoryCache.get(new HistoryCacheBaseKey(filePath, vcsKey)); if (cachedHistory == null) { return null; } @@ -86,9 +86,9 @@ public class VcsHistoryCache { public void clear() { synchronized (myLock) { - final Iterator> iterator = myHistoryCache.entrySet().iterator(); + final Iterator> iterator = myHistoryCache.entrySet().iterator(); while (iterator.hasNext()) { - final Map.Entry next = iterator.next(); + final Map.Entry next = iterator.next(); if (! next.getKey().getFilePath().isNonLocal()) { iterator.remove(); } @@ -99,84 +99,13 @@ public class VcsHistoryCache { public void put(@NotNull final FilePath filePath, @NotNull final VcsKey vcsKey, @NotNull final VcsRevisionNumber number, @NotNull final VcsAnnotation vcsAnnotation) { synchronized (myLock) { - myAnnotationCache.put(new WithRevisionKey(filePath, vcsKey, number), vcsAnnotation); + myAnnotationCache.put(new HistoryCacheWithRevisionKey(filePath, vcsKey, number), vcsAnnotation); } } public VcsAnnotation get(@NotNull final FilePath filePath, @NotNull final VcsKey vcsKey, @NotNull final VcsRevisionNumber number) { synchronized (myLock) { - return myAnnotationCache.get(new WithRevisionKey(filePath, vcsKey, number)); - } - } - - private static class WithRevisionKey extends BaseKey { - private final VcsRevisionNumber myRevisionNumber; - - private WithRevisionKey(FilePath filePath, VcsKey vcsKey, @NotNull VcsRevisionNumber revisionNumber) { - super(filePath, vcsKey); - myRevisionNumber = revisionNumber; - } - - public VcsRevisionNumber getRevisionNumber() { - return myRevisionNumber; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; - - WithRevisionKey that = (WithRevisionKey)o; - - if (!myRevisionNumber.equals(that.myRevisionNumber)) return false; - - return true; - } - - @Override - public int hashCode() { - int result = super.hashCode(); - result = 31 * result + myRevisionNumber.hashCode(); - return result; - } - } - - private static class BaseKey { - private final FilePath myFilePath; - private final VcsKey myVcsKey; - - BaseKey(FilePath filePath, VcsKey vcsKey) { - myFilePath = filePath; - myVcsKey = vcsKey; - } - - public FilePath getFilePath() { - return myFilePath; - } - - public VcsKey getVcsKey() { - return myVcsKey; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - BaseKey baseKey = (BaseKey)o; - - if (!myFilePath.equals(baseKey.myFilePath)) return false; - if (!myVcsKey.equals(baseKey.myVcsKey)) return false; - - return true; - } - - @Override - public int hashCode() { - int result = myFilePath.hashCode(); - result = 31 * result + myVcsKey.hashCode(); - return result; + return myAnnotationCache.get(new HistoryCacheWithRevisionKey(filePath, vcsKey, number)); } } diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/annotate/CvsFileAnnotation.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/annotate/CvsFileAnnotation.java index aa6d449df696..3538aecee976 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/annotate/CvsFileAnnotation.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/annotate/CvsFileAnnotation.java @@ -180,6 +180,11 @@ public class CvsFileAnnotation implements FileAnnotation{ return null; } + @Override + public int getLineCount() { + return myAnnotations.length; + } + private abstract class CvsAnnotationAspect extends LineAnnotationAspectAdapter { public CvsAnnotationAspect(String id, boolean showByDefault) { super(id, showByDefault); diff --git a/plugins/git4idea/src/git4idea/annotate/GitFileAnnotation.java b/plugins/git4idea/src/git4idea/annotate/GitFileAnnotation.java index da98e8703b24..c5417fad8a26 100644 --- a/plugins/git4idea/src/git4idea/annotate/GitFileAnnotation.java +++ b/plugins/git4idea/src/git4idea/annotate/GitFileAnnotation.java @@ -233,6 +233,11 @@ public class GitFileAnnotation implements FileAnnotation { return null; } + @Override + public int getLineCount() { + return myLines.size(); + } + /** * {@inheritDoc} */ diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/annotate/HgAnnotation.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/annotate/HgAnnotation.java index 0d6075ecfe45..501e044e5a28 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/annotate/HgAnnotation.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/annotate/HgAnnotation.java @@ -58,6 +58,11 @@ public class HgAnnotation implements FileAnnotation { return null; } + @Override + public int getLineCount() { + return lines.size(); + } + public VcsRevisionNumber originalRevision(int lineNumber) { return getLineRevisionNumber(lineNumber); } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnFileAnnotation.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnFileAnnotation.java index 4e211f432c79..e4329a259887 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnFileAnnotation.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnFileAnnotation.java @@ -307,6 +307,11 @@ public class SvnFileAnnotation implements FileAnnotation { }; } + @Override + public int getLineCount() { + return getNumLines(); + } + private abstract class SvnAnnotationAspect extends LineAnnotationAspectAdapter { public SvnAnnotationAspect(String id, boolean showByDefault) { super(id, showByDefault);