Skip to content

Commit

Permalink
applied a couple of improvements to the PR as discussed with Rei.
Browse files Browse the repository at this point in the history
re-compiled the CapiOSInfo.class to be target=1.5
replaced the CompletableFuture with a custom implementation since it requires Java 1.8
simplified the handling in the timeout test for the emulation case (which never times out)
  • Loading branch information
Jan S. Rellermeyer committed May 18, 2017
1 parent ae92970 commit 403f543
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 103 deletions.
59 changes: 32 additions & 27 deletions src/java/capiblock/com/ibm/research/capiblock/CapiBlockDevice.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,37 +49,41 @@ public class CapiBlockDevice {
* the block size in Bytes
*/
public static final int BLOCK_SIZE = 4096;
public static final String CAPI_BLOCK_VERBOSE_PROPERTY_NAME = "com.ibm.research.capiblock.verbose"; //$NON-NLS-1$
public static final String CAPI_BLOCK_EMULATION_PROPERTY_NAME = "com.ibm.research.capiblock.emulation"; //$NON-NLS-1$
public static final String CAPI_BLOCK_CAPACITY_PROPERTY_NAME = "com.ibm.research.capiblock.capacity"; //$NON-NLS-1$

private static boolean useEmulation = false;
private static boolean verbose = Boolean.parseBoolean(System.getProperty("capi.block.verbose", "false"));
private static boolean verbose = Boolean.parseBoolean(System.getProperty(CAPI_BLOCK_VERBOSE_PROPERTY_NAME, "false"));

static {
initialize();
}

// Have this private static method because a static initializer cannot have return in it.
private static void initialize() {
String emulationProperty = System.getProperty("capi.block.emulation");
final String emulationProperty = System.getProperty(CAPI_BLOCK_EMULATION_PROPERTY_NAME);
if (emulationProperty != null) {
useEmulation = Boolean.parseBoolean(emulationProperty);
useEmulation = Boolean.getBoolean(CAPI_BLOCK_EMULATION_PROPERTY_NAME);
if (useEmulation) {
if (verbose) {
System.err.println("WARNING: CAPI block library will use emulation");
System.err.println("WARNING: CAPI block library will use emulation"); //$NON-NLS-1$
}
return;
}
}

String resourceName = "/linux/" + System.getProperty("os.arch") + "/libcapiblock.so";
InputStream is = CapiBlockDevice.class.getResourceAsStream(resourceName);
final String resourceName = "/linux/" + System.getProperty("os.arch") + "/libcapiblock.so"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
final InputStream is = CapiBlockDevice.class.getResourceAsStream(resourceName);
if (is == null) {
if (emulationProperty != null && !useEmulation) {
// The user explicitly disabled the emulation,
// but cannot find the JNI library, so throw an exception.
throw new UnsupportedOperationException("Unsupported OS/arch. Cannot find " + resourceName);
throw new UnsupportedOperationException("Unsupported OS/arch. Cannot find " + resourceName); //$NON-NLS-1$
} else {
useEmulation = true;
if (verbose) {
System.err.println("WARNING: CAPI block library will use emulation");
System.err.println("WARNING: CAPI block library will use emulation"); //$NON-NLS-1$
}
return;
}
Expand All @@ -88,10 +92,10 @@ private static void initialize() {
boolean loaded = false;
FileOutputStream out = null;
try {
tempLib = File.createTempFile("libcapiblock", ".so");
tempLib = File.createTempFile("libcapiblock", ".so"); //$NON-NLS-1$ //$NON-NLS-2$
out = new FileOutputStream(tempLib);

byte[] buf = new byte[4096];
final byte[] buf = new byte[4096];
while (true) {
int read = is.read(buf);
if (read == -1) {
Expand All @@ -103,15 +107,15 @@ private static void initialize() {
out = null;
System.load(tempLib.getAbsolutePath());
loaded = true;
} catch (IOException ex) {
} catch (final IOException ex) {
if (emulationProperty != null && !useEmulation) {
// The user explicitly disabled the emulation,
// but cannot load the JNI library, so throw an exception.
throw new ExceptionInInitializerError("Cannot load libcapiblock");
throw new ExceptionInInitializerError("Cannot load libcapiblock"); //$NON-NLS-1$
} else {
useEmulation = true;
if (verbose) {
System.err.println("WARNING: CAPI block library will use emulation");
System.err.println("WARNING: CAPI block library will use emulation"); //$NON-NLS-1$
}
return;
}
Expand All @@ -120,7 +124,8 @@ private static void initialize() {
if (out != null) {
out.close();
}
} catch (IOException ex) {
} catch (final IOException ex) {
// ignore exception during close
}
if (tempLib != null && tempLib.exists()) {
if (!loaded) {
Expand All @@ -146,9 +151,9 @@ public static synchronized CapiBlockDevice getInstance() {
if (instance == null) {
instance = new CapiBlockDevice();
if (useEmulation) {
String capacityProperty = System.getProperty("capi.block.capacity");
final String capacityProperty = System.getProperty(CAPI_BLOCK_CAPACITY_PROPERTY_NAME);
if (capacityProperty == null) {
throw new IllegalStateException("Necessary property capi.block.capacity is not set");
throw new IllegalStateException("Necessary property com.ibm.research.capiblock.capacity is not set"); //$NON-NLS-1$
}
capacity = Integer.parseInt(capacityProperty);
}
Expand All @@ -161,7 +166,7 @@ public static synchronized CapiBlockDevice getInstance() {
*
* @return true, if the CAPI Flash emulation is being used. false, otherwise.
*/
public boolean useEmulation() {
public boolean isEmulated() {
return useEmulation;
}

Expand Down Expand Up @@ -191,20 +196,20 @@ public Chunk openChunk(final String path) throws IOException {
* @throws IOException
* when the operation failed.
*/
public Chunk openChunk(final String path, int maxRequests)
public Chunk openChunk(final String path, final int maxRequests)
throws IOException {
if (useEmulation) {
if (maxRequests < 0) {
throw new IOException("maxRequests must not be negative");
throw new IOException("maxRequests must not be negative"); //$NON-NLS-1$
}
synchronized (this) {
RandomAccessFile f = null;
if (files.containsKey(path)) {
FileAndCounterPair pair = files.get(path);
final FileAndCounterPair pair = files.get(path);
pair.referenceCounter++;
f = pair.file;
} else {
f = new RandomAccessFile(path, "rws");
f = new RandomAccessFile(path, "rws"); //$NON-NLS-1$
f.setLength((long) BLOCK_SIZE * capacity);
files.put(path, new FileAndCounterPair(f));
}
Expand All @@ -215,13 +220,13 @@ public Chunk openChunk(final String path, int maxRequests)
}
}

synchronized void closeEmulation(String path) throws IOException {
synchronized void closeEmulation(final String path) throws IOException {
if (!useEmulation) {
throw new IllegalStateException("closeEmulation() is called when CAPI Flash emulation is not used");
throw new IllegalStateException("closeEmulation() is called when CAPI Flash emulation is not used"); //$NON-NLS-1$
}
FileAndCounterPair pair = files.get(path);
final FileAndCounterPair pair = files.get(path);
if (pair == null) {
throw new IllegalStateException("Trying to close a non-existing CAPI Flash emulation file: " + path);
throw new IllegalStateException("Trying to close a non-existing CAPI Flash emulation file: " + path); //$NON-NLS-1$
}
pair.referenceCounter--;
if (pair.referenceCounter == 0) {
Expand All @@ -231,10 +236,10 @@ synchronized void closeEmulation(String path) throws IOException {
}

private class FileAndCounterPair {
RandomAccessFile file;
final RandomAccessFile file;
int referenceCounter;

FileAndCounterPair(RandomAccessFile file) {
FileAndCounterPair(final RandomAccessFile file) {
this.file = file;
referenceCounter = 1;
}
Expand Down
49 changes: 37 additions & 12 deletions src/java/capiblock/com/ibm/research/capiblock/EmulatedChunk.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* IBM_PROLOG_BEGIN_TAG
* This is an automatically generated prolog.
*
* $Source: src/java/capiblock/com/ibm/research/capiblock/Chunk.java $
* $Source: src/java/capiblock/com/ibm/research/capiblock/EmulatedChunk.java $
*
* IBM Data Engine for NoSQL - Power Systems Edition User Library Project
*
Expand All @@ -28,8 +28,8 @@
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

/**
* Emulated chunk of CAPI Flash, using RandomAccessFile
Expand Down Expand Up @@ -73,9 +73,9 @@ public long writeBlock(final long lba, final long nBlocks, final ByteBuffer buf)
buf.rewind();
buf.limit((int) nBlocks * CapiBlockDevice.BLOCK_SIZE);
synchronized (inChannel) {
inChannel.write(buf, (long) lba * CapiBlockDevice.BLOCK_SIZE);
inChannel.write(buf, lba * CapiBlockDevice.BLOCK_SIZE);
}
} catch (Exception ex) {
} catch (final Exception ex) {
throw new IOException(ex);
}
synchronized (this) {
Expand Down Expand Up @@ -106,11 +106,11 @@ public long readBlock(final long lba, final long nBlocks, final ByteBuffer buf)
int oldLimit = buf.limit();
buf.limit((int) (nBlocks * CapiBlockDevice.BLOCK_SIZE));
synchronized (inChannel) {
inChannel.read(buf, (long) lba * CapiBlockDevice.BLOCK_SIZE);
inChannel.read(buf, lba * CapiBlockDevice.BLOCK_SIZE);
}
buf.limit(oldLimit);
buf.rewind();
} catch (Exception ex) {
} catch (final Exception ex) {
throw new IOException(ex);
}
synchronized (this) {
Expand Down Expand Up @@ -143,9 +143,7 @@ public Future<Long> readBlockAsync(final long lba, final long nBlocks, final Byt
numAReads++;
numReads--;
}
CompletableFuture<Long> future = new CompletableFuture<Long>();
future.complete(retVal);
return (Future<Long>) future;
return new EmulatedFuture(retVal);
}

/**
Expand All @@ -171,9 +169,7 @@ public Future<Long> writeBlockAsync(final long lba, final long nBlocks, final By
numAWrites++;
numWrites--;
}
CompletableFuture<Long> future = new CompletableFuture<Long>();
future.complete(retVal);
return (Future<Long>) future;
return new EmulatedFuture(retVal);
}

/**
Expand Down Expand Up @@ -234,4 +230,33 @@ public Stats getStats() {
0, 0,
0, 0);
}

private static class EmulatedFuture implements Future<Long> {

private final long retVal;

protected EmulatedFuture(final long retVal) {
this.retVal = retVal;
}

public boolean cancel(final boolean ignored) {
return false;
}

public Long get() {
return retVal;
}

public Long get(final long timeout, final TimeUnit unit) {
return retVal;
}

public boolean isCancelled() {
return false;
}

public boolean isDone() {
return true;
}
}
}
Loading

0 comments on commit 403f543

Please sign in to comment.