001/* 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019package org.apache.hadoop.hbase.client; 020 021import java.util.ArrayList; 022import java.util.Collections; 023import java.util.List; 024import java.util.Map; 025import java.util.Optional; 026import java.util.Set; 027import java.util.TreeMap; 028import org.apache.hadoop.hbase.HConstants; 029import org.apache.hadoop.hbase.util.Bytes; 030import org.apache.yetus.audience.InterfaceAudience; 031 032/** 033 * Container for Actions (i.e. Get, Delete, or Put), which are grouped by 034 * regionName. Intended to be used with {@link AsyncProcess}. 035 */ 036@InterfaceAudience.Private 037public final class MultiAction { 038 // TODO: This class should not be visible outside of the client package. 039 040 // map of regions to lists of puts/gets/deletes for that region. 041 protected Map<byte[], List<Action>> actions = new TreeMap<>(Bytes.BYTES_COMPARATOR); 042 043 private long nonceGroup = HConstants.NO_NONCE; 044 045 public MultiAction() { 046 super(); 047 } 048 049 /** 050 * Get the total number of Actions 051 * 052 * @return total number of Actions for all groups in this container. 053 */ 054 public int size() { 055 int size = 0; 056 for (List<?> l : actions.values()) { 057 size += l.size(); 058 } 059 return size; 060 } 061 062 /** 063 * Add an Action to this container based on it's regionName. If the regionName 064 * is wrong, the initial execution will fail, but will be automatically 065 * retried after looking up the correct region. 066 * 067 * @param regionName 068 * @param a 069 */ 070 public void add(byte[] regionName, Action a) { 071 add(regionName, Collections.singletonList(a)); 072 } 073 074 /** 075 * Add an Action to this container based on it's regionName. If the regionName 076 * is wrong, the initial execution will fail, but will be automatically 077 * retried after looking up the correct region. 078 * 079 * @param regionName 080 * @param actionList list of actions to add for the region 081 */ 082 public void add(byte[] regionName, List<Action> actionList){ 083 List<Action> rsActions = actions.get(regionName); 084 if (rsActions == null) { 085 rsActions = new ArrayList<>(actionList.size()); 086 actions.put(regionName, rsActions); 087 } 088 rsActions.addAll(actionList); 089 } 090 091 public void setNonceGroup(long nonceGroup) { 092 this.nonceGroup = nonceGroup; 093 } 094 095 public Set<byte[]> getRegions() { 096 return actions.keySet(); 097 } 098 099 public boolean hasNonceGroup() { 100 return nonceGroup != HConstants.NO_NONCE; 101 } 102 103 public long getNonceGroup() { 104 return this.nonceGroup; 105 } 106 107 // returns the max priority of all the actions 108 public int getPriority() { 109 Optional<Action> result = actions.values().stream().flatMap(List::stream) 110 .max((action1, action2) -> Math.max(action1.getPriority(), action2.getPriority())); 111 return result.isPresent() ? result.get().getPriority() : HConstants.PRIORITY_UNSET; 112 } 113}