Skip to content

Commit 35b4d3e

Browse files
authored
Merge pull request #5 from cloudant-labs/close-after-delete
Fix close after delete
2 parents ee3c848 + 318d01b commit 35b4d3e

File tree

3 files changed

+45
-15
lines changed

3 files changed

+45
-15
lines changed

src/main/java/com/cloudant/fdblucene/FDBDirectory.java

+3-12
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
*/
5252
public final class FDBDirectory extends Directory {
5353

54-
private static class FileMetaData {
54+
static class FileMetaData {
5555

5656
private final Tuple asTuple;
5757

@@ -241,7 +241,8 @@ public IndexOutput createOutput(final String name, final IOContext context) thro
241241
}
242242

243243
final String resourceDescription = String.format("FDBIndexOutput(name=%s,number=%d)", name, fileNumber);
244-
return new FDBIndexOutput(this, resourceDescription, name, txc, fileSubspace(fileNumber), pageSize, txnSize);
244+
return new FDBIndexOutput(this, resourceDescription, name, txc, metaKey(name), fileSubspace(fileNumber),
245+
pageSize, txnSize);
245246
}
246247

247248
/**
@@ -296,16 +297,6 @@ public long fileLength(final String name) throws IOException {
296297
return meta.getFileLength();
297298
}
298299

299-
void setFileLength(final TransactionContext txc, final String name, final long length) {
300-
final byte[] metaKey = metaKey(name);
301-
txc.run(txn -> {
302-
final byte[] value = txn.get(metaKey).join();
303-
final FileMetaData meta = new FileMetaData(value).setFileLength(length);
304-
txn.set(metaKey, meta.pack());
305-
return null;
306-
});
307-
}
308-
309300
@Override
310301
public String[] listAll() throws IOException {
311302
final Range metaRange = metaRange();

src/main/java/com/cloudant/fdblucene/FDBIndexOutput.java

+29-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.io.IOException;
1919
import java.util.concurrent.CompletableFuture;
20+
import java.util.function.Consumer;
2021
import java.util.zip.CRC32;
2122

2223
import org.apache.lucene.store.IndexOutput;
@@ -25,6 +26,7 @@
2526
import com.apple.foundationdb.TransactionContext;
2627
import com.apple.foundationdb.async.AsyncUtil;
2728
import com.apple.foundationdb.subspace.Subspace;
29+
import com.cloudant.fdblucene.FDBDirectory.FileMetaData;
2830

2931
public final class FDBIndexOutput extends IndexOutput {
3032

@@ -59,6 +61,7 @@ private static byte[] pageKey(final Subspace subspace, final long pos, final int
5961

6062
private final FDBDirectory dir;
6163
private final TransactionContext txc;
64+
private final byte[] metaKey;
6265
private final Subspace subspace;
6366
private byte[] txnBuffer;
6467

@@ -74,10 +77,12 @@ private static byte[] pageKey(final Subspace subspace, final long pos, final int
7477
private final int txnSize;
7578

7679
FDBIndexOutput(final FDBDirectory dir, final String resourceDescription, final String name,
77-
final TransactionContext txc, final Subspace subspace, final int pageSize, final int txnSize) {
80+
final TransactionContext txc, final byte[] metaKey, final Subspace subspace, final int pageSize,
81+
final int txnSize) {
7882
super(resourceDescription, name);
7983
this.dir = dir;
8084
this.txc = txc;
85+
this.metaKey = metaKey;
8186
this.subspace = subspace;
8287
this.readVersionCache = new ReadVersionCache();
8388
this.pageSize = pageSize;
@@ -97,7 +102,7 @@ public void close() throws IOException {
97102
flushTxnBuffer(subspace, txn, txnBuffer, txnBufferOffset, pointer, pageSize);
98103
txn.options().setNextWriteNoWriteConflictRange();
99104

100-
dir.setFileLength(txn, getName(), pointer);
105+
setFileLength(txn, pointer);
101106
return null;
102107
});
103108
}
@@ -149,7 +154,9 @@ private void flushTxnBuffer() {
149154
lastFlushFuture = txc.runAsync(txn -> {
150155
readVersionCache.setReadVersion(txn);
151156
txn.options().setTransactionLoggingEnable(String.format("%s,out,flush,%d", getName(), pointer));
152-
flushTxnBuffer(subspace, txn, txnBuffer, txnBufferOffset, pointer, pageSize);
157+
applyIfExists(txn, value -> {
158+
flushTxnBuffer(subspace, txn, txnBuffer, txnBufferOffset, pointer, pageSize);
159+
});
153160
return AsyncUtil.DONE;
154161
});
155162
}
@@ -160,4 +167,23 @@ private void flushTxnBufferIfFull() {
160167
}
161168
}
162169

170+
private void setFileLength(final TransactionContext txc, final long length) {
171+
txc.run(txn -> {
172+
applyIfExists(txn, value -> {
173+
final FileMetaData meta = new FileMetaData(value).setFileLength(length);
174+
txn.set(metaKey, meta.pack());
175+
});
176+
return null;
177+
});
178+
}
179+
180+
private void applyIfExists(final Transaction txn, final Consumer<byte[]> fun) {
181+
txn.get(metaKey).thenApply(value -> {
182+
if (value != null) {
183+
fun.accept(value);
184+
}
185+
return null;
186+
}).join();
187+
}
188+
163189
}

src/test/java/com/cloudant/fdblucene/SimpleFDBDirectoryTest.java

+13
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,19 @@ public void addIndexes() throws Exception {
186186
}
187187
}
188188

189+
@Test
190+
public void testCloseAfterDeleteShouldntThrow() throws Exception {
191+
final Directory dir = FDBDirectory.open(DB, FileSystems.getDefault().getPath("lucene", "test1"));
192+
assertCloseDoesntThrowOnDeletedFile(dir);
193+
}
194+
195+
private void assertCloseDoesntThrowOnDeletedFile(final Directory dir) throws Exception {
196+
cleanupDir(dir);
197+
final IndexOutput out = dir.createOutput("foo", null);
198+
dir.deleteFile("foo");
199+
out.close();
200+
}
201+
189202
private void addDocument(final IndexWriter writer, final String docId) throws IOException {
190203
final Document doc = new Document();
191204
doc.add(new TextField("foo", "hello everybody", Store.NO));

0 commit comments

Comments
 (0)