1 package com
.intellij
.openapi
.vcs
.changes
;
3 import com
.intellij
.openapi
.project
.Project
;
4 import com
.intellij
.openapi
.util
.Pair
;
5 import com
.intellij
.openapi
.vcs
.*;
6 import com
.intellij
.openapi
.vfs
.VirtualFile
;
7 import com
.intellij
.util
.containers
.MultiMap
;
8 import org
.jetbrains
.annotations
.Nullable
;
13 public class RemoteRevisionsStateCache
implements ChangesOnServerTracker
{
14 private final static long DISCRETE
= 600000;
16 private final Map
<String
, Pair
<Boolean
, VcsRoot
>> myChanged
;
18 private final MultiMap
<VcsRoot
, String
> myQueries
;
19 private final Map
<VcsRoot
, Long
> myTs
;
20 private final Object myLock
;
21 private ProjectLevelVcsManager myVcsManager
;
23 RemoteRevisionsStateCache(final Project project
) {
24 myVcsManager
= ProjectLevelVcsManager
.getInstance(project
);
25 myChanged
= new HashMap
<String
, Pair
<Boolean
, VcsRoot
>>();
26 myQueries
= new MultiMap
<VcsRoot
, String
>();
27 myTs
= new HashMap
<VcsRoot
, Long
>();
28 myLock
= new Object();
31 public void invalidate(final Collection
<String
> paths
) {
32 synchronized (myLock
) {
33 for (String path
: paths
) {
34 myChanged
.remove(path
);
40 private VirtualFile
getRootForPath(final String s
) {
41 return myVcsManager
.getVcsRootFor(new FilePathImpl(new File(s
), false));
44 public boolean isUpToDate(final Change change
) {
45 final List
<File
> files
= ChangesUtil
.getIoFilesFromChanges(Collections
.singletonList(change
));
46 synchronized (myLock
) {
47 for (File file
: files
) {
48 final String path
= file
.getAbsolutePath();
49 final Pair
<Boolean
, VcsRoot
> data
= myChanged
.get(path
);
50 if (data
!= null && Boolean
.TRUE
.equals(data
.getFirst())) return false;
56 public void plus(final Pair
<String
, AbstractVcs
> pair
) {
57 final VirtualFile root
= getRootForPath(pair
.getFirst());
58 if (root
== null) return;
59 synchronized (myLock
) {
60 myQueries
.putValue(new VcsRoot(pair
.getSecond(), root
), pair
.getFirst());
64 public void minus(Pair
<String
, AbstractVcs
> pair
) {
65 final VirtualFile root
= getRootForPath(pair
.getFirst());
66 if (root
== null) return;
67 synchronized (myLock
) {
68 myQueries
.removeValue(new VcsRoot(pair
.getSecond(), root
), pair
.getFirst());
69 myChanged
.remove(pair
.getFirst());
73 public void directoryMappingChanged() {
75 synchronized (myLock
) {
81 public boolean updateStep() {
82 final MultiMap
<VcsRoot
, String
> dirty
= new MultiMap
<VcsRoot
, String
>();
83 final long oldPoint
= System
.currentTimeMillis() - DISCRETE
;
85 synchronized (myLock
) {
86 for (VcsRoot root
: myQueries
.keySet()) {
87 final Collection
<String
> collection
= myQueries
.get(root
);
88 for (String s
: collection
) {
89 dirty
.putValue(root
, s
);
94 final Set
<VcsRoot
> roots
= new HashSet
<VcsRoot
>();
95 for (Map
.Entry
<VcsRoot
, Long
> entry
: myTs
.entrySet()) {
96 if (! dirty
.get(entry
.getKey()).isEmpty()) continue;
98 final Long ts
= entry
.getValue();
99 if ((ts
== null) || (oldPoint
> ts
)) {
100 roots
.add(entry
.getKey());
103 for (Map
.Entry
<String
, Pair
<Boolean
, VcsRoot
>> entry
: myChanged
.entrySet()) {
104 final VcsRoot vcsRoot
= entry
.getValue().getSecond();
105 if ((! dirty
.get(vcsRoot
).isEmpty()) || roots
.contains(vcsRoot
)) {
106 dirty
.putValue(vcsRoot
, entry
.getKey());
111 if (dirty
.isEmpty()) return false;
113 final Map
<String
, Pair
<Boolean
, VcsRoot
>> results
= new HashMap
<String
, Pair
<Boolean
, VcsRoot
>>();
114 for (VcsRoot vcsRoot
: dirty
.keySet()) {
115 final TreeDiffProvider provider
= vcsRoot
.vcs
.getTreeDiffProvider();
116 if (provider
== null) continue;
118 final Collection
<String
> paths
= dirty
.get(vcsRoot
);
119 final Collection
<String
> remotelyChanged
= provider
.getRemotelyChanged(vcsRoot
.path
, paths
);
120 for (String path
: paths
) {
121 results
.put(path
, new Pair
<Boolean
, VcsRoot
>(remotelyChanged
.contains(path
), vcsRoot
));
125 final long curTime
= System
.currentTimeMillis();
126 synchronized (myLock
) {
127 myChanged
.putAll(results
);
128 for (VcsRoot vcsRoot
: dirty
.keySet()) {
129 myTs
.put(vcsRoot
, curTime
);