From 95ee211edf7ad7bedf1d31377df05c08cedc92ac Mon Sep 17 00:00:00 2001 From: Apekshit Sharma Date: Fri, 11 May 2018 02:07:05 -0700 Subject: [PATCH] HBASE-20594 Provide utility to get table desc delta Ammending Author: Mike Drob --- .../hadoop/hbase/client/TableDescriptorUtils.java | 79 ++++++++++++++++++++++ .../hbase/client/TestTableDescriptorUtils.java | 71 +++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 hbase-client/src/main/java/org/apache/hadoop/hbase/client/TableDescriptorUtils.java create mode 100644 hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestTableDescriptorUtils.java diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/TableDescriptorUtils.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/TableDescriptorUtils.java new file mode 100644 index 0000000000..1ba4b5e176 --- /dev/null +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/TableDescriptorUtils.java @@ -0,0 +1,79 @@ +/** + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.hbase.client; + +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.hbase.thirdparty.com.google.common.base.Preconditions; +import org.apache.yetus.audience.InterfaceAudience; + +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; + +@InterfaceAudience.Public +public class TableDescriptorUtils { + public static class TableDescriptorDelta { + public Set columnsAdded = new TreeSet<>(Bytes.BYTES_COMPARATOR); + public Set columnsDeleted = new TreeSet<>(Bytes.BYTES_COMPARATOR); + public Set columnsModified = new TreeSet<>(Bytes.BYTES_COMPARATOR); + } + + private TableDescriptorUtils() { } + + /** + * Compares two TableDescriptors and returns which columns were added, deleted, or modified from oldTD to newTD + * @return a TableDescriptorDelta that contains the added/deleted/modified column names + */ + public static TableDescriptorDelta computeDelta(TableDescriptor oldTD, TableDescriptor newTD) { + Preconditions.checkNotNull(oldTD); + Preconditions.checkNotNull(newTD); + + TableDescriptorDelta delta = new TableDescriptorDelta(); + + Map oldCFs = new TreeMap<>(Bytes.BYTES_COMPARATOR); + Set newCFs = new TreeSet<>(Bytes.BYTES_COMPARATOR); + + for (ColumnFamilyDescriptor cfd : oldTD.getColumnFamilies()) { + oldCFs.put(cfd.getName(), cfd); + } + + for (ColumnFamilyDescriptor cfd : newTD.getColumnFamilies()) { + byte[] cfName = cfd.getName(); + newCFs.add(cfName); + + if (!oldCFs.containsKey(cfName)) { + // If column family is in newTD but not oldTD, then it was added + delta.columnsAdded.add(cfName); + } else if (!cfd.equals(oldCFs.get(cfName))) { + // If column family is in both, but not equal, then it was modified + delta.columnsModified.add(cfName); + } + } + + // If column family is in oldTD, but not in newTD, then it got deleted. + for (byte[] cfName : oldCFs.keySet()) { + if (!newCFs.contains(cfName)) { + delta.columnsDeleted.add(cfName); + } + } + + return delta; + } +} diff --git a/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestTableDescriptorUtils.java b/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestTableDescriptorUtils.java new file mode 100644 index 0000000000..ac015340dd --- /dev/null +++ b/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestTableDescriptorUtils.java @@ -0,0 +1,71 @@ +/** + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.hbase.client; + +import org.apache.hadoop.hbase.HBaseClassTestRule; +import org.apache.hadoop.hbase.client.TableDescriptorUtils.TableDescriptorDelta; +import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.testclassification.SmallTests; +import org.apache.hadoop.hbase.util.Bytes; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import java.util.Arrays; + +import static org.junit.Assert.assertEquals; + +@Category(SmallTests.class) +public class TestTableDescriptorUtils { + @ClassRule + public static final HBaseClassTestRule CLASS_RULE = + HBaseClassTestRule.forClass(TestTableDescriptorUtils.class); + + @Test + public void testDelta() { + ColumnFamilyDescriptor cf1 = ColumnFamilyDescriptorBuilder.of("cf1"); + ColumnFamilyDescriptor cf2 = ColumnFamilyDescriptorBuilder.of("cf2"); + ColumnFamilyDescriptor cf3 = ColumnFamilyDescriptorBuilder.of("cf3"); + TableDescriptor td = TableDescriptorBuilder + .newBuilder(TableName.valueOf("test")) + .setColumnFamilies(Arrays.asList(cf1, cf2, cf3)) + .build(); + + TableDescriptorDelta selfCompare = TableDescriptorUtils.computeDelta(td, td); + assertEquals(0, selfCompare.columnsAdded.size()); + assertEquals(0, selfCompare.columnsDeleted.size()); + assertEquals(0, selfCompare.columnsModified.size()); + + ColumnFamilyDescriptor modCf3 = ColumnFamilyDescriptorBuilder + .newBuilder(cf3).setMaxVersions(5).build(); + ColumnFamilyDescriptor cf4 = ColumnFamilyDescriptorBuilder.of("cf4"); + TableDescriptor newTd = TableDescriptorBuilder + .newBuilder(td) + .removeColumnFamily(Bytes.toBytes("cf1")) + .modifyColumnFamily(modCf3) + .setColumnFamily(cf4) + .build(); + + TableDescriptorDelta delta = TableDescriptorUtils.computeDelta(td, newTd); + + assertEquals(1, delta.columnsAdded.size()); + assertEquals(1, delta.columnsDeleted.size()); + assertEquals(1, delta.columnsModified.size()); + } +} -- 2.16.1