View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.wal;
20  
21  import java.util.concurrent.ConcurrentHashMap;
22  import java.util.concurrent.atomic.AtomicInteger;
23  
24  import org.apache.hadoop.conf.Configuration;
25  import org.apache.hadoop.hbase.classification.InterfaceAudience;
26  import org.apache.hadoop.hbase.util.Bytes;
27  import org.apache.hadoop.hbase.wal.RegionGroupingProvider.RegionGroupingStrategy;
28  
29  /**
30   * A WAL grouping strategy that limits the number of wal groups to
31   * "hbase.wal.regiongrouping.numgroups".
32   */
33  @InterfaceAudience.Private
34  public class BoundedGroupingStrategy implements RegionGroupingStrategy{
35  
36    static final String NUM_REGION_GROUPS = "hbase.wal.regiongrouping.numgroups";
37    static final int DEFAULT_NUM_REGION_GROUPS = 2;
38  
39    private ConcurrentHashMap<String, String> groupNameCache =
40        new ConcurrentHashMap<String, String>();
41    private AtomicInteger counter = new AtomicInteger(0);
42    private String[] groupNames;
43  
44    @Override
45    public String group(byte[] identifier, byte[] namespace) {
46      String idStr = Bytes.toString(identifier);
47      String groupName = groupNameCache.get(idStr);
48      if (null == groupName) {
49        groupName = groupNames[getAndIncrAtomicInteger(counter, groupNames.length)];
50        String extantName = groupNameCache.putIfAbsent(idStr, groupName);
51        if (extantName != null) {
52          return extantName;
53        }
54      }
55      return groupName;
56    }
57  
58    // Non-blocking incrementing & resetting of AtomicInteger.
59    private int getAndIncrAtomicInteger(AtomicInteger atomicInt, int reset) {
60      for (;;) {
61        int current = atomicInt.get();
62        int next = (current + 1);
63        if (next == reset) {
64          next = 0;
65        }
66        if (atomicInt.compareAndSet(current, next)) return current;
67      }
68    }
69  
70    @Override
71    public void init(Configuration config, String providerId) {
72      int regionGroupNumber = config.getInt(NUM_REGION_GROUPS, DEFAULT_NUM_REGION_GROUPS);
73      groupNames = new String[regionGroupNumber];
74      for (int i = 0; i < regionGroupNumber; i++) {
75        groupNames[i] = "regiongroup-" + i;
76      }
77    }
78  
79  }