De-serializes a MultiResponse. This is only used when talking to HBase 0.92.x to 0.94.x.
(final ChannelBuffer buf)
| 732 | * This is only used when talking to HBase 0.92.x to 0.94.x. |
| 733 | */ |
| 734 | Response deserializeMultiResponse(final ChannelBuffer buf) { |
| 735 | final int nregions = buf.readInt(); |
| 736 | HBaseRpc.checkNonEmptyArrayLength(buf, nregions); |
| 737 | final Object[] resps = new Object[batch.size()]; |
| 738 | int n = 0; // Index in `batch'. |
| 739 | for (int i = 0; i < nregions; i++) { |
| 740 | final byte[] region_name = HBaseRpc.readByteArray(buf); |
| 741 | final int nkeys = buf.readInt(); |
| 742 | HBaseRpc.checkNonEmptyArrayLength(buf, nkeys); |
| 743 | for (int j = 0; j < nkeys; j++) { |
| 744 | final int nrpcs_per_key = buf.readInt(); |
| 745 | boolean error = buf.readByte() != 0x00; |
| 746 | Object resp; // Response for the current region. |
| 747 | if (error) { |
| 748 | final HBaseException e = RegionClient.deserializeException(buf, null); |
| 749 | resp = e; |
| 750 | } else { |
| 751 | resp = RegionClient.deserializeObject(buf, this); |
| 752 | // A successful response to a `Put' will be an empty `Result' |
| 753 | // object, which we de-serialize as an empty `ArrayList'. |
| 754 | // There's no need to waste memory keeping these around. |
| 755 | if (resp instanceof ArrayList && ((ArrayList) resp).isEmpty()) { |
| 756 | resp = SUCCESS; |
| 757 | } else if (resp == null) { |
| 758 | // Awesomely, `null' is used to indicate all RPCs for this region |
| 759 | // have failed, and we're not told why. Most of the time, it will |
| 760 | // be an NSRE, so assume that. What were they thinking when they |
| 761 | // wrote that code in HBase? Seriously WTF. |
| 762 | resp = NSRE; |
| 763 | error = true; |
| 764 | } |
| 765 | } |
| 766 | if (error) { |
| 767 | final HBaseException e = (HBaseException) resp; |
| 768 | for (int k = 0; k < nrpcs_per_key; k++) { |
| 769 | // We need to "clone" the exception for each RPC, as each RPC that |
| 770 | // failed needs to have its own exception with a reference to the |
| 771 | // failed RPC. This makes significantly simplifies the callbacks |
| 772 | // that do error handling, as they can extract the RPC out of the |
| 773 | // exception. The downside is that we don't have a perfect way of |
| 774 | // cloning "e", so instead we just abuse its `make' factory method |
| 775 | // slightly to duplicate it. This mangles the message a bit, but |
| 776 | // that's mostly harmless. |
| 777 | resps[n + k] = e.make(e, batch.get(n + k)); |
| 778 | } |
| 779 | } else { |
| 780 | for (int k = 0; k < nrpcs_per_key; k++) { |
| 781 | resps[n + k] = resp; |
| 782 | } |
| 783 | } |
| 784 | n += nrpcs_per_key; |
| 785 | } |
| 786 | } |
| 787 | return new Response(resps); |
| 788 | } |
| 789 | |
| 790 | /** |
| 791 | * De-serializes a {@code MultiPutResponse}. |
no test coverage detected