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