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 * @param mutations The data to send. 106 * @throws IOException if the row of added mutation doesn't match the original row 107 */ 108 public RowMutations add(List<? extends Mutation> mutations) throws IOException { 109 for (Mutation mutation : mutations) { 110 if (!Bytes.equals(row, mutation.getRow())) { 111 throw new WrongRowIOException( 112 "The row in the recently added Mutation <" + Bytes.toStringBinary(mutation.getRow()) 113 + "> doesn't match the original one <" + Bytes.toStringBinary(this.row) + ">"); 114 } 115 } 116 this.mutations.addAll(mutations); 117 return this; 118 } 119 120 /** 121 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Use 122 * {@link Row#COMPARATOR} instead 123 */ 124 @Deprecated 125 @Override 126 public int compareTo(Row i) { 127 return Bytes.compareTo(this.getRow(), i.getRow()); 128 } 129 130 /** 131 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. No replacement 132 */ 133 @Deprecated 134 @Override 135 public boolean equals(Object obj) { 136 if (obj == this) return true; 137 if (obj instanceof RowMutations) { 138 RowMutations other = (RowMutations) obj; 139 return compareTo(other) == 0; 140 } 141 return false; 142 } 143 144 /** 145 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. No replacement 146 */ 147 @Deprecated 148 @Override 149 public int hashCode() { 150 return Arrays.hashCode(row); 151 } 152 153 @Override 154 public byte[] getRow() { 155 return row; 156 } 157 158 /** Returns An unmodifiable list of the current mutations. */ 159 public List<Mutation> getMutations() { 160 return Collections.unmodifiableList(mutations); 161 } 162 163 public int getMaxPriority() { 164 int maxPriority = Integer.MIN_VALUE; 165 for (Mutation mutation : mutations) { 166 maxPriority = Math.max(maxPriority, mutation.getPriority()); 167 } 168 return maxPriority; 169 } 170}