@@ -97,6 +97,8 @@ public Set<Object> getAllCachedProject() {
9797 return mapProject2BundleId .keySet ();
9898 }
9999
100+ private static final Map <Object , Set <Object >> mapProject2RemovedFiles = new ConcurrentHashMap <>();
101+
100102 public void removeFilesFromCache (@ NotNull Collection <Object > files ) {
101103 try {
102104 dcLogger .logInfo ("Request to remove from cache " + files .size () + " files: " + files );
@@ -107,6 +109,9 @@ public void removeFilesFromCache(@NotNull Collection<Object> files) {
107109 for (Object file : files ) {
108110 if (file != null && isFileInCache (file )) {
109111 mapFile2Suggestions .remove (file );
112+ mapProject2RemovedFiles
113+ .computeIfAbsent (pdUtils .getProject (file ), p -> new HashSet <>())
114+ .add (file );
110115 hashContentUtils .removeFileHashContent (file );
111116 removeCounter ++;
112117 }
@@ -132,6 +137,7 @@ public void removeProjectFromCaches(@NotNull Object project) {
132137 dcLogger .logInfo ("Removed from cache: " + project );
133138 }
134139 removeFilesFromCache (cachedFilesOfProject (project ));
140+ mapProject2RemovedFiles .remove (project );
135141 }
136142
137143 private Collection <Object > cachedFilesOfProject (@ NotNull Object project ) {
@@ -171,22 +177,20 @@ public void waitForUpdateAnalysisFinish(@NotNull Object project, @Nullable Objec
171177 }
172178 }
173179
174- /*
175- public static void updateCachedResultsForFile(@NotNull Object psiFile) {
176- updateCachedResultsForFiles(Collections.singleton(psiFile), Collections.emptyList());
177- }
178- */
179-
180180 public void updateCachedResultsForFiles (
181181 @ NotNull Object project ,
182- @ NotNull Collection <Object > psiFiles ,
183- @ NotNull Collection <Object > filesToRemove ,
182+ @ NotNull Collection <Object > allProjectFiles ,
184183 @ NotNull Object progress ) {
185- if (psiFiles .isEmpty () && filesToRemove .isEmpty ()) {
184+ Collection <Object > filesToRemove = mapProject2RemovedFiles .remove (project );
185+ if (filesToRemove == null ) filesToRemove = Collections .emptyList ();
186+ // remove from server only files physically removed from Project
187+ filesToRemove .removeAll (allProjectFiles );
188+ if (allProjectFiles .isEmpty () && filesToRemove .isEmpty ()) {
186189 dcLogger .logWarn ("updateCachedResultsForFiles requested for empty list of files" );
187190 return ;
188191 }
189- dcLogger .logInfo ("Update requested for " + psiFiles .size () + " files: " + psiFiles .toString ());
192+ dcLogger .logInfo (
193+ "Update requested for " + allProjectFiles .size () + " files: " + allProjectFiles .toString ());
190194 if (!deepCodeParams .consentGiven (project )) {
191195 dcLogger .logWarn ("Consent check fail! Project: " + pdUtils .getProjectName (project ));
192196 return ;
@@ -196,7 +200,7 @@ public void updateCachedResultsForFiles(
196200 dcLogger .logInfo ("MUTEX LOCK" );
197201 setUpdateInProgress (project );
198202 Collection <Object > filesToProceed =
199- psiFiles .stream ()
203+ allProjectFiles .stream ()
200204 .filter (Objects ::nonNull )
201205 .filter (file -> !mapFile2Suggestions .containsKey (file ))
202206 .collect (Collectors .toSet ());
@@ -212,29 +216,19 @@ public void updateCachedResultsForFiles(
212216 + " ["
213217 + fileHash
214218 + "]" );
215- if (filesToProceed .size () == 1 && filesToRemove .isEmpty ()) {
216- // if only one file updates then its most likely from annotator. So we need to get
217- // suggestions asap:
218- // we do that through createBundle with fileContent
219- mapFile2Suggestions .put (firstFile , retrieveSuggestions (firstFile , progress ));
220- // and then request normal extendBundle later to synchronize results on server
221- pdUtils .runInBackgroundCancellable (
222- firstFile ,
223- "Synchronize analysis result with server..." ,
224- (progress1 ) ->
225- retrieveSuggestions (project , filesToProceed , filesToRemove , progress1 ));
226- } else {
227- mapFile2Suggestions .putAll (
228- retrieveSuggestions (project , filesToProceed , filesToRemove , progress ));
229- }
230219 } else if (!filesToRemove .isEmpty ()) {
220+ dcLogger .logWarn (
221+ "Nothing to update for "
222+ + allProjectFiles .size ()
223+ + " files: "
224+ + allProjectFiles .toString ());
225+ }
226+ if (!filesToRemove .isEmpty ()) {
231227 dcLogger .logInfo (
232228 "Files to remove: " + filesToRemove .size () + " files: " + filesToRemove .toString ());
233- retrieveSuggestions (project , filesToProceed , filesToRemove , progress );
234- } else {
235- dcLogger .logWarn (
236- "Nothing to update for " + psiFiles .size () + " files: " + psiFiles .toString ());
237229 }
230+ mapFile2Suggestions .putAll (
231+ retrieveSuggestions (project , filesToProceed , filesToRemove , progress ));
238232 } finally {
239233 // if (filesToProceed != null && !filesToProceed.isEmpty())
240234 dcLogger .logInfo ("MUTEX RELEASED" );
@@ -286,15 +280,23 @@ private Map<Object, List<SuggestionForFile>> retrieveSuggestions(
286280
287281 List <String > missingFiles = createBundleStep (project , filesToProceed , filesToRemove , progress );
288282
283+ if (filesToProceed .isEmpty ()) { // no sense to proceed
284+ return EMPTY_MAP ;
285+ }
289286 uploadFilesStep (project , filesToProceed , missingFiles , progress );
290287
291288 // ---------------------------------------- Get Analysis
292289 final String bundleId = mapProject2BundleId .getOrDefault (project , "" );
293- if (bundleId .isEmpty ()) return EMPTY_MAP ; // no sense to proceed without bundleId
290+ if (bundleId .isEmpty ()) { // no sense to proceed
291+ return EMPTY_MAP ;
292+ }
294293 long startTime = System .currentTimeMillis ();
295294 pdUtils .progressSetText (progress , WAITING_FOR_ANALYSIS_TEXT );
296295 pdUtils .progressCheckCanceled (progress );
297- GetAnalysisResponse getAnalysisResponse = doGetAnalysis (project , bundleId , progress );
296+ List <String > filesToAnalyse =
297+ filesToProceed .stream ().map (pdUtils ::getDeepCodedFilePath ).collect (Collectors .toList ());
298+ GetAnalysisResponse getAnalysisResponse =
299+ doGetAnalysis (project , bundleId , progress , filesToAnalyse );
298300 Map <Object , List <SuggestionForFile >> result =
299301 parseGetAnalysisResponse (project , filesToProceed , getAnalysisResponse , progress );
300302 dcLogger .logInfo (
@@ -397,59 +399,6 @@ private void uploadFilesStep(
397399 "--- Upload Files took: " + (System .currentTimeMillis () - startTime ) + " milliseconds" );
398400 }
399401
400- /** Perform costly network request. <b>No cache checks!</b> */
401- @ NotNull
402- private List <SuggestionForFile > retrieveSuggestions (
403- @ NotNull Object file , @ NotNull Object progress ) {
404- final Object project = pdUtils .getProject (file );
405- List <SuggestionForFile > result ;
406- long startTime ;
407- // ---------------------------------------- Create Bundle
408- startTime = System .currentTimeMillis ();
409- dcLogger .logInfo ("Creating temporary Bundle from File content" );
410- pdUtils .progressCheckCanceled (progress );
411-
412- FileContent fileContent =
413- new FileContent (pdUtils .getDeepCodedFilePath (file ), hashContentUtils .getFileContent (file ));
414- FileContentRequest fileContentRequest =
415- new FileContentRequest (Collections .singletonList (fileContent ));
416-
417- // todo?? it might be cheaper on server side to extend one temporary bundle
418- // rather then create the new one every time
419- final CreateBundleResponse createBundleResponse =
420- DeepCodeRestApi .createBundle (deepCodeParams .getSessionToken (), fileContentRequest );
421- isNotSucceed (project , createBundleResponse , "Bad Create/Extend Bundle request: " );
422-
423- final String bundleId = createBundleResponse .getBundleId ();
424- if (bundleId .isEmpty ()) return Collections .emptyList (); // no sense to proceed without bundleId
425-
426- List <String > missingFiles = createBundleResponse .getMissingFiles ();
427- dcLogger .logInfo (
428- "--- Create temporary Bundle took: "
429- + (System .currentTimeMillis () - startTime )
430- + " milliseconds"
431- + "\n bundleId: "
432- + bundleId
433- + "\n missingFiles: "
434- + missingFiles );
435- if (!missingFiles .isEmpty ()) dcLogger .logWarn ("missingFiles is NOT empty!" );
436-
437- // ---------------------------------------- Get Analysis
438- pdUtils .progressCheckCanceled (progress );
439- startTime = System .currentTimeMillis ();
440- GetAnalysisResponse getAnalysisResponse = doGetAnalysis (project , bundleId , progress );
441- result =
442- parseGetAnalysisResponse (
443- project , Collections .singleton (file ), getAnalysisResponse , progress )
444- .getOrDefault (file , Collections .emptyList ());
445- mapProject2analysisUrl .put (project , "" );
446-
447- dcLogger .logInfo (
448- "--- Get Analysis took: " + (System .currentTimeMillis () - startTime ) + " milliseconds" );
449- // progress.stop();
450- return result ;
451- }
452-
453402 private void uploadFiles (
454403 @ NotNull Object project ,
455404 @ NotNull Collection <Object > filesToProceed ,
@@ -589,7 +538,10 @@ private void doUploadFiles(
589538
590539 @ NotNull
591540 private GetAnalysisResponse doGetAnalysis (
592- @ NotNull Object project , @ NotNull String bundleId , @ NotNull Object progress ) {
541+ @ NotNull Object project ,
542+ @ NotNull String bundleId ,
543+ @ NotNull Object progress ,
544+ List <String > filesToAnalyse ) {
593545 GetAnalysisResponse response ;
594546 int counter = 0 ;
595547 final int timeout = 100 ; // seconds
@@ -601,7 +553,8 @@ private GetAnalysisResponse doGetAnalysis(
601553 deepCodeParams .getSessionToken (),
602554 bundleId ,
603555 deepCodeParams .getMinSeverity (),
604- deepCodeParams .useLinter ());
556+ deepCodeParams .useLinter (),
557+ filesToAnalyse );
605558
606559 pdUtils .progressCheckCanceled (progress );
607560 dcLogger .logInfo (response .toString ());
0 commit comments