Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

ISPN-2869 Optimize GridInputStream.skip()

* Simplify GridInputStream
* Improved test for GridInputStream.skip() & small bug fix
* Add test for GridInputStream.available()
  • Loading branch information...
commit 202f93a7fd8eef5cf18342c2aa7160e3ac5ce87c 1 parent 7b6120b
@luksa luksa authored galderz committed
View
62 core/src/main/java/org/infinispan/io/GridInputStream.java
@@ -36,27 +36,22 @@
private int index = 0; // index into the file for writing
private int localIndex = 0;
private byte[] currentBuffer = null;
- private boolean endReached = false;
+ private int fileSize;
private boolean closed = false;
private FileChunkMapper fileChunkMapper;
GridInputStream(GridFile file, Cache<String, byte[]> cache) {
fileChunkMapper = new FileChunkMapper(file, cache);
+ fileSize = (int)file.length();
}
@Override
public int read() throws IOException {
checkClosed();
- int remaining = getBytesRemainingInChunk();
- if (remaining == 0) {
- if (endReached)
- return -1;
- fetchNextChunk();
- if (currentBuffer == null)
- return -1;
- else if (isLastChunk())
- endReached = true;
- }
+ if (isEndReached())
+ return -1;
+ if (getBytesRemainingInChunk() == 0)
+ fetchChunk();
int retval = 0x0ff&currentBuffer[localIndex++];
index++;
return retval;
@@ -84,15 +79,11 @@ public int read(byte[] b, int off, int len) throws IOException {
}
private int readFromChunk(byte[] b, int off, int len) {
+ if (isEndReached())
+ return -1;
int remaining = getBytesRemainingInChunk();
if (remaining == 0) {
- if (endReached)
- return -1;
- fetchNextChunk();
- if (currentBuffer == null)
- return -1;
- else if (isLastChunk())
- endReached = true;
+ fetchChunk();
remaining = getBytesRemainingInChunk();
}
int bytesToRead = Math.min(len, remaining);
@@ -102,19 +93,21 @@ else if (isLastChunk())
return bytesToRead;
}
- private boolean isLastChunk() {
- return currentBuffer.length < getChunkSize();
- }
-
@Override
public long skip(long len) throws IOException {
- checkClosed();
- //naive and inefficient, but working
- long count = 0;
- while(len!=count && read()!=-1){
- count++;
- }
- return count;
+ checkClosed();
+ if (len <= 0)
+ return 0;
+
+ int bytesToSkip = Math.min((int)len, getBytesRemainingInStream());
+ index += bytesToSkip;
+ if (bytesToSkip <= getBytesRemainingInChunk()) {
+ localIndex += bytesToSkip;
+ } else {
+ fetchChunk();
+ localIndex = index % getChunkSize();
+ }
+ return bytesToSkip;
}
@Override
@@ -126,10 +119,13 @@ public int available() throws IOException {
@Override
public void close() throws IOException {
localIndex = index = 0;
- endReached = false;
closed = true;
}
+ private boolean isEndReached() {
+ return index == fileSize;
+ }
+
private void checkClosed() throws IOException{
if(closed){
throw new IOException("Stream is closed");
@@ -140,7 +136,11 @@ private int getBytesRemainingInChunk() {
return currentBuffer == null ? 0 : currentBuffer.length - localIndex;
}
- private void fetchNextChunk() {
+ private int getBytesRemainingInStream() {
+ return fileSize - index;
+ }
+
+ private void fetchChunk() {
currentBuffer = fileChunkMapper.fetchChunk(getChunkNumber());
localIndex = 0;
}
View
72 core/src/test/java/org/infinispan/io/GridFileTest.java
@@ -334,30 +334,62 @@ public void testCanReadClosed() throws Exception {
assertNotNull(e);
}
+ public void testSkip() throws Exception {
+ String filePath = "skip.txt";
+ writeToFile(filePath, "abcde" + "fghij" + "klmno" + "pqrst" + "uvwxy" + "z", 5);
+ InputStream in = fs.getInput(filePath);
+ try {
+ long skipped = in.skip(2); // skip inside current chunk
+ assertEquals(skipped, 2);
+ assertEquals((char)in.read(), 'c');
+ skipped = in.skip(2); // skip to end of chunk
+ assertEquals(skipped, 2);
+ assertEquals((char)in.read(), 'f');
- public void testSkipAndAvailable() throws Exception {
- String filePath = "skip.dat";
- OutputStream out = fs.getOutput(filePath);
- try{
- out.write(1);
- out.write(2);
- out.write(3);
- }finally{
- out.close();
- }
- InputStream in = fs.getInput(filePath);
- try{
- long skipped = in.skip(2);
- assertEquals(skipped, 2);
- assertEquals(in.read(), 3);
- }finally{
- in.close();
- }
- }
+ skipped = in.skip(6); // skip into next chunk
+ assertEquals(skipped, 6);
+ assertEquals((char)in.read(), 'm');
+
+ skipped = in.skip(9); // skip _over_ next chunk
+ assertEquals(skipped, 9);
+ assertEquals((char)in.read(), 'w');
+
+ skipped = in.skip(-1); // negative skip
+ assertEquals(skipped, 0);
+ assertEquals((char)in.read(), 'x');
+
+ skipped = in.skip(10); // skip beyond EOF
+ assertEquals(skipped, 2);
+ assertEquals(in.read(), -1);
+ } finally {
+ in.close();
+ }
+ }
+
+ @SuppressWarnings("ResultOfMethodCallIgnored")
+ public void testAvailable() throws Exception {
+ String filePath = "available.txt";
+ writeToFile(filePath, "abcde" + "fghij" + "klmno" + "pqrst" + "uvwxy" + "z", 5);
+
+ InputStream in = fs.getInput(filePath);
+ try {
+ assertEquals(in.available(), 0); // since first chunk hasn't been fetched yet
+ in.read();
+ assertEquals(in.available(), 4);
+ in.skip(3);
+ assertEquals(in.available(), 1);
+ in.read();
+ assertEquals(in.available(), 0);
+ in.read();
+ assertEquals(in.available(), 4);
+ } finally {
+ in.close();
+ }
+ }
- public void testLastModified() throws Exception {
+ public void testLastModified() throws Exception {
assertEquals(fs.getFile("nonExistentFile.txt").lastModified(), 0);
long time1 = System.currentTimeMillis();
Please sign in to comment.
Something went wrong with that request. Please try again.