From 6231da1ca3eecbb993ed65bade5b0e0ccafc6988 Mon Sep 17 00:00:00 2001 From: Pooya Salehi Date: Wed, 25 Jun 2025 17:42:58 +0200 Subject: [PATCH] ..wip --- .../cluster/block/ClusterBlocks.java | 38 +++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/cluster/block/ClusterBlocks.java b/server/src/main/java/org/elasticsearch/cluster/block/ClusterBlocks.java index 522d47009ec29..ed20623e26c85 100644 --- a/server/src/main/java/org/elasticsearch/cluster/block/ClusterBlocks.java +++ b/server/src/main/java/org/elasticsearch/cluster/block/ClusterBlocks.java @@ -17,6 +17,7 @@ import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.cluster.metadata.MetadataIndexStateService; import org.elasticsearch.cluster.metadata.ProjectId; +import org.elasticsearch.cluster.metadata.ProjectMetadata; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Writeable; @@ -43,7 +44,7 @@ public class ClusterBlocks implements Diffable { private static final ClusterBlock[] EMPTY_BLOCKS_ARRAY = new ClusterBlock[0]; - public static final ClusterBlocks EMPTY_CLUSTER_BLOCK = new ClusterBlocks(Set.of(), Map.of()); + public static final ClusterBlocks EMPTY_CLUSTER_BLOCK = new ClusterBlocks(Set.of(), Map.of(), 0); private final Set global; @@ -57,15 +58,17 @@ public class ClusterBlocks implements Diffable { */ // Package private for testing final Map projectBlocksMap; + private final long projectsWithUnderDeletionBlockGeneration; private final EnumMap levelHolders; - ClusterBlocks(Set global, Map projectBlocksMap) { + ClusterBlocks(Set global, Map projectBlocksMap, long projectsWithUnderDeletionBlockGeneration) { this.global = global; assert projectBlocksMap.values().stream().allMatch(projectBlocks -> projectBlocks.isEmpty() == false) : "Map must not contain projects with empty blocks " + projectBlocksMap; this.projectBlocksMap = projectBlocksMap; this.levelHolders = generateLevelHolders(global, projectBlocksMap); + this.projectsWithUnderDeletionBlockGeneration = projectsWithUnderDeletionBlockGeneration; } public Set global() { @@ -165,6 +168,14 @@ public boolean hasGlobalBlock(ClusterBlock block) { return global.contains(block); } + public boolean hasProjectGlobalBlock(ProjectId projectId, ClusterBlock block) { + var projectBlocks = projectBlocksMap.get(projectId); + if (projectBlocks == null) { + return false; + } + return projectBlocks.projectGlobals().contains(block); + } + public boolean hasGlobalBlockWithId(final int blockId) { for (ClusterBlock clusterBlock : global) { if (clusterBlock.id() == blockId) { @@ -493,7 +504,7 @@ && noProjectOrDefaultProjectOnly(projectBlocksMap) && projectBlocksMap.getOrDefault(Metadata.DEFAULT_PROJECT_ID, ProjectBlocks.EMPTY).indices().isEmpty()) { return EMPTY_CLUSTER_BLOCK; } - return new ClusterBlocks(global, projectBlocksMap); + return new ClusterBlocks(global, projectBlocksMap, 0 /*todo*/); } else { return readFromSingleProjectNode(in); } @@ -506,9 +517,9 @@ private static ClusterBlocks readFromSingleProjectNode(StreamInput in) throws IO return EMPTY_CLUSTER_BLOCK; } if (indicesBlocks.isEmpty()) { - return new ClusterBlocks(global, Map.of()); + return new ClusterBlocks(global, Map.of(), 0); } - return new ClusterBlocks(global, Map.of(Metadata.DEFAULT_PROJECT_ID, new ProjectBlocks(indicesBlocks, Set.of()))); + return new ClusterBlocks(global, Map.of(Metadata.DEFAULT_PROJECT_ID, new ProjectBlocks(indicesBlocks, Set.of())), 0); } private static Set readBlockSet(StreamInput in) throws IOException { @@ -602,6 +613,10 @@ public ClusterBlocks initializeProjects(Set projectIds) { } } + public long projectsWithUnderDeletionBlockGeneration() { + return projectsWithUnderDeletionBlockGeneration; + } + public static Builder builder() { return new Builder(); } @@ -617,6 +632,8 @@ public static class Builder { private final Set global = new HashSet<>(); private final Map projects = new HashMap<>(); + private long projectsWithUnderDeletionBlockGeneration = 0; + private boolean newProjectsWithUnderDeletionBlock = false; public Builder() {} @@ -636,6 +653,7 @@ public Builder blocks(ClusterBlocks blocks) { projectBlocks.indices.get(entry.getKey()).addAll(entry.getValue()); } } + this.projectsWithUnderDeletionBlockGeneration = blocks.projectsWithUnderDeletionBlockGeneration(); return this; } @@ -700,7 +718,10 @@ public Builder removeProject(ProjectId projectId) { public Builder addProjectGlobalBlock(ProjectId projectId, ClusterBlock block) { assert projectId.equals(ProjectId.DEFAULT) == false; - projects.computeIfAbsent(projectId, k -> emptyMutableProjectBlocks()).projectGlobal.add(block); + boolean added = projects.computeIfAbsent(projectId, k -> emptyMutableProjectBlocks()).projectGlobal.add(block); + if (newProjectsWithUnderDeletionBlock == false && block.id() == ProjectMetadata.PROJECT_UNDER_DELETION_BLOCK.id() && added) { + newProjectsWithUnderDeletionBlock = true; + } return this; } @@ -812,7 +833,10 @@ && noProjectOrDefaultProjectOnly(projects) ); } } - return new ClusterBlocks(Set.copyOf(global), Map.copyOf(projectsBuilder)); + long newProjectsWithUnderDeletionBlockGeneration = newProjectsWithUnderDeletionBlock + ? projectsWithUnderDeletionBlockGeneration + 1 + : projectsWithUnderDeletionBlockGeneration; + return new ClusterBlocks(Set.copyOf(global), Map.copyOf(projectsBuilder), newProjectsWithUnderDeletionBlockGeneration); } } }