Package org.apache.hadoop.hbase

Source Code of org.apache.hadoop.hbase.TestSplit

/**
* Copyright 2007 The Apache Software Foundation
*
* 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.
*/
package org.apache.hadoop.hbase;

import java.io.IOException;
import java.util.TreeMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.io.Text;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;

/**
* {@Link TestHRegion} does a split but this TestCase adds testing of fast
* split and manufactures odd-ball split scenarios.
*/
public class TestSplit extends MultiRegionTable {
  @SuppressWarnings("hiding")
  static final Log LOG = LogFactory.getLog(TestSplit.class.getName());
 
  /** constructor */
  public TestSplit() {
    super();
   
    // Make lease timeout longer, lease checks less frequent
    conf.setInt("hbase.master.lease.period", 10 * 1000);
    conf.setInt("hbase.master.lease.thread.wakefrequency", 5 * 1000);

    // Increase the amount of time between client retries
    conf.setLong("hbase.client.pause", 15 * 1000);

    Logger.getRootLogger().setLevel(Level.WARN);
    Logger.getLogger(this.getClass().getPackage().getName()).
      setLevel(Level.DEBUG);
  }

  /** {@inheritDoc} */
  @Override
  public void setUp() throws Exception {
    super.setUp();
    // This size should make it so we always split using the addContent
    // below.  After adding all data, the first region is 1.3M
    conf.setLong("hbase.hregion.max.filesize", 1024 * 128);
  }
 
  /**
   * Splits twice and verifies getting from each of the split regions.
   * @throws Exception
   */
  public void testBasicSplit() throws Exception {
    HRegion region = null;
    HLog hlog = new HLog(this.localFs, this.testDir, this.conf);
    try {
      HTableDescriptor htd = createTableDescriptor(getName());
      HRegionInfo hri = new HRegionInfo(1, htd, null, null);
      region = new HRegion(testDir, hlog, this.localFs, this.conf, hri, null);
      basicSplit(region);
    } finally {
      if (region != null) {
        region.close();
      }
      hlog.closeAndDelete();
    }
  }
 
  private void basicSplit(final HRegion region) throws Exception {
    addContent(region, COLFAMILY_NAME3);
    region.internalFlushcache();
    Text midkey = new Text();
    assertTrue(region.needsSplit(midkey));
    HRegion [] regions = split(region);
    // Assert can get rows out of new regions.  Should be able to get first
    // row from first region and the midkey from second region.
    byte [] b = new byte [] {FIRST_CHAR, FIRST_CHAR, FIRST_CHAR};
    assertGet(regions[0], COLFAMILY_NAME3, new Text(b));
    assertGet(regions[1], COLFAMILY_NAME3, midkey);
    // Test I can get scanner and that it starts at right place.
    assertScan(regions[0], COLFAMILY_NAME3, new Text(b));
    assertScan(regions[1], COLFAMILY_NAME3, midkey);
    // Now prove can't split regions that have references.
    Text [] midkeys = new Text[regions.length];
    for (int i = 0; i < regions.length; i++) {
      midkeys[i] = new Text();
      // Even after above splits, still needs split but after splits its
      // unsplitable because biggest store file is reference.  References
      // make the store unsplittable, until something bigger comes along.
      assertFalse(regions[i].needsSplit(midkeys[i]));
      // Add so much data to this region, we create a store file that is > than
      // one of our unsplitable references.
      // it will.
      for (int j = 0; j < 2; j++) {
        addContent(regions[i], COLFAMILY_NAME3);
      }
      addContent(regions[i], COLFAMILY_NAME2);
      addContent(regions[i], COLFAMILY_NAME1);
      regions[i].internalFlushcache();
    }
   
    // Assert that even if one store file is larger than a reference, the
    // region is still deemed unsplitable (Can't split region if references
    // presen).
    for (int i = 0; i < regions.length; i++) {
      midkeys[i] = new Text();
      // Even after above splits, still needs split but after splits its
      // unsplitable because biggest store file is reference.  References
      // make the store unsplittable, until something bigger comes along.
      assertFalse(regions[i].needsSplit(midkeys[i]));
    }
   
    // To make regions splitable force compaction.
    for (int i = 0; i < regions.length; i++) {
      assertTrue(regions[i].compactStores());
    }

    TreeMap<String, HRegion> sortedMap = new TreeMap<String, HRegion>();
    // Split these two daughter regions so then I'll have 4 regions.  Will
    // split because added data above.
    for (int i = 0; i < regions.length; i++) {
      HRegion [] rs = split(regions[i]);
      for (int j = 0; j < rs.length; j++) {
        sortedMap.put(rs[j].getRegionName().toString(), rs[j]);
      }
    }
    LOG.info("Made 4 regions");
    // The splits should have been even.  Test I can get some arbitrary row out
    // of each.
    int interval = (LAST_CHAR - FIRST_CHAR) / 3;
    for (HRegion r: sortedMap.values()) {
      assertGet(r, COLFAMILY_NAME3,
          new Text(new String(b, HConstants.UTF8_ENCODING)));
      b[0] += interval;
    }
  }
 
  /**
   * Test that a region is cleaned up after its daughter splits release all
   * references.
   * @throws Exception
   */
  public void testSplitRegionIsDeleted() throws Exception {
    try {
      // Start up a hbase cluster
      MiniHBaseCluster cluster = new MiniHBaseCluster(conf, 1, true);
      try {
        // Create a table.
        HBaseAdmin admin = new HBaseAdmin(this.conf);
        admin.createTable(createTableDescriptor(getName()));
        // This builds a multi-region table by splitting.  It will assert
        // the parent region gets cleaned-up.
        MultiRegionTable.makeMultiRegionTable(conf, cluster,
            this.localFs, getName(), COLFAMILY_NAME3);
      } finally {
        cluster.shutdown();
      }
    } catch (Exception e) {
      LOG.error("test failed", e);
      throw e;
    }
  }
 
  private void assertGet(final HRegion r, final String family, final Text k)
  throws IOException {
    // Now I have k, get values out and assert they are as expected.
    byte [][] results = r.get(k, new Text(family),
      Integer.MAX_VALUE);
    for (int j = 0; j < results.length; j++) {
      Text tmp = new Text(results[j]);
      // Row should be equal to value every time.
      assertEquals(k.toString(), tmp.toString());
    }
  }
 
  /*
   * Assert first value in the passed region is <code>firstValue</code>.
   * @param r
   * @param column
   * @param firstValue
   * @throws IOException
   */
  private void assertScan(final HRegion r, final String column,
      final Text firstValue)
  throws IOException {
    Text [] cols = new Text[] {new Text(column)};
    HInternalScannerInterface s = r.getScanner(cols,
      HConstants.EMPTY_START_ROW, System.currentTimeMillis(), null);
    try {
      HStoreKey curKey = new HStoreKey();
      TreeMap<Text, byte []> curVals = new TreeMap<Text, byte []>();
      boolean first = true;
      OUTER_LOOP: while(s.next(curKey, curVals)) {
        for(Text col: curVals.keySet()) {
          byte [] val = curVals.get(col);
          Text curval = new Text(val);
          if (first) {
            first = false;
            assertTrue(curval.compareTo(firstValue) == 0);
          } else {
            // Not asserting anything.  Might as well break.
            break OUTER_LOOP;
          }
        }
      }
    } finally {
      s.close();
    }
  }
 
  private HRegion [] split(final HRegion r) throws IOException {
    Text midKey = new Text();
    assertTrue(r.needsSplit(midKey));
    // Assert can get mid key from passed region.
    assertGet(r, COLFAMILY_NAME3, midKey);
    HRegion [] regions = r.closeAndSplit(midKey, null);
    assertEquals(regions.length, 2);
    return regions;
  }
}
TOP

Related Classes of org.apache.hadoop.hbase.TestSplit

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.