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

Lucene example source code file (TestTransactionRollback.java)

This example Lucene source code file (TestTransactionRollback.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

bitset, exception, exception, hashmap, indexcommit, indexcommit, indexdeletionpolicy, indexwriter, io, ioexception, ioexception, map, string, string, test_version_current, util

The Lucene TestTransactionRollback.java source code

package org.apache.lucene.index;

/**
 * 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.IOException;
import java.util.BitSet;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.HashMap;

import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.analysis.MockAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.store.Directory;

/**
 * Test class to illustrate using IndexDeletionPolicy to provide multi-level rollback capability.
 * This test case creates an index of records 1 to 100, introducing a commit point every 10 records.
 * 
 * A "keep all" deletion policy is used to ensure we keep all commit points for testing purposes
 */

public class TestTransactionRollback extends LuceneTestCase {
	
  private static final String FIELD_RECORD_ID = "record_id";
  private Directory dir;
	
  //Rolls back index to a chosen ID
  private void rollBackLast(int id) throws Exception {
		
    // System.out.println("Attempting to rollback to "+id);
    String ids="-"+id;
    IndexCommit last=null;
    Collection<IndexCommit> commits = IndexReader.listCommits(dir);
    for (Iterator<IndexCommit> iterator = commits.iterator(); iterator.hasNext();) {
      IndexCommit commit =  iterator.next();
      Map<String,String> ud=commit.getUserData();
      if (ud.size() > 0)
        if (ud.get("index").endsWith(ids))
          last=commit;
    }

    if (last==null)
      throw new RuntimeException("Couldn't find commit point "+id);
		
    IndexWriter w = new IndexWriter(dir, newIndexWriterConfig(
        TEST_VERSION_CURRENT, new MockAnalyzer(random)).setIndexDeletionPolicy(
        new RollbackDeletionPolicy(id)).setIndexCommit(last));
    Map<String,String> data = new HashMap();
    data.put("index", "Rolled back to 1-"+id);
    w.commit(data);
    w.close();
  }

  public void testRepeatedRollBacks() throws Exception {		

    int expectedLastRecordId=100;
    while (expectedLastRecordId>10) {
      expectedLastRecordId -=10;			
      rollBackLast(expectedLastRecordId);
      
      BitSet expecteds = new BitSet(100);
      expecteds.set(1,(expectedLastRecordId+1),true);
      checkExpecteds(expecteds);			
    }
  }
	
  private void checkExpecteds(BitSet expecteds) throws Exception {
    IndexReader r = IndexReader.open(dir, true);
		
    //Perhaps not the most efficient approach but meets our needs here.
    for (int i = 0; i < r.maxDoc(); i++) {
      if(!r.isDeleted(i)) {
        String sval=r.document(i).get(FIELD_RECORD_ID);
        if(sval!=null) {
          int val=Integer.parseInt(sval);
          assertTrue("Did not expect document #"+val, expecteds.get(val));
          expecteds.set(val,false);
        }
      }
    }
    r.close();
    assertEquals("Should have 0 docs remaining ", 0 ,expecteds.cardinality());
  }

  /*
  private void showAvailableCommitPoints() throws Exception {
    Collection commits = IndexReader.listCommits(dir);
    for (Iterator iterator = commits.iterator(); iterator.hasNext();) {
      IndexCommit comm = (IndexCommit) iterator.next();
      System.out.print("\t Available commit point:["+comm.getUserData()+"] files=");
      Collection files = comm.getFileNames();
      for (Iterator iterator2 = files.iterator(); iterator2.hasNext();) {
        String filename = (String) iterator2.next();
        System.out.print(filename+", ");				
      }
      System.out.println();
    }
  }
  */

  @Override
  public void setUp() throws Exception {
    super.setUp();
    dir = newDirectory();
    //Build index, of records 1 to 100, committing after each batch of 10
    IndexDeletionPolicy sdp=new KeepAllDeletionPolicy();
    IndexWriter w=new IndexWriter(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random)).setIndexDeletionPolicy(sdp));
    for(int currentRecordId=1;currentRecordId<=100;currentRecordId++) {
      Document doc=new Document();
      doc.add(newField(FIELD_RECORD_ID,""+currentRecordId,Field.Store.YES,Field.Index.ANALYZED));
      w.addDocument(doc);
			
      if (currentRecordId%10 == 0) {
        Map<String,String> data = new HashMap();
        data.put("index", "records 1-"+currentRecordId);
        w.commit(data);
      }
    }

    w.close();
  }
  
  @Override
  public void tearDown() throws Exception {
    dir.close();
    super.tearDown();
  }

  // Rolls back to previous commit point
  class RollbackDeletionPolicy implements IndexDeletionPolicy {
    private int rollbackPoint;

    public RollbackDeletionPolicy(int rollbackPoint) {
      this.rollbackPoint = rollbackPoint;
    }

    public void onCommit(List<? extends IndexCommit> commits) throws IOException {
    }

    public void onInit(List<? extends IndexCommit> commits) throws IOException {
      for (final IndexCommit commit : commits) {
        Map<String,String> userData=commit.getUserData();
        if (userData.size() > 0) {
          // Label for a commit point is "Records 1-30"
          // This code reads the last id ("30" in this example) and deletes it
          // if it is after the desired rollback point
          String x = userData.get("index");
          String lastVal = x.substring(x.lastIndexOf("-")+1);
          int last = Integer.parseInt(lastVal);
          if (last>rollbackPoint) {
            /*
            System.out.print("\tRolling back commit point:" +
                             " UserData="+commit.getUserData() +")  ("+(commits.size()-1)+" commit points left) files=");
            Collection files = commit.getFileNames();
            for (Iterator iterator2 = files.iterator(); iterator2.hasNext();) {
              System.out.print(" "+iterator2.next());				
            }
            System.out.println();
            */
						
            commit.delete();									
          }
        }
      }
    }		
  }

  class DeleteLastCommitPolicy implements IndexDeletionPolicy {

    public void onCommit(List<? extends IndexCommit> commits) throws IOException {}

    public void onInit(List<? extends IndexCommit> commits) throws IOException {
      commits.get(commits.size()-1).delete();
    }
  }

  public void testRollbackDeletionPolicy() throws Exception {		
    for(int i=0;i<2;i++) {
      // Unless you specify a prior commit point, rollback
      // should not work:
      new IndexWriter(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random))
          .setIndexDeletionPolicy(new DeleteLastCommitPolicy())).close();
      IndexReader r = IndexReader.open(dir, true);
      assertEquals(100, r.numDocs());
      r.close();
    }
  }
	
  // Keeps all commit points (used to build index)
  class KeepAllDeletionPolicy implements IndexDeletionPolicy {
    public void onCommit(List<? extends IndexCommit> commits) throws IOException {}
    public void onInit(List<? extends IndexCommit> commits) throws IOException {}
  }
}

Other Lucene examples (source code examples)

Here is a short list of links related to this Lucene TestTransactionRollback.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.