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