@@ -311,6 +311,39 @@ public boolean addDirectory(String dir) {
311
311
return false ;
312
312
}
313
313
314
+ private int getFileCount (File sourceRoot , String dir ) throws IOException {
315
+ int file_cnt = 0 ;
316
+ if (RuntimeEnvironment .getInstance ().isPrintProgress ()) {
317
+ LOGGER .log (Level .INFO , "Counting files in {0} ..." , dir );
318
+ file_cnt = indexDown (sourceRoot , dir , true , 0 , 0 );
319
+ LOGGER .log (Level .INFO ,
320
+ "Need to process: {0} files for {1}" ,
321
+ new Object []{file_cnt , dir });
322
+ }
323
+
324
+ return file_cnt ;
325
+ }
326
+
327
+ private void markProjectIndexed (Project project ) throws IOException {
328
+ RuntimeEnvironment env = RuntimeEnvironment .getInstance ();
329
+
330
+ // Successfully indexed the directory. If this is a project
331
+ // that has just been indexed for the first time mark it so
332
+ // by sending special message to the webapp.
333
+ if (project != null && !project .isIndexed ()) {
334
+ if (env .getConfigHost () != null && env .getConfigPort () > 0 ) {
335
+ Message m = Message .createMessage ("project" );
336
+ m .addTag (project .getName ());
337
+ m .setText ("indexed" );
338
+ m .write (env .getConfigHost (), env .getConfigPort ());
339
+ }
340
+
341
+ // Also need to store the correct value in configuration
342
+ // when indexer writes it to a file.
343
+ project .setIndexed (true );
344
+ }
345
+ }
346
+
314
347
/**
315
348
* Update the content of this index database
316
349
*
@@ -337,7 +370,7 @@ public void update() throws IOException, HistoryException {
337
370
}
338
371
339
372
if (ctags != null ) {
340
- String filename = RuntimeEnvironment . getInstance () .getCTagsExtraOptionsFile ();
373
+ String filename = env .getCTagsExtraOptionsFile ();
341
374
if (filename != null ) {
342
375
ctags .setCTagsExtraOptionsFile (filename );
343
376
}
@@ -391,44 +424,25 @@ public void update() throws IOException, HistoryException {
391
424
startuid );
392
425
}
393
426
}
394
- // The code below traverses the tree to get total count.
395
- int file_cnt = 0 ;
396
- if (env .isPrintProgress ()) {
397
- LOGGER .log (Level .INFO , "Counting files in {0} ..." , dir );
398
- file_cnt = indexDown (sourceRoot , dir , true , 0 , 0 );
399
- LOGGER .log (Level .INFO ,
400
- "Need to process: {0} files for {1}" ,
401
- new Object []{file_cnt , dir });
402
- }
403
427
404
428
// The actual indexing happens in indexDown().
405
- indexDown (sourceRoot , dir , false , 0 , file_cnt );
429
+ indexDown (sourceRoot , dir , false , 0 ,
430
+ getFileCount (sourceRoot , dir ));
406
431
432
+ // Remove data for the trailing terms that indexDown()
433
+ // did not traverse. These correspond to files that have been
434
+ // removed and have higher ordering than any present files.
407
435
while (uidIter != null && uidIter .term () != null
408
436
&& uidIter .term ().utf8ToString ().startsWith (startuid )) {
409
437
410
- removeFile ();
438
+ removeFile (true );
411
439
BytesRef next = uidIter .next ();
412
- if (next == null ) {
440
+ if (next == null ) {
413
441
uidIter =null ;
414
442
}
415
443
}
416
444
417
- // Successfully indexed the directory. If this is a project
418
- // that has just been indexed for the first time mark it so
419
- // by sending special message to the webapp.
420
- if (project != null && !project .isIndexed ()) {
421
- if (env .getConfigHost () != null && env .getConfigPort () > 0 ) {
422
- Message m = Message .createMessage ("project" );
423
- m .addTag (project .getName ());
424
- m .setText ("indexed" );
425
- m .write (env .getConfigHost (), env .getConfigPort ());
426
- }
427
-
428
- // Also need to store the correct value in configuration
429
- // when indexer writes it to a file.
430
- project .setIndexed (true );
431
- }
445
+ markProjectIndexed (project );
432
446
} finally {
433
447
reader .close ();
434
448
}
@@ -602,9 +616,10 @@ private void removeHistoryFile(String path) {
602
616
* Remove a stale file (uidIter.term().text()) from the index database,
603
617
* history cache and xref.
604
618
*
619
+ * @param removeHistory if false, do not remove history cache for this file
605
620
* @throws java.io.IOException if an error occurs
606
621
*/
607
- private void removeFile () throws IOException {
622
+ private void removeFile (boolean removeHistory ) throws IOException {
608
623
String path = Util .uid2url (uidIter .term ().utf8ToString ());
609
624
610
625
for (IndexChangedListener listener : listeners ) {
@@ -616,7 +631,9 @@ private void removeFile() throws IOException {
616
631
writer .commit ();
617
632
618
633
removeXrefFile (path );
619
- removeHistoryFile (path );
634
+ if (removeHistory ) {
635
+ removeHistoryFile (path );
636
+ }
620
637
621
638
setDirty ();
622
639
for (IndexChangedListener listener : listeners ) {
@@ -837,16 +854,25 @@ private boolean isLocal(String path) {
837
854
return local ;
838
855
}
839
856
857
+ private void printProgress (int currentCount , int totalCount ) {
858
+ if (RuntimeEnvironment .getInstance ().isPrintProgress ()
859
+ && totalCount > 0 && LOGGER .isLoggable (Level .INFO )) {
860
+ LOGGER .log (Level .INFO , "Progress: {0} ({1}%)" ,
861
+ new Object []{currentCount ,
862
+ (currentCount * 100.0f / totalCount )});
863
+ }
864
+ }
865
+
840
866
/**
841
867
* Generate indexes recursively
842
868
*
843
869
* @param dir the root indexDirectory to generate indexes for
844
- * @param path the path
870
+ * @param parent path to parent directory
845
871
* @param count_only if true will just traverse the source root and count
846
872
* files
847
- * @param cur_count current count during the traversal of the tree
873
+ * @param cur_count current file count during the traversal of the tree
848
874
* @param est_total estimate total files to process
849
- *
875
+ * @return current file count
850
876
*/
851
877
private int indexDown (File dir , String parent , boolean count_only ,
852
878
int cur_count , int est_total ) throws IOException {
@@ -880,30 +906,42 @@ private int indexDown(File dir, String parent, boolean count_only,
880
906
continue ;
881
907
}
882
908
883
- if (RuntimeEnvironment .getInstance ().isPrintProgress ()
884
- && est_total > 0 && LOGGER .isLoggable (Level .INFO )) {
885
- LOGGER .log (Level .INFO , "Progress: {0} ({1}%)" ,
886
- new Object []{lcur_count ,
887
- (lcur_count * 100.0f / est_total )});
888
- }
909
+ printProgress (lcur_count , est_total );
889
910
890
911
if (uidIter != null ) {
891
912
String uid = Util .path2uid (path ,
892
913
DateTools .timeToString (file .lastModified (),
893
914
DateTools .Resolution .MILLISECOND )); // construct uid for doc
894
- BytesRef buid = new BytesRef (uid );
915
+ BytesRef buid = new BytesRef (uid );
916
+ // Traverse terms that have smaller UID than the current
917
+ // file, i.e. given the ordering they positioned before the file
918
+ // or it is the file that has been modified.
895
919
while (uidIter != null && uidIter .term () != null
896
- && uidIter .term ().compareTo (emptyBR ) !=0
920
+ && uidIter .term ().compareTo (emptyBR ) != 0
897
921
&& uidIter .term ().compareTo (buid ) < 0 ) {
898
- removeFile ();
922
+
923
+ // If the term's path matches path of currently processed file,
924
+ // it is clear that the file has been modified and thus
925
+ // removeFile() will be followed by call to addFile() below.
926
+ // In such case, instruct removeFile() not to remove history
927
+ // cache for the file so that incremental history cache
928
+ // generation works.
929
+ String termPath = Util .uid2url (uidIter .term ().utf8ToString ());
930
+ removeFile (!termPath .equals (path ));
931
+
899
932
BytesRef next = uidIter .next ();
900
- if (next ==null ) {uidIter =null ;}
933
+ if (next == null ) {
934
+ uidIter = null ;
935
+ }
901
936
}
902
937
938
+ // If the file was not modified, skip to the next one.
903
939
if (uidIter != null && uidIter .term () != null
904
940
&& uidIter .term ().bytesEquals (buid )) {
905
941
BytesRef next = uidIter .next (); // keep matching docs
906
- if (next ==null ) {uidIter =null ;}
942
+ if (next == null ) {
943
+ uidIter = null ;
944
+ }
907
945
continue ;
908
946
}
909
947
}
0 commit comments