From: <tho...@us...> - 2011-03-08 15:12:50
|
Revision: 4281 http://bigdata.svn.sourceforge.net/bigdata/?rev=4281&view=rev Author: thompsonbry Date: 2011-03-08 15:12:43 +0000 (Tue, 08 Mar 2011) Log Message: ----------- Modified RWStrategy to explicitly pass in the offset and length of the data to be read from the RWStore. This is in preparation for examining ways of recycling the byte[] buffers in coordination with the B+Tree to reduce heap pressure. Modified RWStore to use a double-checked locking pattern in the re-opener such that it does not always synchronize before a read or write operation on the backing channel. This removes some sources of false contention during query. Modified Paths: -------------- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/journal/RWStrategy.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/rwstore/RWStore.java Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/journal/RWStrategy.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/journal/RWStrategy.java 2011-03-08 15:06:58 UTC (rev 4280) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/journal/RWStrategy.java 2011-03-08 15:12:43 UTC (rev 4281) @@ -612,7 +612,7 @@ */ final byte buf[] = new byte[sze + 4]; // 4 bytes for checksum - m_store.getData(rwaddr, buf); + m_store.getData(rwaddr, buf, 0, sze+4); return ByteBuffer.wrap(buf, 0, sze); Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/rwstore/RWStore.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/rwstore/RWStore.java 2011-03-08 15:06:58 UTC (rev 4280) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/rwstore/RWStore.java 2011-03-08 15:12:43 UTC (rev 4281) @@ -3137,35 +3137,55 @@ } - synchronized public FileChannel reopenChannel() throws IOException { + public FileChannel reopenChannel() throws IOException { - if (raf != null && raf.getChannel().isOpen()) { + /* + * Note: This is basically a double-checked locking pattern. It is + * used to avoid synchronizing when the backing channel is already + * open. + */ + { + final RandomAccessFile tmp = raf; + if (tmp != null) { + final FileChannel channel = tmp.getChannel(); + if (channel.isOpen()) { + /* + * The channel is still open. If you are allowing + * concurrent reads on the channel, then this could + * indicate that two readers each found the channel + * closed and that one was able to re-open the channel + * before the other such that the channel was open again + * by the time the 2nd reader got here. + */ + return channel; + } + } + } + + synchronized(this) { - /* - * The channel is still open. If you are allowing concurrent - * reads on the channel, then this could indicate that two - * readers each found the channel closed and that one was able - * to re-open the channel before the other such that the channel - * was open again by the time the 2nd reader got here. - */ + if (raf != null) { + final FileChannel channel = raf.getChannel(); + if (channel.isOpen()) { + return channel; + } + } - return raf.getChannel(); + // open the file. + this.raf = new RandomAccessFile(file, mode); - } + // Update counters. + final StoreCounters<?> c = (StoreCounters<?>) storeCounters + .get().acquire(); + try { + c.nreopen++; + } finally { + c.release(); + } - // open the file. - this.raf = new RandomAccessFile(file, mode); + return raf.getChannel(); - // Update counters. - final StoreCounters<?> c = (StoreCounters<?>) storeCounters.get() - .acquire(); - try { - c.nreopen++; - } finally { - c.release(); - } - - return raf.getChannel(); + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |