Author: johan
Date: Tue Apr 6 13:37:38 2010
New Revision: 931148
URL: http://svn.apache.org/viewvc?rev=931148&view=rev
Log:
Cache BufferedRandomAccessFile.length result to avoid native call. Patch by
johan, review by jbellis. CASSANDRA-950
Added:
cassandra/trunk/test/unit/org/apache/cassandra/io/util/
cassandra/trunk/test/unit/org/apache/cassandra/io/util/BufferedRandomAccessFileTest.java
Modified:
cassandra/trunk/src/java/org/apache/cassandra/io/util/BufferedRandomAccessFile.java
Modified:
cassandra/trunk/src/java/org/apache/cassandra/io/util/BufferedRandomAccessFile.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/io/util/BufferedRandomAccessFile.java?rev=931148&r1=931147&r2=931148&view=diff
==============================================================================
---
cassandra/trunk/src/java/org/apache/cassandra/io/util/BufferedRandomAccessFile.java
(original)
+++
cassandra/trunk/src/java/org/apache/cassandra/io/util/BufferedRandomAccessFile.java
Tue Apr 6 13:37:38 2010
@@ -57,6 +57,7 @@ public class BufferedRandomAccessFile ex
private boolean hitEOF_; // buffer contains last file block?
private long diskPos_; // disk position
private long markedPointer;
+ private long fileLength = -1; // cache for file size
/*
* To describe the above fields, we introduce the following abstractions for
@@ -125,7 +126,7 @@ public class BufferedRandomAccessFile ex
{
super(file, mode);
path_ = file.getAbsolutePath();
- this.init(size);
+ this.init(size, mode);
}
/**
@@ -138,14 +139,14 @@ public class BufferedRandomAccessFile ex
this(name, mode, 0);
}
- public BufferedRandomAccessFile(String name, String mode, int size) throws
FileNotFoundException
+ public BufferedRandomAccessFile(String name, String mode, int size) throws
IOException
{
super(name, mode);
path_ = name;
- this.init(size);
+ this.init(size, mode);
}
- private void init(int size)
+ private void init(int size, String mode) throws IOException
{
this.dirty_ = false;
this.lo_ = this.curr_ = this.hi_ = 0;
@@ -153,6 +154,11 @@ public class BufferedRandomAccessFile ex
this.maxHi_ = (long) BuffSz_;
this.hitEOF_ = false;
this.diskPos_ = 0L;
+ if ("r".equals(mode))
+ {
+ // read only file, we can cache file length
+ this.fileLength = super.length();
+ }
}
public String getPath()
@@ -266,8 +272,16 @@ public class BufferedRandomAccessFile ex
public long length() throws IOException
{
- // max accounts for the case where we have written past the old file
length, but not yet flushed our buffer
- return Math.max(this.curr_, super.length());
+ if (fileLength == -1)
+ {
+ // max accounts for the case where we have written past the old
file length, but not yet flushed our buffer
+ return Math.max(this.curr_, super.length());
+ }
+ else
+ {
+ // opened as read only, file length is cached
+ return fileLength;
+ }
}
public int read() throws IOException
Added:
cassandra/trunk/test/unit/org/apache/cassandra/io/util/BufferedRandomAccessFileTest.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/test/unit/org/apache/cassandra/io/util/BufferedRandomAccessFileTest.java?rev=931148&view=auto
==============================================================================
---
cassandra/trunk/test/unit/org/apache/cassandra/io/util/BufferedRandomAccessFileTest.java
(added)
+++
cassandra/trunk/test/unit/org/apache/cassandra/io/util/BufferedRandomAccessFileTest.java
Tue Apr 6 13:37:38 2010
@@ -0,0 +1,48 @@
+package org.apache.cassandra.io.util;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.junit.Test;
+
+public class BufferedRandomAccessFileTest
+{
+
+ @Test
+ public void testLength() throws IOException
+ {
+ File tmpFile = File.createTempFile("lengthtest", "bin");
+ BufferedRandomAccessFile rw = new BufferedRandomAccessFile(tmpFile,
"rw");
+ assertEquals(0, rw.length());
+
+ // write a chunk smaller then our buffer, so will not be flushed
+ // to disk
+ byte[] lessThenBuffer = new byte[BufferedRandomAccessFile.BuffSz_ / 2];
+ rw.write(lessThenBuffer);
+ assertEquals(lessThenBuffer.length, rw.length());
+
+ // sync the data and check length
+ rw.sync();
+ assertEquals(lessThenBuffer.length, rw.length());
+
+ // write more then the buffer can hold and check length
+ byte[] biggerThenBuffer = new byte[BufferedRandomAccessFile.BuffSz_ *
2];
+ rw.write(biggerThenBuffer);
+ assertEquals(biggerThenBuffer.length + lessThenBuffer.length,
rw.length());
+
+ // checking that reading doesn't interfere
+ rw.seek(0);
+ rw.read();
+ assertEquals(biggerThenBuffer.length + lessThenBuffer.length,
rw.length());
+
+ rw.close();
+
+ // will use cachedlength
+ BufferedRandomAccessFile r = new BufferedRandomAccessFile(tmpFile,
"r");
+ assertEquals(lessThenBuffer.length + biggerThenBuffer.length,
r.length());
+ r.close();
+ }
+
+}