Skip to content

Commit

Permalink
IGNITE-23413 Create RebalanceMinimumRequiredTimeProvider interface an…
Browse files Browse the repository at this point in the history
…d its implementation (#4769)
  • Loading branch information
ibessonov authored Dec 10, 2024
1 parent c1d88a3 commit 31ab613
Show file tree
Hide file tree
Showing 9 changed files with 918 additions and 14 deletions.
10 changes: 10 additions & 0 deletions check-rules/spotbugs-excludes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,16 @@
<Class name="org.apache.ignite.internal.distributionzones.DistributionZonesUtil"/>
<Field name="DISTRIBUTION_ZONE_DATA_NODES_VALUE_PREFIX_BYTES"/>
</Match>
<Match>
<!-- I literally have no idea why these checks fail. -->
<Bug pattern="MS_PKGPROTECT"/>
<Class name="org.apache.ignite.internal.distributionzones.rebalance.RebalanceUtil"/>
<Or>
<Field name="STABLE_ASSIGNMENTS_PREFIX_BYTES"/>
<Field name="PENDING_ASSIGNMENTS_PREFIX_BYTES"/>
<Field name="PENDING_CHANGE_TRIGGER_PREFIX_BYTES"/>
</Or>
</Match>
<!-- end of false-positive exclusions -->


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,24 @@ public String storageProfile() {
return storageProfile;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}

CatalogStorageProfileDescriptor that = (CatalogStorageProfileDescriptor) o;
return storageProfile.equals(that.storageProfile);
}

@Override
public int hashCode() {
return storageProfile.hashCode();
}

/**
* Serializer for {@link CatalogStorageProfilesDescriptor}.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,21 @@ public class CatalogZoneDescriptor extends CatalogObjectDescriptor {
*/
private final ConsistencyMode consistencyMode;

/**
* Returns {@code true} if zone upgrade will lead to assignments recalculation.
*/
public static boolean updateRequiresAssignmentsRecalculation(CatalogZoneDescriptor oldDescriptor, CatalogZoneDescriptor newDescriptor) {
if (oldDescriptor.updateToken() == newDescriptor.updateToken()) {
return false;
}

return oldDescriptor.partitions != newDescriptor.partitions
|| oldDescriptor.replicas != newDescriptor.replicas
|| !oldDescriptor.filter.equals(newDescriptor.filter)
|| !oldDescriptor.storageProfiles.profiles().equals(newDescriptor.storageProfiles.profiles())
|| oldDescriptor.consistencyMode != newDescriptor.consistencyMode;
}

/**
* Constructs a distribution zone descriptor.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,28 @@

package org.apache.ignite.internal.catalog.descriptors;

import static java.util.Collections.emptyList;
import static org.apache.ignite.internal.catalog.CatalogService.DEFAULT_STORAGE_PROFILE;
import static org.apache.ignite.internal.catalog.commands.CatalogUtils.fromParams;
import static org.apache.ignite.internal.catalog.descriptors.CatalogZoneDescriptor.updateRequiresAssignmentsRecalculation;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.List;
import java.util.function.Function;
import org.apache.ignite.internal.catalog.Catalog;
import org.apache.ignite.internal.catalog.commands.AlterZoneCommand;
import org.apache.ignite.internal.catalog.commands.AlterZoneCommandBuilder;
import org.apache.ignite.internal.catalog.commands.StorageProfileParams;
import org.apache.ignite.internal.catalog.storage.AlterZoneEntry;
import org.junit.jupiter.api.Test;

class CatalogZoneDescriptorTest {
@Test
void toStringContainsTypeAndFields() {
var descriptor = new CatalogZoneDescriptor(
1,
"zone1",
2,
3,
4,
5,
6,
"the-filter",
fromParams(List.of(StorageProfileParams.builder().storageProfile(DEFAULT_STORAGE_PROFILE).build())),
ConsistencyMode.STRONG_CONSISTENCY
);
var descriptor = createZoneDescriptor();

String toString = descriptor.toString();

Expand All @@ -57,4 +54,73 @@ void toStringContainsTypeAndFields() {
assertThat(toString, containsString("storageProfiles=CatalogStorageProfilesDescriptor ["));
assertThat(toString, containsString("consistencyMode=STRONG_CONSISTENCY"));
}

@Test
void testUpdateRequiresAssignmentsRecalculationAutoAdjust() {
doTestUpdateRequiresAssignmentsRecalculation(builder -> builder.dataNodesAutoAdjust(100), false);
}

@Test
void testUpdateRequiresAssignmentsRecalculationAutoAdjustScaleUp() {
doTestUpdateRequiresAssignmentsRecalculation(builder -> builder.dataNodesAutoAdjustScaleUp(100), false);
}

@Test
void testUpdateRequiresAssignmentsRecalculationAutoAdjustScaleDown() {
doTestUpdateRequiresAssignmentsRecalculation(builder -> builder.dataNodesAutoAdjustScaleDown(100), false);
}

@Test
void testUpdateRequiresAssignmentsRecalculationFilter() {
doTestUpdateRequiresAssignmentsRecalculation(builder -> builder.filter("foo"), true);
}

@Test
void testUpdateRequiresAssignmentsRecalculationReplicas() {
doTestUpdateRequiresAssignmentsRecalculation(builder -> builder.replicas(100500), true);
}

@Test
void testUpdateRequiresAssignmentsRecalculationStorageProfiles() {
doTestUpdateRequiresAssignmentsRecalculation(builder -> builder.storageProfilesParams(
List.of(StorageProfileParams.builder().storageProfile(DEFAULT_STORAGE_PROFILE + "2").build())
), true);
}

private static void doTestUpdateRequiresAssignmentsRecalculation(
Function<AlterZoneCommandBuilder, AlterZoneCommandBuilder> alter,
boolean expectedResult
) {
var oldZone = createZoneDescriptor();

Catalog catalog = createCatalogWithSingleZone(oldZone);

var alterZoneCommand = (AlterZoneCommand) alter.apply(AlterZoneCommand.builder().zoneName(oldZone.name())).build();

var alterZoneEntry = (AlterZoneEntry) alterZoneCommand.get(catalog).get(0);
alterZoneEntry.applyUpdate(catalog, oldZone.updateToken() + 1);

CatalogZoneDescriptor newZone = alterZoneEntry.descriptor();

assertEquals(expectedResult, updateRequiresAssignmentsRecalculation(oldZone, newZone));
}

private static CatalogZoneDescriptor createZoneDescriptor() {
return new CatalogZoneDescriptor(
1,
"zone1",
2,
3,
4,
5,
6,
"the-filter",
fromParams(List.of(StorageProfileParams.builder().storageProfile(DEFAULT_STORAGE_PROFILE).build())),
ConsistencyMode.STRONG_CONSISTENCY
);
}

private static Catalog createCatalogWithSingleZone(CatalogZoneDescriptor zone) {
return new Catalog(1, 1, 1, List.of(zone), emptyList(), zone.id());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* 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.ignite.internal.distributionzones.rebalance;

/**
* Interface required for catalog compaction to determine a version for compaction.
*/
@SuppressWarnings("InterfaceMayBeAnnotatedFunctional")
public interface RebalanceMinimumRequiredTimeProvider {
/**
* Returns the minimum time required for rebalance, or current timestamp if there are no active rebalances and there is a guarantee that
* all rebalances launched in the future will use catalog version corresponding to the current time or greater.
*/
long minimumRequiredTime();
}
Loading

0 comments on commit 31ab613

Please sign in to comment.