diff --git a/core/src/main/java/org/apache/accumulo/core/client/admin/TabletMergeability.java b/core/src/main/java/org/apache/accumulo/core/client/admin/TabletMergeability.java index 1b4edfc6895..cf6444cf524 100644 --- a/core/src/main/java/org/apache/accumulo/core/client/admin/TabletMergeability.java +++ b/core/src/main/java/org/apache/accumulo/core/client/admin/TabletMergeability.java @@ -24,11 +24,14 @@ import com.google.common.base.Preconditions; +/** + * @since 4.0.0 + */ public class TabletMergeability implements Serializable { private static final long serialVersionUID = 1L; - public static final TabletMergeability NEVER = new TabletMergeability(Duration.ofNanos(-1)); - public static final TabletMergeability NOW = new TabletMergeability(Duration.ZERO); + private static final TabletMergeability NEVER = new TabletMergeability(Duration.ofNanos(-1)); + private static final TabletMergeability NOW = new TabletMergeability(Duration.ZERO); private final Duration delay; @@ -36,18 +39,47 @@ private TabletMergeability(Duration delay) { this.delay = Objects.requireNonNull(delay); } + /** + * Determines if the configured delay signals a tablet is never eligible to be automatically + * merged. (Has a delay of -1) + * + * @return true if never mergeable, else false + */ public boolean isNever() { return this.delay.isNegative(); } + /** + * Determines if the configured delay signals a tablet is always eligible to be automatically + * merged now. (Has a delay of 0) + * + * @return true if always mergeable now, else false + */ public boolean isNow() { return this.delay.isZero(); } - public boolean isFuture() { + /** + * Determines if the configured delay signals a tablet has a configured delay before being + * eligible to be automatically merged. (Has a positive delay) + * + * @return true if there is a configured delay, else false + */ + public boolean isDelayed() { return delay.toNanos() > 0; } + /** + * Returns the duration of the delay which is one of: + * + * + * + * @return the configured mergeability delay + */ public Duration getDelay() { return delay; } @@ -73,15 +105,53 @@ public String toString() { } else if (isNever()) { return "TabletMergeability=NEVER"; } - return "TabletMergeability=AFTER:" + delay.toNanos(); + return "TabletMergeability=AFTER:" + delay.toMillis() + "ms"; + } + + /** + * Signifies that a tablet is never eligible to be automatically merged. + * + * @return a {@link TabletMergeability} with a delay of -1 signaling never merge + */ + public static TabletMergeability never() { + return NEVER; + } + + /** + * Signifies that a tablet is eligible now to be automatically merged + * + * @return a {@link TabletMergeability} with a delay of 0 signaling never merge + */ + public static TabletMergeability now() { + return NOW; } + /** + * Creates a {@link TabletMergeability} from the given delay. The duration must be one of + * + * + * @param delay the duration of the delay + * + * @return a {@link TabletMergeability} from the given delay. + */ public static TabletMergeability from(Duration delay) { Preconditions.checkArgument(delay.toNanos() >= -1, - "Duration of delay must be -1, 0, or a positive offset."); + "Duration of delay must be -1, 0, or a positive delay."); return new TabletMergeability(delay); } + /** + * Creates a {@link TabletMergeability} that signals a tablet has a delay to a point in the future + * before it is automatically eligible to be merged. The duration must be positive value. + * + * @param delay the duration of the delay + * + * @return a {@link TabletMergeability} from the given delay. + */ public static TabletMergeability after(Duration delay) { Preconditions.checkArgument(delay.toNanos() > 0, "Duration of delay must be greater than 0."); return new TabletMergeability(delay); diff --git a/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletMergeabilityMetadata.java b/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletMergeabilityMetadata.java index deee2c98398..0fa18652874 100644 --- a/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletMergeabilityMetadata.java +++ b/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletMergeabilityMetadata.java @@ -35,10 +35,10 @@ public class TabletMergeabilityMetadata implements Serializable { private static final long serialVersionUID = 1L; - public static final TabletMergeabilityMetadata NEVER = - new TabletMergeabilityMetadata(TabletMergeability.NEVER); - public static final TabletMergeabilityMetadata NOW = - new TabletMergeabilityMetadata(TabletMergeability.NOW); + private static final TabletMergeabilityMetadata NEVER = + new TabletMergeabilityMetadata(TabletMergeability.never()); + private static final TabletMergeabilityMetadata NOW = + new TabletMergeabilityMetadata(TabletMergeability.now()); private final TabletMergeability tabletMergeability; private final SteadyTime steadyTime; @@ -46,7 +46,7 @@ public class TabletMergeabilityMetadata implements Serializable { private TabletMergeabilityMetadata(TabletMergeability tabletMergeability, SteadyTime steadyTime) { this.tabletMergeability = Objects.requireNonNull(tabletMergeability); this.steadyTime = steadyTime; - Preconditions.checkArgument(tabletMergeability.isFuture() == (steadyTime != null), + Preconditions.checkArgument(tabletMergeability.isDelayed() == (steadyTime != null), "SteadyTime must be set if and only if TabletMergeability delay is greater than 0."); } @@ -114,6 +114,14 @@ public String toString() { return "TabletMergeabilityMetadata{" + tabletMergeability + ", " + steadyTime + '}'; } + public static TabletMergeabilityMetadata now() { + return NOW; + } + + public static TabletMergeabilityMetadata never() { + return NEVER; + } + public static TabletMergeabilityMetadata after(Duration delay, SteadyTime currentTime) { return from(TabletMergeability.after(delay), currentTime); } 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 94e247c734a..2b59f78431d 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 @@ -702,7 +702,7 @@ static class Builder { private final ImmutableSet.Builder compacted = ImmutableSet.builder(); private final ImmutableSet.Builder userCompactionsRequested = ImmutableSet.builder(); private UnSplittableMetadata unSplittableMetadata; - private TabletMergeabilityMetadata mergeability = TabletMergeabilityMetadata.NEVER; + private TabletMergeabilityMetadata mergeability = TabletMergeabilityMetadata.never(); void table(TableId tableId) { this.tableId = tableId; diff --git a/core/src/test/java/org/apache/accumulo/core/metadata/schema/TabletMetadataTest.java b/core/src/test/java/org/apache/accumulo/core/metadata/schema/TabletMetadataTest.java index c969f0c5f2a..679e9a29c20 100644 --- a/core/src/test/java/org/apache/accumulo/core/metadata/schema/TabletMetadataTest.java +++ b/core/src/test/java/org/apache/accumulo/core/metadata/schema/TabletMetadataTest.java @@ -644,7 +644,7 @@ public void testBuilder() { .putFile(sf1, dfv1).putFile(sf2, dfv2).putBulkFile(rf1, loadedFateId1) .putBulkFile(rf2, loadedFateId2).putFlushId(27).putDirName("dir1").putScan(sf3).putScan(sf4) .putCompacted(compactFateId1).putCompacted(compactFateId2).putCloned() - .putTabletMergeability(TabletMergeabilityMetadata.NOW) + .putTabletMergeability(TabletMergeabilityMetadata.now()) .build(ECOMP, HOSTING_REQUESTED, MERGED, USER_COMPACTION_REQUESTED, UNSPLITTABLE); assertEquals(extent, tm.getExtent()); @@ -664,7 +664,7 @@ public void testBuilder() { assertFalse(tm.hasMerged()); assertNull(tm.getUnSplittable()); assertEquals("OK", tm.getCloned()); - assertEquals(TabletMergeabilityMetadata.NOW, tm.getTabletMergeability()); + assertEquals(TabletMergeabilityMetadata.now(), tm.getTabletMergeability()); assertThrows(IllegalStateException.class, tm::getOperationId); assertThrows(IllegalStateException.class, tm::getSuspend); assertThrows(IllegalStateException.class, tm::getTime); diff --git a/server/base/src/main/java/org/apache/accumulo/server/init/FileSystemInitializer.java b/server/base/src/main/java/org/apache/accumulo/server/init/FileSystemInitializer.java index 6ba0285546d..ef6536da098 100644 --- a/server/base/src/main/java/org/apache/accumulo/server/init/FileSystemInitializer.java +++ b/server/base/src/main/java/org/apache/accumulo/server/init/FileSystemInitializer.java @@ -95,7 +95,7 @@ private Map createEntries() { var builder = TabletMetadata.builder(keyExtent).putDirName(dirName) .putTime(new MetadataTime(0, TimeType.LOGICAL)) .putTabletAvailability(TabletAvailability.HOSTED) - .putTabletMergeability(TabletMergeabilityMetadata.NEVER).putPrevEndRow(prevEndRow); + .putTabletMergeability(TabletMergeabilityMetadata.never()).putPrevEndRow(prevEndRow); for (String file : files) { builder.putFile(new ReferencedTabletFile(new Path(file)).insert(), new DataFileValue(0, 0)); } diff --git a/server/base/src/test/java/org/apache/accumulo/server/constraints/MetadataConstraintsTest.java b/server/base/src/test/java/org/apache/accumulo/server/constraints/MetadataConstraintsTest.java index 33db16efb7f..2162fa328c6 100644 --- a/server/base/src/test/java/org/apache/accumulo/server/constraints/MetadataConstraintsTest.java +++ b/server/base/src/test/java/org/apache/accumulo/server/constraints/MetadataConstraintsTest.java @@ -664,13 +664,13 @@ public void testMergeabilityColumn() { m = new Mutation(new Text("0;foo")); TabletColumnFamily.MERGEABILITY_COLUMN.put(m, - TabletMergeabilityMetadata.toValue(TabletMergeabilityMetadata.NEVER)); + TabletMergeabilityMetadata.toValue(TabletMergeabilityMetadata.never())); violations = mc.check(createEnv(), m); assertTrue(violations.isEmpty()); m = new Mutation(new Text("0;foo")); TabletColumnFamily.MERGEABILITY_COLUMN.put(m, - TabletMergeabilityMetadata.toValue(TabletMergeabilityMetadata.NOW)); + TabletMergeabilityMetadata.toValue(TabletMergeabilityMetadata.now())); violations = mc.check(createEnv(), m); assertTrue(violations.isEmpty()); diff --git a/server/manager/src/main/java/org/apache/accumulo/manager/FateServiceHandler.java b/server/manager/src/main/java/org/apache/accumulo/manager/FateServiceHandler.java index 161e97e01cc..7cdde03dc52 100644 --- a/server/manager/src/main/java/org/apache/accumulo/manager/FateServiceHandler.java +++ b/server/manager/src/main/java/org/apache/accumulo/manager/FateServiceHandler.java @@ -257,7 +257,7 @@ public void executeFateOperation(TInfo tinfo, TCredentials c, TFateId opid, TFat manager.fate(type).seedTransaction(op, fateId, new TraceRepo<>(new CreateTable(c.getPrincipal(), tableName, timeType, options, splitsPath, splitCount, splitsDirsPath, initialTableState, - initialTabletAvailability, namespaceId, TabletMergeabilityMetadata.NEVER)), + initialTabletAvailability, namespaceId, TabletMergeabilityMetadata.never())), autoCleanup, goalMessage); break; diff --git a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/split/UpdateTablets.java b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/split/UpdateTablets.java index 146bb726a6a..33e27fd42e2 100644 --- a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/split/UpdateTablets.java +++ b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/split/UpdateTablets.java @@ -219,8 +219,8 @@ private void addNewTablets(FateId fateId, Manager manager, TabletMetadata tablet .debug("{} copying compacted marker to new child tablet {}", fateId, compactedFateId)); mutator.putTabletAvailability(tabletMetadata.getTabletAvailability()); - mutator.putTabletMergeability(splitInfo.isSystemCreated() ? TabletMergeabilityMetadata.NOW - : TabletMergeabilityMetadata.NEVER); + mutator.putTabletMergeability(splitInfo.isSystemCreated() ? TabletMergeabilityMetadata.now() + : TabletMergeabilityMetadata.never()); tabletMetadata.getLoaded().forEach((k, v) -> mutator.putBulkFile(k.getTabletFile(), v)); newTabletsFiles.get(newExtent).forEach(mutator::putFile); diff --git a/server/manager/src/test/java/org/apache/accumulo/manager/tableOps/merge/MergeTabletsTest.java b/server/manager/src/test/java/org/apache/accumulo/manager/tableOps/merge/MergeTabletsTest.java index e6c26aca7b2..8ce711c2c44 100644 --- a/server/manager/src/test/java/org/apache/accumulo/manager/tableOps/merge/MergeTabletsTest.java +++ b/server/manager/src/test/java/org/apache/accumulo/manager/tableOps/merge/MergeTabletsTest.java @@ -152,7 +152,7 @@ public void testManyColumns() throws Exception { var availability = TabletAvailability.HOSTED; var lastLocation = TabletMetadata.Location.last("1.2.3.4:1234", "123456789"); var suspendingTServer = SuspendingTServer.fromValue(new Value("1.2.3.4:5|56")); - var mergeability = TabletMergeabilityMetadata.NOW; + var mergeability = TabletMergeabilityMetadata.now(); var tablet1 = TabletMetadata.builder(ke1).putOperation(opid).putDirName("td1").putFile(file3, dfv3) @@ -234,7 +234,7 @@ public void testManyColumns() throws Exception { EasyMock.expect(tabletMutator.deleteSuspension()).andReturn(tabletMutator); EasyMock.expect(tabletMutator.deleteLocation(lastLocation)).andReturn(tabletMutator); EasyMock.expect(tabletMutator.deleteUnSplittable()).andReturn(tabletMutator); - EasyMock.expect(tabletMutator.putTabletMergeability(TabletMergeabilityMetadata.NOW)) + EasyMock.expect(tabletMutator.putTabletMergeability(TabletMergeabilityMetadata.now())) .andReturn(tabletMutator).once(); }); @@ -405,7 +405,7 @@ public void testTime() throws Exception { .once(); EasyMock.expect(tabletMutator.setMerged()).andReturn(tabletMutator).once(); // Current default if not set is NEVER - EasyMock.expect(tabletMutator.putTabletMergeability(TabletMergeabilityMetadata.NEVER)) + EasyMock.expect(tabletMutator.putTabletMergeability(TabletMergeabilityMetadata.never())) .andReturn(tabletMutator).once(); }); } diff --git a/server/manager/src/test/java/org/apache/accumulo/manager/tableOps/split/UpdateTabletsTest.java b/server/manager/src/test/java/org/apache/accumulo/manager/tableOps/split/UpdateTabletsTest.java index 2f46b671e90..fd88264a5cc 100644 --- a/server/manager/src/test/java/org/apache/accumulo/manager/tableOps/split/UpdateTabletsTest.java +++ b/server/manager/src/test/java/org/apache/accumulo/manager/tableOps/split/UpdateTabletsTest.java @@ -296,7 +296,7 @@ public void testManyColumns() throws Exception { .andReturn(tablet1Mutator); EasyMock.expect(tablet1Mutator.putFile(file2, dfv2)).andReturn(tablet1Mutator); // SplitInfo marked as system generated so should be set to NOW - EasyMock.expect(tablet1Mutator.putTabletMergeability(TabletMergeabilityMetadata.NOW)) + EasyMock.expect(tablet1Mutator.putTabletMergeability(TabletMergeabilityMetadata.now())) .andReturn(tablet1Mutator); tablet1Mutator.submit(EasyMock.anyObject()); EasyMock.expectLastCall().once(); @@ -315,7 +315,7 @@ public void testManyColumns() throws Exception { EasyMock.expect(tablet2Mutator.putCompacted(ucfid3)).andReturn(tablet2Mutator); EasyMock.expect(tablet2Mutator.putTabletAvailability(availability)).andReturn(tablet2Mutator); // SplitInfo marked as system generated so should be set to NOW - EasyMock.expect(tablet2Mutator.putTabletMergeability(TabletMergeabilityMetadata.NOW)) + EasyMock.expect(tablet2Mutator.putTabletMergeability(TabletMergeabilityMetadata.now())) .andReturn(tablet2Mutator); EasyMock.expect(tablet2Mutator.putBulkFile(loaded1.getTabletFile(), flid1)) .andReturn(tablet2Mutator); diff --git a/test/src/main/java/org/apache/accumulo/test/ample/metadata/TestAmple.java b/test/src/main/java/org/apache/accumulo/test/ample/metadata/TestAmple.java index 5113e0772eb..4d8f8c44fd4 100644 --- a/test/src/main/java/org/apache/accumulo/test/ample/metadata/TestAmple.java +++ b/test/src/main/java/org/apache/accumulo/test/ample/metadata/TestAmple.java @@ -150,7 +150,7 @@ public void createMetadata(TableId tableId) { tabletMutator.putDirName(dirName); tabletMutator.putTime(new MetadataTime(0, TimeType.MILLIS)); tabletMutator.putTabletAvailability(TabletAvailability.HOSTED); - tabletMutator.putTabletMergeability(TabletMergeabilityMetadata.NEVER); + tabletMutator.putTabletMergeability(TabletMergeabilityMetadata.never()); tabletMutator.mutate(); } catch (Exception e) { throw new IllegalStateException(e); diff --git a/test/src/main/java/org/apache/accumulo/test/functional/AddSplitIT.java b/test/src/main/java/org/apache/accumulo/test/functional/AddSplitIT.java index fd2644974e0..72ff2bb8ca3 100644 --- a/test/src/main/java/org/apache/accumulo/test/functional/AddSplitIT.java +++ b/test/src/main/java/org/apache/accumulo/test/functional/AddSplitIT.java @@ -96,7 +96,7 @@ public void addSplitTest() throws Exception { TableId id = TableId.of(c.tableOperations().tableIdMap().get(tableName)); try (TabletsMetadata tm = getServerContext().getAmple().readTablets().forTable(id).build()) { // Default for user created tablets should be mergeability set to NEVER - tm.stream().forEach(tablet -> assertEquals(TabletMergeabilityMetadata.NEVER, + tm.stream().forEach(tablet -> assertEquals(TabletMergeabilityMetadata.never(), tablet.getTabletMergeability())); } } diff --git a/test/src/main/java/org/apache/accumulo/test/functional/MetadataIT.java b/test/src/main/java/org/apache/accumulo/test/functional/MetadataIT.java index ffd392e6446..e805143e672 100644 --- a/test/src/main/java/org/apache/accumulo/test/functional/MetadataIT.java +++ b/test/src/main/java/org/apache/accumulo/test/functional/MetadataIT.java @@ -290,7 +290,7 @@ private void testCommonSystemTableConfig(ClientContext client, TableId tableId, assertTrue( tablets.stream().allMatch(tm -> tm.getTabletAvailability() == TabletAvailability.HOSTED)); assertTrue(tablets.stream() - .allMatch(tm -> tm.getTabletMergeability().equals(TabletMergeabilityMetadata.NEVER))); + .allMatch(tm -> tm.getTabletMergeability().equals(TabletMergeabilityMetadata.never()))); } } } diff --git a/test/src/main/java/org/apache/accumulo/test/functional/SplitIT.java b/test/src/main/java/org/apache/accumulo/test/functional/SplitIT.java index d5a5e4a4f56..0a4da6ef9d3 100644 --- a/test/src/main/java/org/apache/accumulo/test/functional/SplitIT.java +++ b/test/src/main/java/org/apache/accumulo/test/functional/SplitIT.java @@ -263,8 +263,8 @@ public void tabletShouldSplit() throws Exception { .equals(entry.getKey().getColumnQualifier())) { // Default tablet should be set to NEVER, all newly generated system splits should be // set to NOW - var mergeability = extent.endRow() == null ? TabletMergeabilityMetadata.NEVER - : TabletMergeabilityMetadata.NOW; + var mergeability = extent.endRow() == null ? TabletMergeabilityMetadata.never() + : TabletMergeabilityMetadata.now(); assertEquals(mergeability, TabletMergeabilityMetadata.fromValue(entry.getValue())); } count++;