[infinispan-commits] Infinispan SVN: r2146 - trunk/lucene-directory/src/main/java/org/infinispan/lucene.

infinispan-commits at lists.jboss.org infinispan-commits at lists.jboss.org
Tue Aug 3 19:51:45 EDT 2010


Author: sannegrinovero
Date: 2010-08-03 19:51:45 -0400 (Tue, 03 Aug 2010)
New Revision: 2146

Added:
   trunk/lucene-directory/src/main/java/org/infinispan/lucene/SingleChunkIndexInput.java
Modified:
   trunk/lucene-directory/src/main/java/org/infinispan/lucene/InfinispanDirectory.java
   trunk/lucene-directory/src/main/java/org/infinispan/lucene/InfinispanIndexInput.java
Log:
[ISPN-567] (Avoid readlocks on small Lucene segments) trunk

Modified: trunk/lucene-directory/src/main/java/org/infinispan/lucene/InfinispanDirectory.java
===================================================================
--- trunk/lucene-directory/src/main/java/org/infinispan/lucene/InfinispanDirectory.java	2010-08-03 18:08:32 UTC (rev 2145)
+++ trunk/lucene-directory/src/main/java/org/infinispan/lucene/InfinispanDirectory.java	2010-08-03 23:51:45 UTC (rev 2146)
@@ -243,7 +243,16 @@
     */
    public IndexInput openInput(String name) throws IOException {
       final FileCacheKey fileKey = new FileCacheKey(indexName, name);
-      return new InfinispanIndexInput(cache, fileKey, chunkSize);
+      FileMetadata fileMetadata = (FileMetadata) cache.withFlags(Flag.SKIP_LOCKING).get(fileKey);
+      if (fileMetadata == null) {
+         throw new FileNotFoundException("Error loading medatada for index file: " + fileKey);
+      }
+      else if (fileMetadata.getSize() <= chunkSize) {
+         return new SingleChunkIndexInput(cache, fileKey, fileMetadata);
+      }
+      else {
+         return new InfinispanIndexInput(cache, fileKey, chunkSize, fileMetadata);
+      }
    }
 
    /**

Modified: trunk/lucene-directory/src/main/java/org/infinispan/lucene/InfinispanIndexInput.java
===================================================================
--- trunk/lucene-directory/src/main/java/org/infinispan/lucene/InfinispanIndexInput.java	2010-08-03 18:08:32 UTC (rev 2145)
+++ trunk/lucene-directory/src/main/java/org/infinispan/lucene/InfinispanIndexInput.java	2010-08-03 23:51:45 UTC (rev 2146)
@@ -56,31 +56,16 @@
 
    private boolean isClone;
 
-   public InfinispanIndexInput(AdvancedCache<CacheKey, Object> cache, FileCacheKey fileKey, int chunkSize) throws FileNotFoundException {
+   public InfinispanIndexInput(AdvancedCache<CacheKey, Object> cache, FileCacheKey fileKey, int chunkSize, FileMetadata fileMetadata) throws FileNotFoundException {
       this.cache = cache;
       this.fileKey = fileKey;
       this.chunkSize = chunkSize;
+      this.file = fileMetadata;
       final String filename = fileKey.getFileName();
       this.readLockKey = new FileReadLockKey(fileKey.getIndexName(), filename);
-      
-      boolean failure = true;
       aquireReadLock();
-      try {
-
-         // get file header from file
-         this.file = (FileMetadata) cache.withFlags(Flag.SKIP_LOCKING).get(fileKey);
-
-         if (file == null) {
-            throw new FileNotFoundException("Error loading medatada for index file: " + fileKey);
-         }
-
-         if (log.isDebugEnabled()) {
-            log.debug("Opened new IndexInput for file:{0} in index: {1}", filename, fileKey.getIndexName());
-         }
-         failure = false;
-      } finally {
-         if (failure)
-            releaseReadLock();
+      if (log.isDebugEnabled()) {
+         log.debug("Opened new IndexInput for file:{0} in index: {1}", filename, fileKey.getIndexName());
       }
    }
 

Added: trunk/lucene-directory/src/main/java/org/infinispan/lucene/SingleChunkIndexInput.java
===================================================================
--- trunk/lucene-directory/src/main/java/org/infinispan/lucene/SingleChunkIndexInput.java	                        (rev 0)
+++ trunk/lucene-directory/src/main/java/org/infinispan/lucene/SingleChunkIndexInput.java	2010-08-03 23:51:45 UTC (rev 2146)
@@ -0,0 +1,88 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.lucene;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import org.apache.lucene.store.IndexInput;
+import org.infinispan.AdvancedCache;
+import org.infinispan.context.Flag;
+
+/**
+ * SingleChunkIndexInput can be used instead of InfinispanIndexInput to read a segment
+ * when it has a size small enough to fit in a single chunk.
+ * In this quite common case for some segment types we
+ * don't need the readLock to span multiple chunks, the pointer to the buffer is safe enough.
+ * This leads to an extreme simple implementation.
+ * 
+ * @author Sanne Grinovero
+ * @since 4.0
+ */
+public class SingleChunkIndexInput extends IndexInput {
+
+   private final byte[] buffer;
+   private int bufferPosition;
+
+   public SingleChunkIndexInput(AdvancedCache<CacheKey, Object> cache, FileCacheKey fileKey, FileMetadata fileMetadata) throws FileNotFoundException {
+      CacheKey key = new ChunkCacheKey(fileKey.getIndexName(), fileKey.getFileName(), 0);
+      buffer = (byte[]) cache.withFlags(Flag.SKIP_LOCKING).get(key);
+      if (buffer == null) {
+         throw new FileNotFoundException("Chunk value could not be found for key " + key);
+      }
+      bufferPosition = 0;
+   }
+
+   @Override
+   public void close() throws IOException {
+      //nothing to do
+   }
+
+   @Override
+   public long getFilePointer() {
+      return bufferPosition;
+   }
+
+   @Override
+   public long length() {
+      return buffer.length;
+   }
+
+   @Override
+   public byte readByte() throws IOException {
+      return buffer[bufferPosition++];
+   }
+
+   @Override
+   public void readBytes(byte[] b, int offset, int len) throws IOException {
+      System.arraycopy(buffer, bufferPosition, b, offset, len);
+      bufferPosition+=len;
+   }
+
+   @Override
+   public void seek(long pos) throws IOException {
+      //Lucene might use positions larger than length(), in
+      //this case you have to position the pointer to eof.
+      bufferPosition = (int) Math.min(pos, buffer.length);
+   }
+
+}



More information about the infinispan-commits mailing list