62
62
* <p>
63
63
* No methods are thread-safe between each other. E.g.,
64
64
* {@link #complete()} should only be called by a single thread after all
65
- * additions of {@link PendingFileDeletion}s and {@link PendingFileRenaming}s
66
- * are indicated.
65
+ * additions of {@link PendingSymlinkage}s, {@link PendingFileDeletion}s, and
66
+ * {@link PendingFileRenaming}s are indicated.
67
67
* <p>
68
68
* {@link #add(org.opengrok.indexer.index.PendingSymlinkage)} should only
69
69
* be called in serial from a single thread in an isolated stage.
@@ -88,6 +88,8 @@ class PendingFileCompleter {
88
88
89
89
private final Object INSTANCE_LOCK = new Object ();
90
90
91
+ private volatile boolean completing ;
92
+
91
93
/**
92
94
* Descending path segment length comparator.
93
95
*/
@@ -121,8 +123,12 @@ class PendingFileCompleter {
121
123
* @param e element to be added to this set
122
124
* @return {@code true} if this instance's set did not already contain the
123
125
* specified element
126
+ * @throws IllegalStateException if {@link #complete()} is running
124
127
*/
125
128
public boolean add (PendingFileDeletion e ) {
129
+ if (completing ) {
130
+ throw new IllegalStateException ("complete() is running" );
131
+ }
126
132
return deletions .add (e );
127
133
}
128
134
@@ -132,8 +138,12 @@ public boolean add(PendingFileDeletion e) {
132
138
* @param e element to be added to this set
133
139
* @return {@code true} if this instance's set did not already contain the
134
140
* specified element
141
+ * @throws IllegalStateException if {@link #complete()} is running
135
142
*/
136
143
public boolean add (PendingSymlinkage e ) {
144
+ if (completing ) {
145
+ throw new IllegalStateException ("complete() is running" );
146
+ }
137
147
return linkages .add (e );
138
148
}
139
149
@@ -145,8 +155,12 @@ public boolean add(PendingSymlinkage e) {
145
155
* @param e element to be added to this set
146
156
* @return {@code true} if this instance's set did not already contain the
147
157
* specified element
158
+ * @throws IllegalStateException if {@link #complete()} is running
148
159
*/
149
160
public boolean add (PendingFileRenaming e ) {
161
+ if (completing ) {
162
+ throw new IllegalStateException ("complete() is running" );
163
+ }
150
164
synchronized (INSTANCE_LOCK ) {
151
165
boolean rc = renames .add (e );
152
166
deletions .remove (new PendingFileDeletion (e .getAbsolutePath ()));
@@ -156,7 +170,7 @@ public boolean add(PendingFileRenaming e) {
156
170
157
171
/**
158
172
* Complete all the tracked file operations: first in a stage for pending
159
- * deletions next in a stage for pending renamings, and finally in a stage
173
+ * deletions, next in a stage for pending renamings, and finally in a stage
160
174
* for pending symbolic linkages.
161
175
* <p>
162
176
* All operations in each stage are tried in parallel, and any failure is
@@ -171,6 +185,15 @@ public boolean add(PendingFileRenaming e) {
171
185
* @throws java.io.IOException if an I/O error occurs
172
186
*/
173
187
public int complete () throws IOException {
188
+ completing = true ;
189
+ try {
190
+ return completeInner ();
191
+ } finally {
192
+ completing = false ;
193
+ }
194
+ }
195
+
196
+ private int completeInner () throws IOException {
174
197
Instant start = Instant .now ();
175
198
int numDeletions = completeDeletions ();
176
199
if (LOGGER .isLoggable (Level .FINE )) {
@@ -346,8 +369,7 @@ private int completeLinkages() throws IOException {
346
369
347
370
private void doDelete (PendingFileDeletionExec del ) {
348
371
File f = new File (TandemPath .join (del .absolutePath , PENDING_EXTENSION ));
349
- File parent = f .getParentFile ();
350
- del .absoluteParent = parent ;
372
+ del .absoluteParent = f .getParentFile ();
351
373
352
374
doDelete (f );
353
375
f = new File (del .absolutePath );
@@ -436,10 +458,7 @@ private boolean needLink(PendingSymlinkageExec lnk) {
436
458
return true ;
437
459
}
438
460
// not needed if source's canonical matches re-resolved target canonical
439
- if (tgtCanonical .equals (srcCanonical )) {
440
- return false ;
441
- }
442
- return true ;
461
+ return !tgtCanonical .equals (srcCanonical );
443
462
}
444
463
445
464
/**
@@ -488,9 +507,7 @@ private void tryDeleteParents(List<PendingFileDeletionExec> dels) {
488
507
for (File dir : parents ) {
489
508
skels .reset ();
490
509
findFilelessChildren (skels , dir );
491
- skels .childDirs .forEach ((childDir ) -> {
492
- tryDeleteDirectory (childDir );
493
- });
510
+ skels .childDirs .forEach (this ::tryDeleteDirectory );
494
511
tryDeleteDirectory (dir );
495
512
}
496
513
}
@@ -572,7 +589,7 @@ private static int countPathSegments(String path) {
572
589
}
573
590
574
591
private static class PendingFileDeletionExec {
575
- String absolutePath ;
592
+ final String absolutePath ;
576
593
File absoluteParent ;
577
594
IOException exception ;
578
595
PendingFileDeletionExec (String absolutePath ) {
@@ -581,8 +598,8 @@ private static class PendingFileDeletionExec {
581
598
}
582
599
583
600
private static class PendingFileRenamingExec {
584
- String source ;
585
- String target ;
601
+ final String source ;
602
+ final String target ;
586
603
IOException exception ;
587
604
PendingFileRenamingExec (String source , String target ) {
588
605
this .source = source ;
@@ -591,8 +608,8 @@ private static class PendingFileRenamingExec {
591
608
}
592
609
593
610
private static class PendingSymlinkageExec {
594
- String source ;
595
- String targetRel ;
611
+ final String source ;
612
+ final String targetRel ;
596
613
IOException exception ;
597
614
PendingSymlinkageExec (String source , String relTarget ) {
598
615
this .source = source ;
0 commit comments