@Nullable public String listNameIfOnlyOne(final @Nullable Change[] changes) { if (changes == null || changes.length == 0) { return null; } final Change first = changes[0]; for (LocalChangeList list : myMap.values()) { final Collection<Change> listChanges = list.getChanges(); if (listChanges.contains(first)) { // must contain all other for (int i = 1; i < changes.length; i++) { final Change change = changes[i]; if (!listChanges.contains(change)) { return null; } } return list.getName(); } } return null; }
public boolean updateStep() { final MultiMap<VcsRoot, String> dirty = new MultiMap<VcsRoot, String>(); final long oldPoint = System.currentTimeMillis() - (myVcsConfiguration.CHANGED_ON_SERVER_INTERVAL > 0 ? myVcsConfiguration.CHANGED_ON_SERVER_INTERVAL * 60000 : DISCRETE); synchronized (myLock) { // just copies myQueries MultiMap to dirty MultiMap for (VcsRoot root : myQueries.keySet()) { final Collection<String> collection = myQueries.get(root); for (String s : collection) { dirty.putValue(root, s); } } myQueries.clear(); // collect roots for which cache update should be performed (by timestamp) final Set<VcsRoot> roots = new HashSet<VcsRoot>(); for (Map.Entry<VcsRoot, Long> entry : myTs.entrySet()) { // ignore timestamp, as still remote changes checking is required // TODO: why not to add in roots anyway??? - as dirty is still checked when adding myChanged // files. if (!dirty.get(entry.getKey()).isEmpty()) continue; // update only if timeout expired final Long ts = entry.getValue(); if ((ts == null) || (oldPoint > ts)) { roots.add(entry.getKey()); } } // Add dirty files from those vcs roots, that // - needs to be update by timestamp criteria // - that already contain files for update through manually added requests for (Map.Entry<String, Pair<Boolean, VcsRoot>> entry : myChanged.entrySet()) { final VcsRoot vcsRoot = entry.getValue().getSecond(); if ((!dirty.get(vcsRoot).isEmpty()) || roots.contains(vcsRoot)) { dirty.putValue(vcsRoot, entry.getKey()); } } } if (dirty.isEmpty()) return false; final Map<String, Pair<Boolean, VcsRoot>> results = new HashMap<String, Pair<Boolean, VcsRoot>>(); for (VcsRoot vcsRoot : dirty.keySet()) { // todo - actually it means nothing since the only known VCS to use this scheme is Git and now // it always allow // todo - background operations. when it changes, develop more flexible behavior here if (!vcsRoot.getVcs().isVcsBackgroundOperationsAllowed(vcsRoot.getPath())) continue; final TreeDiffProvider provider = vcsRoot.getVcs().getTreeDiffProvider(); if (provider == null) continue; final Collection<String> paths = dirty.get(vcsRoot); final Collection<String> remotelyChanged = provider.getRemotelyChanged(vcsRoot.getPath(), paths); for (String path : paths) { // TODO: Contains invoked for each file - better to use Set (implementations just use List) // TODO: Why to store boolean for changed or not - why not just remove such values from // myChanged??? results.put(path, new Pair<Boolean, VcsRoot>(remotelyChanged.contains(path), vcsRoot)); } } final long curTime = System.currentTimeMillis(); synchronized (myLock) { myChanged.putAll(results); for (VcsRoot vcsRoot : dirty.keySet()) { myTs.put(vcsRoot, curTime); } } return true; }
public boolean updateStep(final AtomicSectionsAware atomicSectionsAware) { final MultiMap<VcsRoot, String> dirty = new MultiMap<VcsRoot, String>(); final long oldPoint = System.currentTimeMillis() - (myVcsConfiguration.CHANGED_ON_SERVER_INTERVAL > 0 ? myVcsConfiguration.CHANGED_ON_SERVER_INTERVAL * 60000 : DISCRETE); synchronized (myLock) { for (VcsRoot root : myQueries.keySet()) { final Collection<String> collection = myQueries.get(root); for (String s : collection) { dirty.putValue(root, s); } } myQueries.clear(); final Set<VcsRoot> roots = new HashSet<VcsRoot>(); for (Map.Entry<VcsRoot, Long> entry : myTs.entrySet()) { if (!dirty.get(entry.getKey()).isEmpty()) continue; final Long ts = entry.getValue(); if ((ts == null) || (oldPoint > ts)) { roots.add(entry.getKey()); } } for (Map.Entry<String, Pair<Boolean, VcsRoot>> entry : myChanged.entrySet()) { final VcsRoot vcsRoot = entry.getValue().getSecond(); if ((!dirty.get(vcsRoot).isEmpty()) || roots.contains(vcsRoot)) { dirty.putValue(vcsRoot, entry.getKey()); } } } if (dirty.isEmpty()) return false; final Map<String, Pair<Boolean, VcsRoot>> results = new HashMap<String, Pair<Boolean, VcsRoot>>(); for (VcsRoot vcsRoot : dirty.keySet()) { atomicSectionsAware.checkShouldExit(); // todo - actually it means nothing since the only known VCS to use this scheme is Git and now // it always allow // todo - background operations. when it changes, develop more flexible behavior here if (!vcsRoot.vcs.isVcsBackgroundOperationsAllowed(vcsRoot.path)) continue; final TreeDiffProvider provider = vcsRoot.vcs.getTreeDiffProvider(); if (provider == null) continue; final Collection<String> paths = dirty.get(vcsRoot); final Collection<String> remotelyChanged = provider.getRemotelyChanged(vcsRoot.path, paths); for (String path : paths) { results.put(path, new Pair<Boolean, VcsRoot>(remotelyChanged.contains(path), vcsRoot)); } } final long curTime = System.currentTimeMillis(); synchronized (myLock) { myChanged.putAll(results); for (VcsRoot vcsRoot : dirty.keySet()) { myTs.put(vcsRoot, curTime); } } return true; }