alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Lucene example source code file (TestLockFactory.java)

This example Lucene source code file (TestLockFactory.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Lucene tags/keywords

directory, directory, exception, file, indexwriter, indexwriter, indexwriterconfig, io, ioexception, ioexception, lock, lock, nativefslockfactory, override, ramdirectory, util

The Lucene TestLockFactory.java source code

package org.apache.lucene.store;

/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.apache.lucene.analysis.MockAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util._TestUtil;

public class TestLockFactory extends LuceneTestCase {

    // Verify: we can provide our own LockFactory implementation, the right
    // methods are called at the right time, locks are created, etc.

    public void testCustomLockFactory() throws IOException {
        Directory dir = new MockDirectoryWrapper(random, new RAMDirectory());
        MockLockFactory lf = new MockLockFactory();
        dir.setLockFactory(lf);

        // Lock prefix should have been set:
        assertTrue("lock prefix was not set by the RAMDirectory", lf.lockPrefixSet);

        IndexWriter writer = new IndexWriter(dir, new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)));

        // add 100 documents (so that commit lock is used)
        for (int i = 0; i < 100; i++) {
            addDoc(writer);
        }

        // Both write lock and commit lock should have been created:
        assertEquals("# of unique locks created (after instantiating IndexWriter)",
                     1, lf.locksCreated.size());
        assertTrue("# calls to makeLock is 0 (after instantiating IndexWriter)",
                   lf.makeLockCount >= 1);
        
        for(final String lockName : lf.locksCreated.keySet()) {
            MockLockFactory.MockLock lock = (MockLockFactory.MockLock) lf.locksCreated.get(lockName);
            assertTrue("# calls to Lock.obtain is 0 (after instantiating IndexWriter)",
                       lock.lockAttempts > 0);
        }
        
        writer.close();
    }

    // Verify: we can use the NoLockFactory with RAMDirectory w/ no
    // exceptions raised:
    // Verify: NoLockFactory allows two IndexWriters
    public void testRAMDirectoryNoLocking() throws IOException {
        Directory dir = new MockDirectoryWrapper(random, new RAMDirectory());
        dir.setLockFactory(NoLockFactory.getNoLockFactory());

        assertTrue("RAMDirectory.setLockFactory did not take",
                   NoLockFactory.class.isInstance(dir.getLockFactory()));

        IndexWriter writer = new IndexWriter(dir, new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)));
        writer.commit(); // required so the second open succeed 
        // Create a 2nd IndexWriter.  This is normally not allowed but it should run through since we're not
        // using any locks:
        IndexWriter writer2 = null;
        try {
            writer2 = new IndexWriter(dir, new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setOpenMode(OpenMode.APPEND));
        } catch (Exception e) {
            e.printStackTrace(System.out);
            fail("Should not have hit an IOException with no locking");
        }

        writer.close();
        if (writer2 != null) {
            writer2.close();
        }
    }

    // Verify: SingleInstanceLockFactory is the default lock for RAMDirectory
    // Verify: RAMDirectory does basic locking correctly (can't create two IndexWriters)
    public void testDefaultRAMDirectory() throws IOException {
        Directory dir = new RAMDirectory();

        assertTrue("RAMDirectory did not use correct LockFactory: got " + dir.getLockFactory(),
                   SingleInstanceLockFactory.class.isInstance(dir.getLockFactory()));

        IndexWriter writer = new IndexWriter(dir, new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)));

        // Create a 2nd IndexWriter.  This should fail:
        IndexWriter writer2 = null;
        try {
            writer2 = new IndexWriter(dir, new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setOpenMode(OpenMode.APPEND));
            fail("Should have hit an IOException with two IndexWriters on default SingleInstanceLockFactory");
        } catch (IOException e) {
        }

        writer.close();
        if (writer2 != null) {
            writer2.close();
        }
    }
    
    public void testSimpleFSLockFactory() throws IOException {
      // test string file instantiation
      new SimpleFSLockFactory("test");
    }

    // Verify: do stress test, by opening IndexReaders and
    // IndexWriters over & over in 2 threads and making sure
    // no unexpected exceptions are raised:
    public void testStressLocks() throws Exception {
      _testStressLocks(null, _TestUtil.getTempDir("index.TestLockFactory6"));
    }

    // Verify: do stress test, by opening IndexReaders and
    // IndexWriters over & over in 2 threads and making sure
    // no unexpected exceptions are raised, but use
    // NativeFSLockFactory:
    public void testStressLocksNativeFSLockFactory() throws Exception {
      File dir = _TestUtil.getTempDir("index.TestLockFactory7");
      _testStressLocks(new NativeFSLockFactory(dir), dir);
    }

    public void _testStressLocks(LockFactory lockFactory, File indexDir) throws Exception {
      Directory dir = newFSDirectory(indexDir, lockFactory);

        // First create a 1 doc index:
        IndexWriter w = new IndexWriter(dir, new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setOpenMode(OpenMode.CREATE));
        addDoc(w);
        w.close();

      WriterThread writer = new WriterThread(100, dir);
      SearcherThread searcher = new SearcherThread(100, dir);
      writer.start();
      searcher.start();

      while(writer.isAlive() || searcher.isAlive()) {
        Thread.sleep(1000);
      }

      assertTrue("IndexWriter hit unexpected exceptions", !writer.hitException);
      assertTrue("IndexSearcher hit unexpected exceptions", !searcher.hitException);

      dir.close();
      // Cleanup
      _TestUtil.rmDir(indexDir);
    }

    // Verify: NativeFSLockFactory works correctly
    public void testNativeFSLockFactory() throws IOException {

      NativeFSLockFactory f = new NativeFSLockFactory(TEMP_DIR);

      f.setLockPrefix("test");
      Lock l = f.makeLock("commit");
      Lock l2 = f.makeLock("commit");

      assertTrue("failed to obtain lock", l.obtain());
      assertTrue("succeeded in obtaining lock twice", !l2.obtain());
      l.release();

      assertTrue("failed to obtain 2nd lock after first one was freed", l2.obtain());
      l2.release();

      // Make sure we can obtain first one again, test isLocked():
      assertTrue("failed to obtain lock", l.obtain());
      assertTrue(l.isLocked());
      assertTrue(l2.isLocked());
      l.release();
      assertFalse(l.isLocked());
      assertFalse(l2.isLocked());
    }

    
    // Verify: NativeFSLockFactory works correctly if the lock file exists
    public void testNativeFSLockFactoryLockExists() throws IOException {
      
      File lockFile = new File(TEMP_DIR, "test.lock");
      lockFile.createNewFile();
      
      Lock l = new NativeFSLockFactory(TEMP_DIR).makeLock("test.lock");
      assertTrue("failed to obtain lock", l.obtain());
      l.release();
      assertFalse("failed to release lock", l.isLocked());
      if (lockFile.exists()) {
        lockFile.delete();
      }
    }

    public void testNativeFSLockReleaseByOtherLock() throws IOException {

      NativeFSLockFactory f = new NativeFSLockFactory(TEMP_DIR);

      f.setLockPrefix("test");
      Lock l = f.makeLock("commit");
      Lock l2 = f.makeLock("commit");

      assertTrue("failed to obtain lock", l.obtain());
      try {
        assertTrue(l2.isLocked());
        l2.release();
        fail("should not have reached here. LockReleaseFailedException should have been thrown");
      } catch (LockReleaseFailedException e) {
        // expected
      } finally {
        l.release();
      }
    }

    // Verify: NativeFSLockFactory assigns null as lockPrefix if the lockDir is inside directory
    public void testNativeFSLockFactoryPrefix() throws IOException {
      File fdir1 = _TestUtil.getTempDir("TestLockFactory.8");
      File fdir2 = _TestUtil.getTempDir("TestLockFactory.8.Lockdir");
      Directory dir1 = newFSDirectory(fdir1, new NativeFSLockFactory(fdir1));
      // same directory, but locks are stored somewhere else. The prefix of the lock factory should != null
      Directory dir2 = newFSDirectory(fdir1, new NativeFSLockFactory(fdir2));
      
      String prefix1 = dir1.getLockFactory().getLockPrefix();
      assertNull("Lock prefix for lockDir same as directory should be null", prefix1);
      
      String prefix2 = dir2.getLockFactory().getLockPrefix();
      assertNotNull("Lock prefix for lockDir outside of directory should be not null", prefix2);
      
      dir1.close();
      dir2.close();
      
      _TestUtil.rmDir(fdir1);
      _TestUtil.rmDir(fdir2);
    }

    // Verify: default LockFactory has no prefix (ie
    // write.lock is stored in index):
    public void testDefaultFSLockFactoryPrefix() throws IOException {
      // Make sure we get null prefix, which wont happen if setLockFactory is ever called.
      File dirName = _TestUtil.getTempDir("TestLockFactory.10");

      Directory dir = new SimpleFSDirectory(dirName);
      assertNull("Default lock prefix should be null", dir.getLockFactory().getLockPrefix());
      dir.close();
      
      dir = new MMapDirectory(dirName);
      assertNull("Default lock prefix should be null", dir.getLockFactory().getLockPrefix());
      dir.close();
      
      dir = new NIOFSDirectory(dirName);
      assertNull("Default lock prefix should be null", dir.getLockFactory().getLockPrefix());
      dir.close();
 
      _TestUtil.rmDir(dirName);
    }

    private class WriterThread extends Thread { 
        private Directory dir;
        private int numIteration;
        public boolean hitException = false;
        public WriterThread(int numIteration, Directory dir) {
            this.numIteration = numIteration;
            this.dir = dir;
        }
        @Override
        public void run() {
            IndexWriter writer = null;
            for(int i=0;i<this.numIteration;i++) {
                try {
                    writer = new IndexWriter(dir, new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setOpenMode(OpenMode.APPEND));
                } catch (IOException e) {
                    if (e.toString().indexOf(" timed out:") == -1) {
                        hitException = true;
                        System.out.println("Stress Test Index Writer: creation hit unexpected IOException: " + e.toString());
                        e.printStackTrace(System.out);
                    } else {
                        // lock obtain timed out
                        // NOTE: we should at some point
                        // consider this a failure?  The lock
                        // obtains, across IndexReader &
                        // IndexWriters should be "fair" (ie
                        // FIFO).
                    }
                } catch (Exception e) {
                    hitException = true;
                    System.out.println("Stress Test Index Writer: creation hit unexpected exception: " + e.toString());
                    e.printStackTrace(System.out);
                    break;
                }
                if (writer != null) {
                    try {
                        addDoc(writer);
                    } catch (IOException e) {
                        hitException = true;
                        System.out.println("Stress Test Index Writer: addDoc hit unexpected exception: " + e.toString());
                        e.printStackTrace(System.out);
                        break;
                    }
                    try {
                        writer.close();
                    } catch (IOException e) {
                        hitException = true;
                        System.out.println("Stress Test Index Writer: close hit unexpected exception: " + e.toString());
                        e.printStackTrace(System.out);
                        break;
                    }
                    writer = null;
                }
            }
        }
    }

    private class SearcherThread extends Thread { 
        private Directory dir;
        private int numIteration;
        public boolean hitException = false;
        public SearcherThread(int numIteration, Directory dir) {
            this.numIteration = numIteration;
            this.dir = dir;
        }
        @Override
        public void run() {
            IndexSearcher searcher = null;
            Query query = new TermQuery(new Term("content", "aaa"));
            for(int i=0;i<this.numIteration;i++) {
                try{
                    searcher = new IndexSearcher(dir, false);
                } catch (Exception e) {
                    hitException = true;
                    System.out.println("Stress Test Index Searcher: create hit unexpected exception: " + e.toString());
                    e.printStackTrace(System.out);
                    break;
                }
                try {
                  searcher.search(query, null, 1000);
                } catch (IOException e) {
                  hitException = true;
                  System.out.println("Stress Test Index Searcher: search hit unexpected exception: " + e.toString());
                  e.printStackTrace(System.out);
                  break;
                }
                // System.out.println(hits.length() + " total results");
                try {
                  searcher.close();
                } catch (IOException e) {
                  hitException = true;
                  System.out.println("Stress Test Index Searcher: close hit unexpected exception: " + e.toString());
                  e.printStackTrace(System.out);
                  break;
                }
            }
        }
    }

    public class MockLockFactory extends LockFactory {

        public boolean lockPrefixSet;
        public Map<String,Lock> locksCreated = Collections.synchronizedMap(new HashMap());
        public int makeLockCount = 0;

        @Override
        public void setLockPrefix(String lockPrefix) {    
            super.setLockPrefix(lockPrefix);
            lockPrefixSet = true;
        }

        @Override
        synchronized public Lock makeLock(String lockName) {
            Lock lock = new MockLock();
            locksCreated.put(lockName, lock);
            makeLockCount++;
            return lock;
        }

        @Override
        public void clearLock(String specificLockName) {}

        public class MockLock extends Lock {
            public int lockAttempts;

            @Override
            public boolean obtain() {
                lockAttempts++;
                return true;
            }
            @Override
            public void release() {
                // do nothing
            }
            @Override
            public boolean isLocked() {
                return false;
            }
        }
    }

    private void addDoc(IndexWriter writer) throws IOException {
        Document doc = new Document();
        doc.add(newField("content", "aaa", Field.Store.NO, Field.Index.ANALYZED));
        writer.addDocument(doc);
    }
}

Other Lucene examples (source code examples)

Here is a short list of links related to this Lucene TestLockFactory.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.