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.Collections; 023import java.util.List; 024import org.apache.hadoop.hbase.util.Bytes; 025import org.apache.yetus.audience.InterfaceAudience; 026 027import org.apache.hbase.thirdparty.org.apache.commons.collections4.CollectionUtils; 028 029/** 030 * Performs multiple mutations atomically on a single row. The mutations are performed in the order 031 * in which they were added. 032 * <p> 033 * We compare and equate mutations based off their row so be careful putting RowMutations into Sets 034 * or using them as keys in Maps. 035 */ 036@InterfaceAudience.Public 037public class RowMutations implements Row { 038 039 /** 040 * Create a {@link RowMutations} with the specified mutations. 041 * @param mutations the mutations to send 042 * @throws IOException if any row in mutations is different to another 043 */ 044 public static RowMutations of(List<? extends Mutation> mutations) throws IOException { 045 if (CollectionUtils.isEmpty(mutations)) { 046 throw new IllegalArgumentException("Cannot instantiate a RowMutations by empty list"); 047 } 048 return new RowMutations(mutations.get(0).getRow(), mutations.size()).add(mutations); 049 } 050 051 private final List<Mutation> mutations; 052 private final byte[] row; 053 054 public RowMutations(byte[] row) { 055 this(row, -1); 056 } 057 058 /** 059 * Create an atomic mutation for the specified row. 060 * @param row row key 061 * @param initialCapacity the initial capacity of the RowMutations 062 */ 063 public RowMutations(byte[] row, int initialCapacity) { 064 this.row = Bytes.copy(Mutation.checkRow(row)); 065 if (initialCapacity <= 0) { 066 this.mutations = new ArrayList<>(); 067 } else { 068 this.mutations = new ArrayList<>(initialCapacity); 069 } 070 } 071 072 /** 073 * Add a mutation 074 * @param mutation The data to send. 075 * @throws IOException if the row of added mutation doesn't match the original row 076 */ 077 public RowMutations add(Mutation mutation) throws IOException { 078 return add(Collections.singletonList(mutation)); 079 } 080 081 /** 082 * Add a list of mutations 083 * @param mutations The data to send. 084 * @throws IOException if the row of added mutation doesn't match the original row 085 */ 086 public RowMutations add(List<? extends Mutation> mutations) throws IOException { 087 for (Mutation mutation : mutations) { 088 if (!Bytes.equals(row, mutation.getRow())) { 089 throw new WrongRowIOException( 090 "The row in the recently added Mutation <" + Bytes.toStringBinary(mutation.getRow()) 091 + "> doesn't match the original one <" + Bytes.toStringBinary(this.row) + ">"); 092 } 093 } 094 this.mutations.addAll(mutations); 095 return this; 096 } 097 098 @Override 099 public byte[] getRow() { 100 return row; 101 } 102 103 /** Returns An unmodifiable list of the current mutations. */ 104 public List<Mutation> getMutations() { 105 return Collections.unmodifiableList(mutations); 106 } 107 108 public int getMaxPriority() { 109 int maxPriority = Integer.MIN_VALUE; 110 for (Mutation mutation : mutations) { 111 maxPriority = Math.max(maxPriority, mutation.getPriority()); 112 } 113 return maxPriority; 114 } 115}