All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gemstone.gemfire.cache.query.internal.index.IndexMaintainceTest Maven / Gradle / Ivy

There is a newer version: 2.0-BETA
Show newest version
/*
 * Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
 *
 * Licensed 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. See accompanying
 * LICENSE file.
 */
/*
 * IndexMaintainceTest.java
 *
 * Created on February 24, 2005, 5:47 PM
 */
package com.gemstone.gemfire.cache.query.internal.index;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.Region;
import com.gemstone.gemfire.cache.query.CacheUtils;
import com.gemstone.gemfire.cache.query.Index;
import com.gemstone.gemfire.cache.query.IndexExistsException;
import com.gemstone.gemfire.cache.query.IndexNameConflictException;
import com.gemstone.gemfire.cache.query.IndexStatistics;
import com.gemstone.gemfire.cache.query.IndexType;
import com.gemstone.gemfire.cache.query.Query;
import com.gemstone.gemfire.cache.query.QueryService;
import com.gemstone.gemfire.cache.query.RegionNotFoundException;
import com.gemstone.gemfire.cache.query.SelectResults;
import com.gemstone.gemfire.cache.query.Utils;
import com.gemstone.gemfire.cache.query.data.Portfolio;
import com.gemstone.gemfire.cache.query.functional.StructSetOrResultsSet;
import com.gemstone.gemfire.cache.query.internal.ExecutionContext;
import com.gemstone.gemfire.cache.query.internal.QueryObserverAdapter;
import com.gemstone.gemfire.cache.query.internal.QueryObserverHolder;
import com.gemstone.gemfire.cache.query.internal.parse.OQLLexerTokenTypes;

import io.snappydata.test.dunit.DistributedTestBase;

/**
 * 
 * @author vaibhav
 */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class IndexMaintainceTest extends TestCase {

  public IndexMaintainceTest(String testName) {
    super(testName);
  }

  protected void setUp() throws Exception {
    if (!isInitDone) {
      init();
    }
    System.out.println("Running " + this.getName());
  }

  protected void tearDown() throws Exception {
  }

  public static Test suite() {
    TestSuite suite = new TestSuite(IndexMaintainceTest.class);
    return suite;
  }

  static QueryService qs;
  static boolean isInitDone = false;
  static Region region;
  static IndexProtocol index;
  protected boolean indexUsed = false;

  private static void init() {
    try {
      Cache cache = CacheUtils.getCache();
      region = CacheUtils.createRegion("portfolio", Portfolio.class);
      region.put("0", new Portfolio(0));
      region.put("1", new Portfolio(1));
      region.put("2", new Portfolio(2));
      region.put("3", new Portfolio(3));
      qs = cache.getQueryService();
      index = (IndexProtocol) qs.createIndex("statusIndex",
          IndexType.FUNCTIONAL, "status", "/portfolio");
      assertTrue(index instanceof CompactRangeIndex);
    }
    catch (Exception e) {
      e.printStackTrace();
    }
    isInitDone = true;
  }

  public void test000BUG32452() throws IndexNameConflictException,
      IndexExistsException, RegionNotFoundException {
    Index i1 = qs.createIndex("tIndex", IndexType.FUNCTIONAL, "vals.secId",
        "/portfolio pf, pf.positions.values vals");
    Index i2 = qs.createIndex("dIndex", IndexType.FUNCTIONAL,
        "pf.getCW(pf.ID)", "/portfolio pf");
    Index i3 = qs.createIndex("fIndex", IndexType.FUNCTIONAL, "sIter",
        "/portfolio pf, pf.collectionHolderMap[(pf.ID).toString()].arr sIter");
    Index i4 = qs.createIndex("cIndex", IndexType.FUNCTIONAL,
        "pf.collectionHolderMap[(pf.ID).toString()].arr[pf.ID]",
        "/portfolio pf");
    Index i5 = qs.createIndex("inIndex", IndexType.FUNCTIONAL, "kIter.secId",
        "/portfolio['0'].positions.values kIter");
    Index i6 = qs.createIndex("sIndex", IndexType.FUNCTIONAL, "pos.secId",
        "/portfolio.values val, val.positions.values pos");
    Index i7 = qs.createIndex("p1Index", IndexType.PRIMARY_KEY, "pkid",
        "/portfolio pf");
    Index i8 = qs.createIndex("p2Index", IndexType.PRIMARY_KEY, "pk",
        "/portfolio pf");
    if (!i1.getCanonicalizedFromClause().equals(
        "/portfolio index_iter1, index_iter1.positions.values index_iter2")
        || !i1.getCanonicalizedIndexedExpression().equals("index_iter2.secId")
        || !i1.getFromClause()
            .equals("/portfolio pf, pf.positions.values vals")
        || !i1.getIndexedExpression().equals("vals.secId")) {
      fail("Mismatch found among fromClauses or IndexedExpressions");
    }
    if (!i2.getCanonicalizedFromClause().equals("/portfolio index_iter1")
        || !i2.getCanonicalizedIndexedExpression().equals(
            "index_iter1.getCW(index_iter1.ID)")
        || !i2.getFromClause().equals("/portfolio pf")
        || !i2.getIndexedExpression().equals("pf.getCW(pf.ID)")) {
      fail("Mismatch found among fromClauses or IndexedExpressions");
    }
    if (!i3
        .getCanonicalizedFromClause()
        .equals(
            "/portfolio index_iter1, index_iter1.collectionHolderMap[index_iter1.ID.toString()].arr index_iter3")
        || !i3.getCanonicalizedIndexedExpression().equals("index_iter3")
        || !i3
            .getFromClause()
            .equals(
                "/portfolio pf, pf.collectionHolderMap[(pf.ID).toString()].arr sIter")
        || !i3.getIndexedExpression().equals("sIter")) {
      fail("Mismatch found among fromClauses or IndexedExpressions");
    }
    if (!i4.getCanonicalizedFromClause().equals("/portfolio index_iter1")
        || !i4.getCanonicalizedIndexedExpression().equals(
            "index_iter1.collectionHolderMap[index_iter1.ID.toString()].arr[index_iter1.ID]")
        || !i4.getFromClause().equals("/portfolio pf")
        || !i4.getIndexedExpression().equals(
            "pf.collectionHolderMap[(pf.ID).toString()].arr[pf.ID]")) {
      fail("Mismatch found among fromClauses or IndexedExpressions");
    }
    if (!i5.getCanonicalizedFromClause().equals(
        "/portfolio['0'].positions.values index_iter4")
        || !i5.getCanonicalizedIndexedExpression().equals("index_iter4.secId")
        || !i5.getFromClause().equals("/portfolio['0'].positions.values kIter")
        || !i5.getIndexedExpression().equals("kIter.secId")) {
      fail("Mismatch found among fromClauses or IndexedExpressions");
    }
    if (!i6.getCanonicalizedFromClause().equals(
        "/portfolio.values index_iter5, index_iter5.positions.values index_iter6")
        || !i6.getCanonicalizedIndexedExpression().equals("index_iter6.secId")
        || !i6.getFromClause().equals(
            "/portfolio.values val, val.positions.values pos")
        || !i6.getIndexedExpression().equals("pos.secId")) {
      fail("Mismatch found among fromClauses or IndexedExpressions");
    }
    if (!i7.getCanonicalizedFromClause().equals("/portfolio index_iter1")
        || !i7.getCanonicalizedIndexedExpression().equals("index_iter1.pkid")
        || !i7.getFromClause().equals("/portfolio pf")
        || !i7.getIndexedExpression().equals("pkid")) {
      fail("Mismatch found among fromClauses or IndexedExpressions");
    }
    if (!i8.getCanonicalizedFromClause().equals("/portfolio index_iter1")
        || !i8.getCanonicalizedIndexedExpression().equals("index_iter1.pk")
        || !i8.getFromClause().equals("/portfolio pf")
        || !i8.getIndexedExpression().equals("pk")) {
      fail("Mismatch found among fromClauses or IndexedExpressions");
    }
    qs.removeIndex(i1);
    qs.removeIndex(i2);
    qs.removeIndex(i3);
    qs.removeIndex(i4);
    qs.removeIndex(i5);
    qs.removeIndex(i6);
    qs.removeIndex(i7);
    qs.removeIndex(i8);
    Index i9 = qs.createIndex("p3Index", IndexType.PRIMARY_KEY, "getPk",
        "/portfolio pf");
    if (!i9.getCanonicalizedFromClause().equals("/portfolio index_iter1")
        || !i9.getCanonicalizedIndexedExpression().equals("index_iter1.pk")
        || !i9.getFromClause().equals("/portfolio pf")
        || !i9.getIndexedExpression().equals("getPk")) {
      fail("Mismatch found among fromClauses or IndexedExpressions");
    }
    qs.removeIndex(i9);
  }

  public void test001AddEntry() throws Exception {
    System.out.println(((CompactRangeIndex) index).dump());
    IndexStatistics stats = index.getStatistics();
    assertEquals(4, stats.getNumberOfValues());
    //    com.gemstone.gemfire.internal.util.
    //    DebuggerSupport.waitForJavaDebugger(region.getCache().getLogger());
    region.put("4", new Portfolio(4));
    System.out.println(((CompactRangeIndex) index).dump());
    stats = index.getStatistics();
    assertEquals(5, stats.getNumberOfValues());
    //Set results = new HashSet();
    //index.query("active", OQLLexerTokenTypes.TOK_EQ, results, new ExecutionContext(null, CacheUtils.getCache()));
    SelectResults results = region.query("status = 'active'");
    System.out.println(Utils.printResult(results));
    assertEquals(3, results.size());
  }

  // !!!:ezoerner:20081030 disabled because modifying an object in place
  // and then putting it back into the cache breaks a CompactRangeIndex.
  // @todo file a ticket on this issue
  public void _test002UpdateEntry() throws Exception {
    IndexStatistics stats = index.getStatistics();
    System.out.println(((CompactRangeIndex) index).dump());
    Portfolio p = (Portfolio) region.get("4");
    p.status = "inactive";
    region.put("4", p);
    assertEquals(5, stats.getNumberOfValues());
    //Set results = new HashSet();
    //index.query("active", OQLLexerTokenTypes.TOK_EQ, results,new ExecutionContext(null, CacheUtils.getCache()));
    SelectResults results = region.query("status = 'active'");
    assertEquals(2, results.size());
  }

  public void test003InvalidateEntry() throws Exception {
    IndexStatistics stats = index.getStatistics();
    region.invalidate("4");
    assertEquals(4, stats.getNumberOfValues());
    //Set results = new HashSet();
    //index.query("active", OQLLexerTokenTypes.TOK_EQ, results,new ExecutionContext(null, CacheUtils.getCache()));
    SelectResults results = region.query("status = 'active'");
    assertEquals(2, results.size());
  }

  public void test004DestroyEntry() throws Exception {
    IndexStatistics stats = index.getStatistics();
    region.put("4", new Portfolio(4));
    region.destroy("4");
    assertEquals(4, stats.getNumberOfValues());
    //Set results = new HashSet();
    //index.query("active", OQLLexerTokenTypes.TOK_EQ, results,new ExecutionContext(null, CacheUtils.getCache()));
    SelectResults results = region.query("status = 'active'");
    assertEquals(2, results.size());
  }

  //This test has a meaning only for Trunk code as it checks for Map implementation
  //Asif : Tests for Region clear operations on Index in a Local VM
  public void test005IndexClearanceOnMapClear() {
    try {
      CacheUtils.restartCache();
      IndexMaintainceTest.isInitDone = false;
      init();
      Query q = qs
          .newQuery("SELECT DISTINCT * FROM /portfolio where status = 'active'");
      QueryObserverHolder.setInstance(new QueryObserverAdapter() {

        public void afterIndexLookup(Collection coll) {
          IndexMaintainceTest.this.indexUsed = true;
        }
      });
      SelectResults set = (SelectResults) q.execute();
      if (set.size() == 0 || !this.indexUsed) {
        fail("Either Size of the result set is zero or Index is not used ");
      }
      this.indexUsed = false;
      
      region.clear();
      set = (SelectResults) q.execute();
      if (set.size() != 0 || !this.indexUsed) {
        fail("Either Size of the result set is not zero or Index is not used ");
      }
    }
    catch (Exception e) {
      e.printStackTrace();
      fail(e.toString());
    }
    finally {
      IndexMaintainceTest.isInitDone = false;
      CacheUtils.restartCache();
    }
  }

  //Asif : Tests for Region clear operations on Index in a Local VM for cases
  // when a clear
  //operation & region put operation occur concurrentlty
  public void test006ConcurrentMapClearAndRegionPutOperation() {
    try {
      CacheUtils.restartCache();
      IndexMaintainceTest.isInitDone = false;
      init();
      Query q = qs
          .newQuery("SELECT DISTINCT * FROM /portfolio where status = 'active'");
      QueryObserverHolder.setInstance(new QueryObserverAdapter() {

        public void afterIndexLookup(Collection coll) {
          IndexMaintainceTest.this.indexUsed = true;
        }

        public void beforeRerunningIndexCreationQuery() {
          //Spawn a separate thread here which does a put opertion on region
          Thread th = new Thread(new Runnable() {

            public void run() {
              //Assert that the size of region is now 0
              assertTrue(IndexMaintainceTest.region.size() == 0);
              IndexMaintainceTest.region.put("" + 8, new Portfolio(8));
            }
          });
          th.start();
          DistributedTestBase.join(th, 30 * 1000, null);
          assertTrue(IndexMaintainceTest.region.size() == 1);
        }
      });
      SelectResults set = (SelectResults) q.execute();
      if (set.size() == 0 || !this.indexUsed) {
        fail("Either Size of the result set is zero or Index is not used ");
      }
      this.indexUsed = false;
      region.clear();
      set = (SelectResults) q.execute();
      if (set.size() != 1 || !this.indexUsed) {
        fail("Either Size of the result set is not one or Index is not used ");
      }
    }
    catch (Exception e) {
      e.printStackTrace();
      fail(e.toString());
    }
    finally {
      IndexMaintainceTest.isInitDone = false;
      CacheUtils.restartCache();
    }
  }
  
  public void test007IndexUpdate() {
    try{
    CacheUtils.restartCache();
    IndexMaintainceTest.isInitDone = false;
    init();
    qs.removeIndexes();
  
    index = (IndexProtocol) qs.createIndex("statusIndex",
        IndexType.FUNCTIONAL, "pos.secId", "/portfolio p , p.positions.values pos");
    String queryStr = "Select distinct pf from /portfolio pf , pf.positions.values ps where ps.secId='SUN'";
    
    Query query =  qs.newQuery(queryStr);
    SelectResults rs =(SelectResults) query.execute();
    int size1 = rs.size();
    for(int i=4;i<50;++i) {
	    region.put(""+i, new Portfolio(i));
    }
    rs =(SelectResults) query.execute();
    int size2 = rs.size();
    assertTrue(size2>size1);
   }catch(Exception e) {
     e.printStackTrace();
     fail("Test failed due to exception="+e);
   }finally {
     IndexMaintainceTest.isInitDone = false;
     CacheUtils.restartCache();
   }
    
  }

  
  /**
   * Test to compare range and compact index.
   * They should return the same results.
   */
  public void test008RangeAndCompactRangeIndex() {
    try{
      //CacheUtils.restartCache();
      if (!IndexMaintainceTest.isInitDone){
        init();
      }
      qs.removeIndexes();

      String[] queryStr = new String[] {
          "Select status from /portfolio pf where status='active'",
          "Select pf.ID from /portfolio pf where pf.ID > 2 and pf.ID < 100",       
          "Select * from /portfolio pf where pf.position1.secId > '2'",       
      };

      String[] queryFields = new String[] {
          "status",
          "ID",
          "position1.secId",
      };

      for (int i=0; i < queryStr.length; i++){
        // Clear indexes if any.
        qs.removeIndexes();

        // initialize region.
        region.clear();
        for (int k=0; k < 10; k++) {
          region.put(""+k, new Portfolio(k));
        }

        for (int j=0; j < 1; j++) { // With different region size.
          // Update Region.
          for (int k=0; k < (j * 100); k++) {
            region.put(""+k, new Portfolio(k));
          }

          // Create compact index.
          IndexManager.TEST_RANGEINDEX_ONLY = false;
          index = (IndexProtocol) qs.createIndex(queryFields[i] + "Index",
              IndexType.FUNCTIONAL, queryFields[i], "/portfolio");

          // Execute Query.    
          SelectResults[][] rs = new SelectResults[1][2];
          Query query =  qs.newQuery(queryStr[i]);
          rs[0][0] =(SelectResults) query.execute();

          // remove compact index.
          qs.removeIndexes();

          // Create Range Index.
          IndexManager.TEST_RANGEINDEX_ONLY = true;
          index = (IndexProtocol) qs.createIndex(queryFields[i] + "rIndex",
              IndexType.FUNCTIONAL, queryFields[i], "/portfolio");

          query =  qs.newQuery(queryStr[i]);
          rs[0][1] =(SelectResults) query.execute();

          System.out.println("#### rs1 size is : " + (rs[0][0]).size() + " rs2 size is : " + (rs[0][1]).size());
          StructSetOrResultsSet ssORrs = new  StructSetOrResultsSet();
          ssORrs.CompareQueryResultsWithoutAndWithIndexes(rs, 1,queryStr);
        }
      }
    }catch(Exception e) {
      e.printStackTrace();
      fail("Test failed due to exception="+e);
    }finally {
      IndexManager.TEST_RANGEINDEX_ONLY = false;
      IndexMaintainceTest.isInitDone = false;
      CacheUtils.restartCache();
    }
  }

  /**
   * Test to compare range and compact index.
   * They should return the same results.
   */
  public void test009AcquringCompactRangeIndexEarly() {
    try{
      //CacheUtils.restartCache();
      if (!IndexMaintainceTest.isInitDone){
        init();
      }
      qs.removeIndexes();

      String[] queryStr = new String[] {
          "Select status from /portfolio pf where status='active'",
          "Select * from /portfolio pf, pf.positions.values pos where pf.ID > 10 and pf.status='active'",
          "Select pf.ID from /portfolio pf where pf.ID > 2 and pf.ID < 100",       
          "Select * from /portfolio pf where pf.position1.secId > '2'",       
          "Select * from /portfolio pf, pf.positions.values pos where pos.secId > '2'",
      };

      // initialize region.
      region.clear();
      for (int k=0; k < 10; k++) {
        region.put(""+k, new Portfolio(k));
      }

      // Create range and compact-range indexes.
      qs.createIndex("id2Index ", IndexType.FUNCTIONAL, "pf.ID", "/portfolio pf");
      qs.createIndex("id2PosIndex ", IndexType.FUNCTIONAL, "pf.ID", "/portfolio pf, pf.positions.values");
      qs.createIndex("status2PosIndex ", IndexType.FUNCTIONAL, "pos.secId", "/portfolio pf, pf.positions.values pos");
      
      // Set the acquire compact range index flag to true
      //IndexManager.TEST_ACQUIRE_COMPACTINDEX_LOCKS_EARLY = true;
      // Update Region.
      for (int k=0; k <  100; k++) {
        region.put(""+k, new Portfolio(k));
      }
      for (int i=0; i < queryStr.length; i++){
        // Execute Query.    
        SelectResults[][] rs = new SelectResults[1][2];
        Query query =  qs.newQuery(queryStr[i]);
        rs[0][0] =(SelectResults) query.execute();
      }

    }catch(Exception e) {
      e.printStackTrace();
      fail("Test failed due to exception="+e);
    }finally {
      //IndexManager.TEST_ACQUIRE_COMPACTINDEX_LOCKS_EARLY = false;
      IndexMaintainceTest.isInitDone = false;
      CacheUtils.restartCache();
    }
  }
  
  ////////// main method ///////////
  public static void main(java.lang.String[] args) {
    junit.textui.TestRunner.run(suite());
  }//end of main method
  
  
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy