This is an automated email from the ASF dual-hosted git repository. cshannon pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/accumulo.git
The following commit(s) were added to refs/heads/main by this push: new 80a48cdc60 Filter based on columns declared in TabletMetadataCheck (#5335) 80a48cdc60 is described below commit 80a48cdc60d4c5839763068f988b383878908844 Author: Christopher L. Shannon <cshan...@apache.org> AuthorDate: Fri Feb 14 17:20:58 2025 -0500 Filter based on columns declared in TabletMetadataCheck (#5335) Adds filtering to TabletMetadataCheckIterator that will use matching families for the provided columns in order to reduce the amount of data that is fetched. A ResolvedColumns instance is returned by each TabletMetadataCheck instance that contains the set of columns and set of matching families to read. CompactionReservationCheck caches the ResolvedColumns instance statically to avoid having to recreate the set of columns and familes for each scan. --- .../core/metadata/schema/TabletMetadata.java | 164 ++++++++++++++++++++- .../core/metadata/schema/TabletMetadataCheck.java | 34 ++++- .../core/metadata/schema/TabletsMetadata.java | 105 +------------ .../metadata/schema/TabletMetadataCheckTest.java | 66 +++++++++ .../iterators/TabletMetadataCheckIterator.java | 7 +- .../coordinator/CompactionReservationCheck.java | 10 +- .../compaction/CompactionReservationCheckTest.java | 34 +++++ 7 files changed, 311 insertions(+), 109 deletions(-) diff --git a/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletMetadata.java b/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletMetadata.java index 0efebce8db..c737b0d66b 100644 --- a/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletMetadata.java +++ b/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletMetadata.java @@ -18,15 +18,28 @@ */ package org.apache.accumulo.core.metadata.schema; +import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.MergedColumnFamily.MERGED_COLUMN; +import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ServerColumnFamily.DIRECTORY_COLUMN; import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ServerColumnFamily.DIRECTORY_QUAL; +import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ServerColumnFamily.FLUSH_COLUMN; +import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ServerColumnFamily.FLUSH_NONCE_COLUMN; import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ServerColumnFamily.FLUSH_NONCE_QUAL; import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ServerColumnFamily.FLUSH_QUAL; +import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ServerColumnFamily.OPID_COLUMN; import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ServerColumnFamily.OPID_QUAL; +import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ServerColumnFamily.SELECTED_COLUMN; import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ServerColumnFamily.SELECTED_QUAL; +import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ServerColumnFamily.TIME_COLUMN; import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ServerColumnFamily.TIME_QUAL; +import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.SplitColumnFamily.UNSPLITTABLE_COLUMN; +import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.SuspendLocationColumn.SUSPEND_COLUMN; +import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.TabletColumnFamily.AVAILABILITY_COLUMN; import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.TabletColumnFamily.AVAILABILITY_QUAL; +import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.TabletColumnFamily.MERGEABILITY_COLUMN; import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.TabletColumnFamily.MERGEABILITY_QUAL; +import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.TabletColumnFamily.PREV_ROW_COLUMN; import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.TabletColumnFamily.PREV_ROW_QUAL; +import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.TabletColumnFamily.REQUESTED_COLUMN; import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.TabletColumnFamily.REQUESTED_QUAL; import java.util.Collection; @@ -40,10 +53,12 @@ import java.util.Objects; import java.util.Optional; import java.util.OptionalLong; import java.util.Set; +import java.util.stream.Collectors; import org.apache.accumulo.core.client.admin.TabletAvailability; import org.apache.accumulo.core.clientImpl.ClientContext; import org.apache.accumulo.core.clientImpl.TabletAvailabilityUtil; +import org.apache.accumulo.core.data.ArrayByteSequence; import org.apache.accumulo.core.data.ByteSequence; import org.apache.accumulo.core.data.Key; import org.apache.accumulo.core.data.TableId; @@ -58,6 +73,7 @@ import org.apache.accumulo.core.metadata.AccumuloTable; import org.apache.accumulo.core.metadata.StoredTabletFile; import org.apache.accumulo.core.metadata.SuspendingTServer; import org.apache.accumulo.core.metadata.TServerInstance; +import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection; import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.BulkFileColumnFamily; import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ClonedColumnFamily; import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.CompactedColumnFamily; @@ -75,6 +91,7 @@ import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.Su import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.TabletColumnFamily; import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.UserCompactionRequestedColumnFamily; import org.apache.accumulo.core.tabletserver.log.LogEntry; +import org.apache.accumulo.core.util.ColumnFQ; import org.apache.accumulo.core.zookeeper.ZcStat; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; @@ -202,7 +219,152 @@ public class TabletMetadata { COMPACTED, USER_COMPACTION_REQUESTED, UNSPLITTABLE, - MERGEABILITY + MERGEABILITY; + + public static final Map<ColumnType,Set<Text>> COLUMNS_TO_FAMILIES; + public static final Map<ColumnType,ColumnFQ> COLUMNS_TO_QUALIFIERS; + + static { + ImmutableMap.Builder<ColumnType,Set<Text>> colsToFamilies = ImmutableMap.builder(); + ImmutableMap.Builder<ColumnType,ColumnFQ> colsToQualifiers = ImmutableMap.builder(); + + for (ColumnType column : EnumSet.allOf(ColumnType.class)) { + switch (column) { + case CLONED: + colsToFamilies.put(column, Set.of(ClonedColumnFamily.NAME)); + break; + case DIR: + case FLUSH_ID: + case TIME: + case OPID: + case SELECTED: + case FLUSH_NONCE: + colsToFamilies.put(column, Set.of(ServerColumnFamily.NAME)); + break; + case FILES: + colsToFamilies.put(column, Set.of(DataFileColumnFamily.NAME)); + break; + case AVAILABILITY: + case HOSTING_REQUESTED: + case PREV_ROW: + case MERGEABILITY: + colsToFamilies.put(column, Set.of(TabletColumnFamily.NAME)); + break; + case LAST: + colsToFamilies.put(column, Set.of(LastLocationColumnFamily.NAME)); + break; + case LOADED: + colsToFamilies.put(column, Set.of(BulkFileColumnFamily.NAME)); + break; + case LOCATION: + colsToFamilies.put(column, + Set.of(CurrentLocationColumnFamily.NAME, FutureLocationColumnFamily.NAME)); + break; + case LOGS: + colsToFamilies.put(column, Set.of(LogColumnFamily.NAME)); + break; + case SCANS: + colsToFamilies.put(column, Set.of(ScanFileColumnFamily.NAME)); + break; + case SUSPEND: + colsToFamilies.put(column, Set.of(SuspendLocationColumn.NAME)); + break; + case ECOMP: + colsToFamilies.put(column, Set.of(ExternalCompactionColumnFamily.NAME)); + break; + case MERGED: + colsToFamilies.put(column, Set.of(MergedColumnFamily.NAME)); + break; + case COMPACTED: + colsToFamilies.put(column, Set.of(CompactedColumnFamily.NAME)); + break; + case USER_COMPACTION_REQUESTED: + colsToFamilies.put(column, Set.of(UserCompactionRequestedColumnFamily.NAME)); + break; + case UNSPLITTABLE: + colsToFamilies.put(column, Set.of(SplitColumnFamily.NAME)); + break; + default: + throw new IllegalArgumentException("Unknown col type " + column); + } + } + + for (ColumnType column : EnumSet.allOf(ColumnType.class)) { + switch (column) { + case CLONED: + case COMPACTED: + case ECOMP: + case FILES: + case LAST: + case LOADED: + case LOCATION: + case LOGS: + case SCANS: + case USER_COMPACTION_REQUESTED: + break; + case DIR: + colsToQualifiers.put(column, DIRECTORY_COLUMN); + break; + case FLUSH_ID: + colsToQualifiers.put(column, FLUSH_COLUMN); + break; + case TIME: + colsToQualifiers.put(column, TIME_COLUMN); + break; + case OPID: + colsToQualifiers.put(column, OPID_COLUMN); + break; + case SELECTED: + colsToQualifiers.put(column, SELECTED_COLUMN); + break; + case FLUSH_NONCE: + colsToQualifiers.put(column, FLUSH_NONCE_COLUMN); + break; + case AVAILABILITY: + colsToQualifiers.put(column, AVAILABILITY_COLUMN); + break; + case HOSTING_REQUESTED: + colsToQualifiers.put(column, REQUESTED_COLUMN); + break; + case PREV_ROW: + colsToQualifiers.put(column, PREV_ROW_COLUMN); + break; + case MERGEABILITY: + colsToQualifiers.put(column, MERGEABILITY_COLUMN); + break; + case SUSPEND: + colsToQualifiers.put(column, SUSPEND_COLUMN); + break; + case MERGED: + colsToQualifiers.put(column, MERGED_COLUMN); + break; + case UNSPLITTABLE: + colsToQualifiers.put(column, UNSPLITTABLE_COLUMN); + break; + default: + throw new IllegalArgumentException("Unknown col type " + column); + } + } + + COLUMNS_TO_FAMILIES = colsToFamilies.build(); + COLUMNS_TO_QUALIFIERS = colsToQualifiers.build(); + } + + public static Set<ByteSequence> resolveFamilies(Set<ColumnType> columns) { + return columns.stream() + .flatMap(cf -> COLUMNS_TO_FAMILIES.get(cf).stream() + .map(family -> new ArrayByteSequence(family.copyBytes()))) + .collect(Collectors.toUnmodifiableSet()); + } + + public static Set<Text> resolveFamiliesAsText(ColumnType column) { + return COLUMNS_TO_FAMILIES.get(column); + } + + public static ColumnFQ resolveQualifier(ColumnType columnType) { + return COLUMNS_TO_QUALIFIERS.get(columnType); + } + } public static class Location { diff --git a/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletMetadataCheck.java b/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletMetadataCheck.java index 8aed438fe8..e3cd96120e 100644 --- a/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletMetadataCheck.java +++ b/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletMetadataCheck.java @@ -20,8 +20,12 @@ package org.apache.accumulo.core.metadata.schema; import java.util.Collections; import java.util.EnumSet; +import java.util.Objects; import java.util.Set; +import org.apache.accumulo.core.data.ByteSequence; +import org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType; + /** * This interface facilitates atomic checks of tablet metadata prior to updating tablet metadata. * The way it is intended to be used is the following. @@ -45,13 +49,35 @@ public interface TabletMetadataCheck { Set<TabletMetadata.ColumnType> ALL_COLUMNS = Collections.unmodifiableSet(EnumSet.allOf(TabletMetadata.ColumnType.class)); + ResolvedColumns ALL_RESOLVED_COLUMNS = new ResolvedColumns(ALL_COLUMNS); + boolean canUpdate(TabletMetadata tabletMetadata); /** - * Determines what tablet metadata columns are read on the server side. Return - * {@link #ALL_COLUMNS} to read all of a tablets metadata. + * Determines what tablet metadata columns/families are read on the server side. Return + * {@link #ALL_RESOLVED_COLUMNS} to read all of a tablets metadata. If all columns are included, + * the families set will be empty which means read all families. */ - default Set<TabletMetadata.ColumnType> columnsToRead() { - return ALL_COLUMNS; + default ResolvedColumns columnsToRead() { + return ALL_RESOLVED_COLUMNS; + } + + class ResolvedColumns { + private final Set<TabletMetadata.ColumnType> columns; + private final Set<ByteSequence> families; + + public ResolvedColumns(Set<ColumnType> columns) { + this.columns = Objects.requireNonNull(columns); + this.families = columns.equals(ALL_COLUMNS) ? Set.of() : ColumnType.resolveFamilies(columns); + } + + public EnumSet<ColumnType> getColumns() { + return EnumSet.copyOf(columns); + } + + public Set<ByteSequence> getFamilies() { + return families; + } } + } diff --git a/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletsMetadata.java b/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletsMetadata.java index 04115dfaea..26d157eb19 100644 --- a/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletsMetadata.java +++ b/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletsMetadata.java @@ -21,12 +21,7 @@ package org.apache.accumulo.core.metadata.schema; import static com.google.common.base.Preconditions.checkState; import static java.util.stream.Collectors.groupingBy; import static java.util.stream.Collectors.toList; -import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ServerColumnFamily.DIRECTORY_COLUMN; -import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ServerColumnFamily.FLUSH_COLUMN; -import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ServerColumnFamily.OPID_COLUMN; -import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ServerColumnFamily.SELECTED_COLUMN; -import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ServerColumnFamily.TIME_COLUMN; -import static org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.TabletColumnFamily.PREV_ROW_COLUMN; +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.PREV_ROW; import java.io.IOException; import java.io.UncheckedIOException; @@ -64,21 +59,6 @@ import org.apache.accumulo.core.iterators.user.WholeRowIterator; import org.apache.accumulo.core.metadata.AccumuloTable; import org.apache.accumulo.core.metadata.schema.Ample.DataLevel; import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection; -import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.BulkFileColumnFamily; -import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ClonedColumnFamily; -import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.CompactedColumnFamily; -import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.CurrentLocationColumnFamily; -import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.DataFileColumnFamily; -import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ExternalCompactionColumnFamily; -import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.FutureLocationColumnFamily; -import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.LastLocationColumnFamily; -import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.LogColumnFamily; -import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.MergedColumnFamily; -import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ScanFileColumnFamily; -import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.SplitColumnFamily; -import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.SuspendLocationColumn; -import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.TabletColumnFamily; -import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.UserCompactionRequestedColumnFamily; import org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType; import org.apache.accumulo.core.metadata.schema.filters.TabletMetadataFilter; import org.apache.accumulo.core.security.Authorizations; @@ -325,84 +305,15 @@ public class TabletsMetadata implements Iterable<TabletMetadata>, AutoCloseable @Override public Options fetch(ColumnType... colsToFetch) { Preconditions.checkArgument(colsToFetch.length > 0); - - for (ColumnType colToFetch : colsToFetch) { - - fetchedCols.add(colToFetch); - - switch (colToFetch) { - case CLONED: - families.add(ClonedColumnFamily.NAME); - break; - case DIR: - qualifiers.add(DIRECTORY_COLUMN); - break; - case FILES: - families.add(DataFileColumnFamily.NAME); - break; - case FLUSH_ID: - qualifiers.add(FLUSH_COLUMN); - break; - case AVAILABILITY: - qualifiers.add(TabletsSection.TabletColumnFamily.AVAILABILITY_COLUMN); - break; - case HOSTING_REQUESTED: - qualifiers.add(TabletsSection.TabletColumnFamily.REQUESTED_COLUMN); - break; - case LAST: - families.add(LastLocationColumnFamily.NAME); - break; - case LOADED: - families.add(BulkFileColumnFamily.NAME); - break; - case LOCATION: - families.add(CurrentLocationColumnFamily.NAME); - families.add(FutureLocationColumnFamily.NAME); - break; - case LOGS: - families.add(LogColumnFamily.NAME); - break; - case PREV_ROW: - qualifiers.add(PREV_ROW_COLUMN); - break; - case SCANS: - families.add(ScanFileColumnFamily.NAME); - break; - case SUSPEND: - families.add(SuspendLocationColumn.SUSPEND_COLUMN.getColumnFamily()); - break; - case TIME: - qualifiers.add(TIME_COLUMN); - break; - case ECOMP: - families.add(ExternalCompactionColumnFamily.NAME); - break; - case MERGED: - families.add(MergedColumnFamily.NAME); - break; - case OPID: - qualifiers.add(OPID_COLUMN); - break; - case SELECTED: - qualifiers.add(SELECTED_COLUMN); - break; - case COMPACTED: - families.add(CompactedColumnFamily.NAME); - break; - case USER_COMPACTION_REQUESTED: - families.add(UserCompactionRequestedColumnFamily.NAME); - break; - case UNSPLITTABLE: - qualifiers.add(SplitColumnFamily.UNSPLITTABLE_COLUMN); - break; - case MERGEABILITY: - qualifiers.add(TabletColumnFamily.MERGEABILITY_COLUMN); - break; - default: - throw new IllegalArgumentException("Unknown col type " + colToFetch); + for (var col : fetchedCols) { + fetchedCols.add(col); + var qualifier = ColumnType.resolveQualifier(col); + if (qualifier != null) { + qualifiers.add(qualifier); + } else { + families.addAll(ColumnType.resolveFamiliesAsText(col)); } } - return this; } diff --git a/core/src/test/java/org/apache/accumulo/core/metadata/schema/TabletMetadataCheckTest.java b/core/src/test/java/org/apache/accumulo/core/metadata/schema/TabletMetadataCheckTest.java new file mode 100644 index 0000000000..8ca0925786 --- /dev/null +++ b/core/src/test/java/org/apache/accumulo/core/metadata/schema/TabletMetadataCheckTest.java @@ -0,0 +1,66 @@ +/* + * 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 + * + * https://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.accumulo.core.metadata.schema; + +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.DIR; +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.ECOMP; +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.FILES; +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.PREV_ROW; +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.SCANS; +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.SELECTED; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.EnumSet; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.accumulo.core.data.ArrayByteSequence; +import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.DataFileColumnFamily; +import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ExternalCompactionColumnFamily; +import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ScanFileColumnFamily; +import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ServerColumnFamily; +import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.TabletColumnFamily; +import org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType; +import org.apache.accumulo.core.metadata.schema.TabletMetadataCheck.ResolvedColumns; +import org.junit.jupiter.api.Test; + +public class TabletMetadataCheckTest { + + @Test + public void testResolvedColumns() { + // check columns is empty set when all columns is used + var resolved1 = new ResolvedColumns(TabletMetadataCheck.ALL_COLUMNS); + assertTrue(resolved1.getFamilies().isEmpty()); + assertTrue(TabletMetadataCheck.ALL_RESOLVED_COLUMNS.getFamilies().isEmpty()); + + // Add some column types and verify resolved families is not empty and is correct + var expectedColumnTypes = EnumSet.of(PREV_ROW, SELECTED, FILES, ECOMP, SCANS, DIR); + var expectedFamilies = Set + .of(ServerColumnFamily.NAME, TabletColumnFamily.NAME, DataFileColumnFamily.NAME, + ScanFileColumnFamily.NAME, ExternalCompactionColumnFamily.NAME) + .stream().map(family -> new ArrayByteSequence(family.copyBytes())) + .collect(Collectors.toSet()); + var resolved2 = new ResolvedColumns(expectedColumnTypes); + assertEquals(expectedColumnTypes, resolved2.getColumns()); + assertEquals(ColumnType.resolveFamilies(resolved2.getColumns()), resolved2.getFamilies()); + assertEquals(expectedFamilies, resolved2.getFamilies()); + } + +} diff --git a/server/base/src/main/java/org/apache/accumulo/server/metadata/iterators/TabletMetadataCheckIterator.java b/server/base/src/main/java/org/apache/accumulo/server/metadata/iterators/TabletMetadataCheckIterator.java index ba08be04a7..e149d02596 100644 --- a/server/base/src/main/java/org/apache/accumulo/server/metadata/iterators/TabletMetadataCheckIterator.java +++ b/server/base/src/main/java/org/apache/accumulo/server/metadata/iterators/TabletMetadataCheckIterator.java @@ -23,11 +23,9 @@ import static org.apache.accumulo.server.metadata.iterators.ColumnFamilyTransfor import java.io.IOException; import java.util.Collection; -import java.util.EnumSet; import java.util.Map; import java.util.NoSuchElementException; import java.util.Objects; -import java.util.Set; import org.apache.accumulo.core.classloader.ClassLoaderUtil; import org.apache.accumulo.core.client.IteratorSetting; @@ -98,11 +96,12 @@ public class TabletMetadataCheckIterator implements SortedKeyValueIterator<Key,V var colsToRead = check.columnsToRead(); - source.seek(new Range(tabletRow), Set.of(), false); + source.seek(new Range(tabletRow), colsToRead.getFamilies(), + !colsToRead.getFamilies().isEmpty()); if (source.hasTop()) { var tabletMetadata = TabletMetadata.convertRow(new IteratorAdapter(source), - EnumSet.copyOf(colsToRead), false, false); + colsToRead.getColumns(), false, false); // TODO checking the prev end row here is redundant w/ other checks that ample currently // does.. however we could try to make all checks eventually use this class diff --git a/server/manager/src/main/java/org/apache/accumulo/manager/compaction/coordinator/CompactionReservationCheck.java b/server/manager/src/main/java/org/apache/accumulo/manager/compaction/coordinator/CompactionReservationCheck.java index f9c2d5841c..f1cd9e6e83 100644 --- a/server/manager/src/main/java/org/apache/accumulo/manager/compaction/coordinator/CompactionReservationCheck.java +++ b/server/manager/src/main/java/org/apache/accumulo/manager/compaction/coordinator/CompactionReservationCheck.java @@ -35,7 +35,6 @@ import java.util.stream.Collectors; import org.apache.accumulo.core.fate.FateId; import org.apache.accumulo.core.metadata.StoredTabletFile; import org.apache.accumulo.core.metadata.schema.TabletMetadata; -import org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType; import org.apache.accumulo.core.metadata.schema.TabletMetadataCheck; import org.apache.accumulo.core.spi.compaction.CompactionKind; import org.apache.accumulo.core.util.time.SteadyTime; @@ -51,6 +50,11 @@ public class CompactionReservationCheck implements TabletMetadataCheck { private static final Logger log = LoggerFactory.getLogger(CompactionReservationCheck.class); + // Cache the ResolvedColumns statically so we do not need to recreate the set of + // columns and families for each mutation + private static final ResolvedColumns RESOLVED_COLUMNS = new ResolvedColumns( + Set.of(PREV_ROW, OPID, SELECTED, FILES, ECOMP, USER_COMPACTION_REQUESTED)); + private CompactionKind kind; private List<String> jobFilesStr; private Long steadyTimeNanos; @@ -163,7 +167,7 @@ public class CompactionReservationCheck implements TabletMetadataCheck { } @Override - public Set<ColumnType> columnsToRead() { - return Set.of(PREV_ROW, OPID, SELECTED, FILES, ECOMP, USER_COMPACTION_REQUESTED); + public ResolvedColumns columnsToRead() { + return RESOLVED_COLUMNS; } } diff --git a/server/manager/src/test/java/org/apache/accumulo/manager/compaction/CompactionReservationCheckTest.java b/server/manager/src/test/java/org/apache/accumulo/manager/compaction/CompactionReservationCheckTest.java index 65540deea0..3812fdd6d0 100644 --- a/server/manager/src/test/java/org/apache/accumulo/manager/compaction/CompactionReservationCheckTest.java +++ b/server/manager/src/test/java/org/apache/accumulo/manager/compaction/CompactionReservationCheckTest.java @@ -19,19 +19,26 @@ package org.apache.accumulo.manager.compaction; import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.ECOMP; +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.FILES; import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.OPID; +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.PREV_ROW; import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.SELECTED; import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.USER_COMPACTION_REQUESTED; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import java.net.URI; import java.time.Duration; +import java.util.EnumSet; import java.util.Set; import java.util.UUID; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import org.apache.accumulo.core.data.ArrayByteSequence; import org.apache.accumulo.core.data.TableId; import org.apache.accumulo.core.dataImpl.KeyExtent; import org.apache.accumulo.core.fate.FateId; @@ -41,8 +48,14 @@ import org.apache.accumulo.core.metadata.StoredTabletFile; import org.apache.accumulo.core.metadata.schema.CompactionMetadata; import org.apache.accumulo.core.metadata.schema.DataFileValue; import org.apache.accumulo.core.metadata.schema.ExternalCompactionId; +import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.DataFileColumnFamily; +import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ExternalCompactionColumnFamily; +import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ServerColumnFamily; +import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.TabletColumnFamily; +import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.UserCompactionRequestedColumnFamily; import org.apache.accumulo.core.metadata.schema.SelectedFiles; import org.apache.accumulo.core.metadata.schema.TabletMetadata; +import org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType; import org.apache.accumulo.core.metadata.schema.TabletOperationId; import org.apache.accumulo.core.metadata.schema.TabletOperationType; import org.apache.accumulo.core.spi.compaction.CompactionKind; @@ -214,6 +227,27 @@ public class CompactionReservationCheckTest { () -> canReserveUser(null, CompactionKind.USER, Set.of(file1, file2), fateId1, time)); } + @Test + public void testResolvedColumns() throws Exception { + var resolved1 = new CompactionReservationCheck(CompactionKind.SYSTEM, Set.of(), null, false, + SteadyTime.from(Duration.ZERO), 100L).columnsToRead(); + var resolved2 = new CompactionReservationCheck(CompactionKind.SYSTEM, Set.of(), null, false, + SteadyTime.from(Duration.ZERO), 100L).columnsToRead(); + var expectedColumnTypes = + EnumSet.of(PREV_ROW, OPID, SELECTED, FILES, ECOMP, USER_COMPACTION_REQUESTED); + var expectedFamilies = Set + .of(ServerColumnFamily.NAME, TabletColumnFamily.NAME, DataFileColumnFamily.NAME, + ExternalCompactionColumnFamily.NAME, UserCompactionRequestedColumnFamily.NAME) + .stream().map(family -> new ArrayByteSequence(family.copyBytes())) + .collect(Collectors.toSet()); + + // Verify same object is re-used across instances + assertSame(resolved1, resolved2); + assertEquals(expectedColumnTypes, resolved1.getColumns()); + assertEquals(ColumnType.resolveFamilies(expectedColumnTypes), resolved1.getFamilies()); + assertEquals(expectedFamilies, resolved1.getFamilies()); + } + private boolean canReserveSystem(TabletMetadata tabletMetadata, CompactionKind kind, Set<StoredTabletFile> jobFiles, boolean deletingSelected, SteadyTime steadyTime) { var check = new CompactionReservationCheck(CompactionKind.SYSTEM, jobFiles, null,