LUCENE-1067: make access to RAMFile's buffers thread safe

git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@598693 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael McCandless 2007-11-27 17:01:21 +00:00
parent 47c8416e68
commit 6ebd306103
3 changed files with 15 additions and 9 deletions

View File

@ -24,8 +24,7 @@ class RAMFile implements Serializable {
private static final long serialVersionUID = 1l; private static final long serialVersionUID = 1l;
// Direct read-only access to state supported for streams since a writing stream implies no other concurrent streams private ArrayList buffers = new ArrayList();
ArrayList buffers = new ArrayList();
long length; long length;
RAMDirectory directory; RAMDirectory directory;
long sizeInBytes; // Only maintained if in a directory; updates synchronized on directory long sizeInBytes; // Only maintained if in a directory; updates synchronized on directory
@ -58,8 +57,7 @@ class RAMFile implements Serializable {
this.lastModified = lastModified; this.lastModified = lastModified;
} }
// Only one writing stream with no concurrent reading streams, so no file synchronization required final synchronized byte[] addBuffer(int size) {
final byte[] addBuffer(int size) {
byte[] buffer = newBuffer(size); byte[] buffer = newBuffer(size);
if (directory!=null) if (directory!=null)
synchronized (directory) { // Ensure addition of buffer and adjustment to directory size are atomic wrt directory synchronized (directory) { // Ensure addition of buffer and adjustment to directory size are atomic wrt directory
@ -72,6 +70,14 @@ class RAMFile implements Serializable {
return buffer; return buffer;
} }
final synchronized byte[] getBuffer(int index) {
return (byte[]) buffers.get(index);
}
final synchronized int numBuffers() {
return buffers.size();
}
/** /**
* Expert: allocate a new buffer. * Expert: allocate a new buffer.
* Subclasses can allocate differently. * Subclasses can allocate differently.

View File

@ -84,11 +84,11 @@ class RAMInputStream extends IndexInput implements Cloneable {
} }
private final void switchCurrentBuffer() throws IOException { private final void switchCurrentBuffer() throws IOException {
if (currentBufferIndex >= file.buffers.size()) { if (currentBufferIndex >= file.numBuffers()) {
// end of file reached, no more buffers left // end of file reached, no more buffers left
throw new IOException("Read past EOF"); throw new IOException("Read past EOF");
} else { } else {
currentBuffer = (byte[]) file.buffers.get(currentBufferIndex); currentBuffer = (byte[]) file.getBuffer(currentBufferIndex);
bufferPosition = 0; bufferPosition = 0;
bufferStart = (long) BUFFER_SIZE * (long) currentBufferIndex; bufferStart = (long) BUFFER_SIZE * (long) currentBufferIndex;
long buflen = length - bufferStart; long buflen = length - bufferStart;

View File

@ -63,7 +63,7 @@ public class RAMOutputStream extends IndexOutput {
if (nextPos > end) { // at the last buffer if (nextPos > end) { // at the last buffer
length = (int)(end - pos); length = (int)(end - pos);
} }
out.writeBytes((byte[])file.buffers.get(buffer++), length); out.writeBytes((byte[])file.getBuffer(buffer++), length);
pos = nextPos; pos = nextPos;
} }
} }
@ -124,10 +124,10 @@ public class RAMOutputStream extends IndexOutput {
} }
private final void switchCurrentBuffer() throws IOException { private final void switchCurrentBuffer() throws IOException {
if (currentBufferIndex == file.buffers.size()) { if (currentBufferIndex == file.numBuffers()) {
currentBuffer = file.addBuffer(BUFFER_SIZE); currentBuffer = file.addBuffer(BUFFER_SIZE);
} else { } else {
currentBuffer = (byte[]) file.buffers.get(currentBufferIndex); currentBuffer = (byte[]) file.getBuffer(currentBufferIndex);
} }
bufferPosition = 0; bufferPosition = 0;
bufferStart = (long) BUFFER_SIZE * (long) currentBufferIndex; bufferStart = (long) BUFFER_SIZE * (long) currentBufferIndex;