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