001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.client;
019
020import java.util.HashMap;
021import java.util.Map;
022import java.util.TreeMap;
023import org.apache.hadoop.hbase.util.Bytes;
024import org.apache.yetus.audience.InterfaceAudience;
025
026import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos;
027
028/**
029 * A container for Result objects, grouped by regionName.
030 */
031@InterfaceAudience.Private
032public class MultiResponse extends AbstractResponse {
033
034  // map of regionName to map of Results by the original index for that Result
035  private Map<byte[], RegionResult> results = new TreeMap<>(Bytes.BYTES_COMPARATOR);
036
037  /**
038   * The server can send us a failure for the region itself, instead of individual failure. It's a
039   * part of the protobuf definition.
040   */
041  private Map<byte[], Throwable> exceptions = new TreeMap<>(Bytes.BYTES_COMPARATOR);
042
043  public MultiResponse() {
044    super();
045  }
046
047  /** Returns Number of pairs in this container */
048  public int size() {
049    int size = 0;
050    for (RegionResult result : results.values()) {
051      size += result.size();
052    }
053    return size;
054  }
055
056  /** Add the pair to the container, grouped by the regionName. */
057  public void add(byte[] regionName, int originalIndex, Object resOrEx) {
058    getResult(regionName).addResult(originalIndex, resOrEx);
059  }
060
061  public void addException(byte[] regionName, Throwable ie) {
062    exceptions.put(regionName, ie);
063  }
064
065  /** Returns the exception for the region, if any. Null otherwise. */
066  public Throwable getException(byte[] regionName) {
067    return exceptions.get(regionName);
068  }
069
070  public Map<byte[], Throwable> getExceptions() {
071    return exceptions;
072  }
073
074  public void addStatistic(byte[] regionName, ClientProtos.RegionLoadStats stat) {
075    getResult(regionName).setStat(stat);
076  }
077
078  private RegionResult getResult(byte[] region) {
079    RegionResult rs = results.get(region);
080    if (rs == null) {
081      rs = new RegionResult();
082      results.put(region, rs);
083    }
084    return rs;
085  }
086
087  public Map<byte[], RegionResult> getResults() {
088    return this.results;
089  }
090
091  @Override
092  public ResponseType type() {
093    return ResponseType.MULTI;
094  }
095
096  static class RegionResult {
097    Map<Integer, Object> result = new HashMap<>();
098    ClientProtos.RegionLoadStats stat;
099
100    public void addResult(int index, Object result) {
101      this.result.put(index, result);
102    }
103
104    public void setStat(ClientProtos.RegionLoadStats stat) {
105      this.stat = stat;
106    }
107
108    public int size() {
109      return this.result.size();
110    }
111
112    public ClientProtos.RegionLoadStats getStat() {
113      return this.stat;
114    }
115  }
116}