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.io.IOException; 021import java.util.ArrayList; 022import java.util.Arrays; 023import java.util.Collections; 024import java.util.List; 025import org.apache.hadoop.hbase.util.Bytes; 026import org.apache.yetus.audience.InterfaceAudience; 027 028import org.apache.hbase.thirdparty.org.apache.commons.collections4.CollectionUtils; 029 030/** 031 * Performs multiple mutations atomically on a single row. The mutations are performed in the order 032 * in which they were added. 033 * <p> 034 * We compare and equate mutations based off their row so be careful putting RowMutations into Sets 035 * or using them as keys in Maps. 036 */ 037@InterfaceAudience.Public 038public class RowMutations implements Row { 039 040 /** 041 * Create a {@link RowMutations} with the specified mutations. 042 * @param mutations the mutations to send 043 * @throws IOException if any row in mutations is different to another 044 */ 045 public static RowMutations of(List<? extends Mutation> mutations) throws IOException { 046 if (CollectionUtils.isEmpty(mutations)) { 047 throw new IllegalArgumentException("Cannot instantiate a RowMutations by empty list"); 048 } 049 return new RowMutations(mutations.get(0).getRow(), mutations.size()).add(mutations); 050 } 051 052 private final List<Mutation> mutations; 053 private final byte[] row; 054 055 public RowMutations(byte[] row) { 056 this(row, -1); 057 } 058 059 /** 060 * Create an atomic mutation for the specified row. 061 * @param row row key 062 * @param initialCapacity the initial capacity of the RowMutations 063 */ 064 public RowMutations(byte[] row, int initialCapacity) { 065 this.row = Bytes.copy(Mutation.checkRow(row)); 066 if (initialCapacity <= 0) { 067 this.mutations = new ArrayList<>(); 068 } else { 069 this.mutations = new ArrayList<>(initialCapacity); 070 } 071 } 072 073 /** 074 * Add a {@link Put} operation to the list of mutations 075 * @param p The {@link Put} to add 076 * @throws IOException if the row of added mutation doesn't match the original row 077 * @deprecated since 2.0 version and will be removed in 3.0 version. use {@link #add(Mutation)} 078 */ 079 @Deprecated 080 public void add(Put p) throws IOException { 081 add((Mutation) p); 082 } 083 084 /** 085 * Add a {@link Delete} operation to the list of mutations 086 * @param d The {@link Delete} to add 087 * @throws IOException if the row of added mutation doesn't match the original row 088 * @deprecated since 2.0 version and will be removed in 3.0 version. use {@link #add(Mutation)} 089 */ 090 @Deprecated 091 public void add(Delete d) throws IOException { 092 add((Mutation) d); 093 } 094 095 /** 096 * Currently only supports {@link Put} and {@link Delete} mutations. 097 * @param mutation The data to send. 098 * @throws IOException if the row of added mutation doesn't match the original row 099 */ 100 public RowMutations add(Mutation mutation) throws IOException { 101 return add(Collections.singletonList(mutation)); 102 } 103 104 /** 105 * Add a list of mutations 106 * @param mutations The data to send. 107 * @throws IOException if the row of added mutation doesn't match the original row 108 */ 109 public RowMutations add(List<? extends Mutation> mutations) throws IOException { 110 for (Mutation mutation : mutations) { 111 if (!Bytes.equals(row, mutation.getRow())) { 112 throw new WrongRowIOException( 113 "The row in the recently added Mutation <" + Bytes.toStringBinary(mutation.getRow()) 114 + "> doesn't match the original one <" + Bytes.toStringBinary(this.row) + ">"); 115 } 116 } 117 this.mutations.addAll(mutations); 118 return this; 119 } 120 121 /** 122 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Use 123 * {@link Row#COMPARATOR} instead 124 */ 125 @Deprecated 126 @Override 127 public int compareTo(Row i) { 128 return Bytes.compareTo(this.getRow(), i.getRow()); 129 } 130 131 /** 132 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. No replacement 133 */ 134 @Deprecated 135 @Override 136 public boolean equals(Object obj) { 137 if (obj == this) return true; 138 if (obj instanceof RowMutations) { 139 RowMutations other = (RowMutations) obj; 140 return compareTo(other) == 0; 141 } 142 return false; 143 } 144 145 /** 146 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. No replacement 147 */ 148 @Deprecated 149 @Override 150 public int hashCode() { 151 return Arrays.hashCode(row); 152 } 153 154 @Override 155 public byte[] getRow() { 156 return row; 157 } 158 159 /** Returns An unmodifiable list of the current mutations. */ 160 public List<Mutation> getMutations() { 161 return Collections.unmodifiableList(mutations); 162 } 163 164 public int getMaxPriority() { 165 int maxPriority = Integer.MIN_VALUE; 166 for (Mutation mutation : mutations) { 167 maxPriority = Math.max(maxPriority, mutation.getPriority()); 168 } 169 return maxPriority; 170 } 171}