1   /**
2    * Copyright 2010 The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  package org.apache.hadoop.hbase.regionserver;
21  
22  import com.google.common.collect.Lists;
23  import org.apache.hadoop.conf.Configuration;
24  import org.apache.hadoop.fs.FileSystem;
25  import org.apache.hadoop.fs.Path;
26  import org.apache.hadoop.hbase.*;
27  import org.apache.hadoop.hbase.client.Mutation;
28  import org.apache.hadoop.hbase.client.Put;
29  import org.apache.hadoop.hbase.io.HeapSize;
30  import org.apache.hadoop.hbase.regionserver.wal.HLog;
31  import org.apache.hadoop.hbase.util.Bytes;
32  import org.apache.hadoop.hbase.util.HashedBytes;
33  import org.apache.hadoop.hbase.util.Pair;
34  import org.junit.Test;
35  import org.junit.experimental.categories.Category;
36  
37  import java.io.IOException;
38  import java.util.List;
39  
40  import static org.junit.Assert.assertEquals;
41  
42  
43  @Category(SmallTests.class)
44  public class TestBatchHRegionLockingAndWrites {
45    private static final String FAMILY = "a";
46  
47    @Test
48    @SuppressWarnings("unchecked")
49    public void testRedundantRowKeys() throws Exception {
50  
51      final int batchSize = 100000;
52  
53      String tableName = getClass().getSimpleName();
54      Configuration conf = HBaseConfiguration.create();
55      conf.setClass(HConstants.REGION_IMPL, MockHRegion.class, HeapSize.class);
56      MockHRegion region = (MockHRegion) TestHRegion.initHRegion(Bytes.toBytes(tableName), tableName, conf, Bytes.toBytes("a"));
57  
58      List<Pair<Mutation, Integer>> someBatch = Lists.newArrayList();
59      int i = 0;
60      while (i < batchSize) {
61        if (i % 2 == 0) {
62          someBatch.add(new Pair<Mutation, Integer>(new Put(Bytes.toBytes(0)), null));
63        } else {
64          someBatch.add(new Pair<Mutation, Integer>(new Put(Bytes.toBytes(1)), null));
65        }
66        i++;
67      }
68      long start = System.nanoTime();
69      region.batchMutate(someBatch.toArray(new Pair[0]));
70      long duration = System.nanoTime() - start;
71      System.out.println("Batch mutate took: " + duration + "ns");
72      assertEquals(2, region.getAcquiredLockCount());
73    }
74  
75    @Test
76    public void testGettingTheLockMatchesMyRow() throws Exception {
77      MockHRegion region = getMockHRegion();
78      HashedBytes rowKey = new HashedBytes(Bytes.toBytes(1));
79      assertEquals(Integer.valueOf(2), region.getLock(null, rowKey, false));
80      assertEquals(Integer.valueOf(2), region.getLock(2, rowKey, false));
81    }
82  
83    private MockHRegion getMockHRegion() throws IOException {
84      String tableName = getClass().getSimpleName();
85      Configuration conf = HBaseConfiguration.create();
86      conf.setClass(HConstants.REGION_IMPL, MockHRegion.class, HeapSize.class);
87      return (MockHRegion) TestHRegion.initHRegion(Bytes.toBytes(tableName), tableName, conf, Bytes.toBytes(FAMILY));
88    }
89  
90    private static class MockHRegion extends HRegion {
91      private int acqioredLockCount = 0;
92  
93      public MockHRegion(Path tableDir, HLog log, FileSystem fs, Configuration conf, final HRegionInfo regionInfo, final HTableDescriptor htd, RegionServerServices rsServices) {
94        super(tableDir, log, fs, conf, regionInfo, htd, rsServices);
95      }
96  
97      private int getAcquiredLockCount() {
98        return acqioredLockCount;
99      }
100 
101     @Override
102     public Integer getLock(Integer lockid, HashedBytes row, boolean waitForLock) throws IOException {
103       acqioredLockCount++;
104       return super.getLock(lockid, row, waitForLock);
105     }
106   }
107 }