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 */ 019 020package org.apache.hadoop.hbase.client; 021 022import java.util.HashMap; 023import java.util.Map; 024import java.util.TreeMap; 025 026import org.apache.yetus.audience.InterfaceAudience; 027import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos; 028import org.apache.hadoop.hbase.util.Bytes; 029 030/** 031 * A container for Result objects, grouped by regionName. 032 */ 033@InterfaceAudience.Private 034public class MultiResponse extends AbstractResponse { 035 036 // map of regionName to map of Results by the original index for that Result 037 private Map<byte[], RegionResult> results = new TreeMap<>(Bytes.BYTES_COMPARATOR); 038 039 /** 040 * The server can send us a failure for the region itself, instead of individual failure. 041 * It's a part of the protobuf definition. 042 */ 043 private Map<byte[], Throwable> exceptions = 044 new TreeMap<>(Bytes.BYTES_COMPARATOR); 045 046 public MultiResponse() { 047 super(); 048 } 049 050 /** 051 * @return Number of pairs in this container 052 */ 053 public int size() { 054 int size = 0; 055 for (RegionResult result: results.values()) { 056 size += result.size(); 057 } 058 return size; 059 } 060 061 /** 062 * Add the pair to the container, grouped by the regionName 063 * 064 * @param regionName 065 * @param originalIndex the original index of the Action (request). 066 * @param resOrEx the result or error; will be empty for successful Put and Delete actions. 067 */ 068 public void add(byte[] regionName, int originalIndex, Object resOrEx) { 069 getResult(regionName).addResult(originalIndex, resOrEx); 070 } 071 072 public void addException(byte []regionName, Throwable ie){ 073 exceptions.put(regionName, ie); 074 } 075 076 /** 077 * @return the exception for the region, if any. Null otherwise. 078 */ 079 public Throwable getException(byte []regionName){ 080 return exceptions.get(regionName); 081 } 082 083 public Map<byte[], Throwable> getExceptions() { 084 return exceptions; 085 } 086 087 public void addStatistic(byte[] regionName, ClientProtos.RegionLoadStats stat) { 088 getResult(regionName).setStat(stat); 089 } 090 091 private RegionResult getResult(byte[] region){ 092 RegionResult rs = results.get(region); 093 if (rs == null) { 094 rs = new RegionResult(); 095 results.put(region, rs); 096 } 097 return rs; 098 } 099 100 public Map<byte[], RegionResult> getResults(){ 101 return this.results; 102 } 103 104 @Override 105 public ResponseType type() { 106 return ResponseType.MULTI; 107 } 108 109 static class RegionResult{ 110 Map<Integer, Object> result = new HashMap<>(); 111 ClientProtos.RegionLoadStats stat; 112 113 public void addResult(int index, Object result){ 114 this.result.put(index, result); 115 } 116 117 public void setStat(ClientProtos.RegionLoadStats stat){ 118 this.stat = stat; 119 } 120 121 public int size() { 122 return this.result.size(); 123 } 124 125 public ClientProtos.RegionLoadStats getStat() { 126 return this.stat; 127 } 128 } 129}