This is an automated email from the ASF dual-hosted git repository.
noble pushed a commit to branch branch_9x
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/branch_9x by this push:
new 60e2c6309fd SOLR-16712: Simplify DocCollection ctor for PRS enabled
collection (#1477)
60e2c6309fd is described below
commit 60e2c6309fd762eccbf62c4256ab2ab72a8c4694
Author: patsonluk <[email protected]>
AuthorDate: Wed Apr 26 06:05:18 2023 -0700
SOLR-16712: Simplify DocCollection ctor for PRS enabled collection (#1477)
---
.../solr/cloud/DistributedClusterStateUpdater.java | 3 +-
.../solr/cloud/overseer/ClusterStateMutator.java | 2 +-
.../solr/cloud/overseer/CollectionMutator.java | 2 +-
.../apache/solr/cloud/overseer/ZkStateWriter.java | 13 +-
.../org/apache/solr/cloud/ClusterStateTest.java | 6 +-
.../OverseerCollectionConfigSetProcessorTest.java | 2 +-
.../solr/cloud/overseer/ZkStateReaderTest.java | 44 +++----
.../solr/cloud/overseer/ZkStateWriterTest.java | 14 +--
.../client/solrj/cloud/DistribStateManager.java | 15 ++-
.../solrj/impl/ZkClientClusterStateProvider.java | 2 +-
.../solr/common/cloud/PerReplicaStatesFetcher.java | 7 +-
.../apache/solr/common/cloud/ZkStateReader.java | 4 +-
.../solrj/impl/BaseHttpClusterStateProvider.java | 12 +-
.../org/apache/solr/common/cloud/ClusterState.java | 2 +-
.../apache/solr/common/cloud/DocCollection.java | 134 ++++++++++++++-------
.../apache/solr/common/cloud/PerReplicaStates.java | 4 +
.../java/org/apache/solr/common/cloud/Replica.java | 19 +--
.../java/org/apache/solr/common/cloud/Slice.java | 11 +-
18 files changed, 176 insertions(+), 120 deletions(-)
diff --git
a/solr/core/src/java/org/apache/solr/cloud/DistributedClusterStateUpdater.java
b/solr/core/src/java/org/apache/solr/cloud/DistributedClusterStateUpdater.java
index d8c05146d33..935f32e5940 100644
---
a/solr/core/src/java/org/apache/solr/cloud/DistributedClusterStateUpdater.java
+++
b/solr/core/src/java/org/apache/solr/cloud/DistributedClusterStateUpdater.java
@@ -511,7 +511,8 @@ public class DistributedClusterStateUpdater {
// Transpose the per replica states into the cluster state
updatedState =
updatedState.copyWith(
- updater.getCollectionName(),
docCollection.copyWith(fetchedPerReplicaStates));
+ updater.getCollectionName(),
+
docCollection.setPerReplicaStates(fetchedPerReplicaStates));
}
}
diff --git
a/solr/core/src/java/org/apache/solr/cloud/overseer/ClusterStateMutator.java
b/solr/core/src/java/org/apache/solr/cloud/overseer/ClusterStateMutator.java
index a8faa27fbf8..2c625b2c5c4 100644
--- a/solr/core/src/java/org/apache/solr/cloud/overseer/ClusterStateMutator.java
+++ b/solr/core/src/java/org/apache/solr/cloud/overseer/ClusterStateMutator.java
@@ -127,7 +127,7 @@ public class ClusterStateMutator {
assert !collectionProps.containsKey(CollectionAdminParams.COLL_CONF);
DocCollection newCollection =
- new DocCollection(
+ DocCollection.create(
cName, slices, collectionProps, router, -1,
stateManager.getPrsSupplier(cName));
return new ZkWriteCommand(cName, newCollection);
diff --git
a/solr/core/src/java/org/apache/solr/cloud/overseer/CollectionMutator.java
b/solr/core/src/java/org/apache/solr/cloud/overseer/CollectionMutator.java
index 492fe9efeb5..028beb37dfd 100644
--- a/solr/core/src/java/org/apache/solr/cloud/overseer/CollectionMutator.java
+++ b/solr/core/src/java/org/apache/solr/cloud/overseer/CollectionMutator.java
@@ -171,7 +171,7 @@ public class CollectionMutator {
}
DocCollection collection =
- new DocCollection(
+ DocCollection.create(
coll.getName(),
coll.getSlicesMap(),
props,
diff --git
a/solr/core/src/java/org/apache/solr/cloud/overseer/ZkStateWriter.java
b/solr/core/src/java/org/apache/solr/cloud/overseer/ZkStateWriter.java
index 9e457f53f89..e38e58b3798 100644
--- a/solr/core/src/java/org/apache/solr/cloud/overseer/ZkStateWriter.java
+++ b/solr/core/src/java/org/apache/solr/cloud/overseer/ZkStateWriter.java
@@ -268,10 +268,11 @@ public class ZkStateWriter {
// Update the Per Replica State znodes if needed
if (cmd.ops != null) {
cmd.ops.persist(path, reader.getZkClient());
+
clusterState =
clusterState.copyWith(
name,
- cmd.collection.copyWith(
+ cmd.collection.setPerReplicaStates(
PerReplicaStatesFetcher.fetch(
cmd.collection.getZNode(), reader.getZkClient(),
null)));
}
@@ -295,25 +296,25 @@ public class ZkStateWriter {
}
Stat stat = reader.getZkClient().setData(path, data,
c.getZNodeVersion(), true);
DocCollection newCollection =
- new DocCollection(
+ DocCollection.create(
name,
c.getSlicesMap(),
c.getProperties(),
c.getRouter(),
stat.getVersion(),
- new
PerReplicaStatesFetcher.LazyPrsSupplier(reader.getZkClient(), path));
+
PerReplicaStatesFetcher.getZkClientPrsSupplier(reader.getZkClient(), path));
clusterState = clusterState.copyWith(name, newCollection);
} else {
log.debug("going to create_collection {}", path);
reader.getZkClient().create(path, data, CreateMode.PERSISTENT,
true);
DocCollection newCollection =
- new DocCollection(
+ DocCollection.create(
name,
c.getSlicesMap(),
c.getProperties(),
c.getRouter(),
0,
- new
PerReplicaStatesFetcher.LazyPrsSupplier(reader.getZkClient(), path));
+
PerReplicaStatesFetcher.getZkClientPrsSupplier(reader.getZkClient(), path));
clusterState = clusterState.copyWith(name, newCollection);
}
}
@@ -324,7 +325,7 @@ public class ZkStateWriter {
clusterState =
clusterState.copyWith(
name,
- currentCollState.copyWith(
+ currentCollState.setPerReplicaStates(
PerReplicaStatesFetcher.fetch(
currentCollState.getZNode(),
reader.getZkClient(), null)));
}
diff --git a/solr/core/src/test/org/apache/solr/cloud/ClusterStateTest.java
b/solr/core/src/test/org/apache/solr/cloud/ClusterStateTest.java
index 28ffd0bd564..ac9b5ffa856 100644
--- a/solr/core/src/test/org/apache/solr/cloud/ClusterStateTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/ClusterStateTest.java
@@ -59,9 +59,11 @@ public class ClusterStateTest extends SolrTestCaseJ4 {
Slice slice2 = new Slice("shard2", sliceToProps, null, "collection1");
slices.put("shard2", slice2);
collectionStates.put(
- "collection1", new DocCollection("collection1", slices, props,
DocRouter.DEFAULT, 0, null));
+ "collection1",
+ DocCollection.create("collection1", slices, props, DocRouter.DEFAULT,
0, null));
collectionStates.put(
- "collection2", new DocCollection("collection2", slices, props,
DocRouter.DEFAULT, 0, null));
+ "collection2",
+ DocCollection.create("collection2", slices, props, DocRouter.DEFAULT,
0, null));
ClusterState clusterState = new ClusterState(liveNodes, collectionStates);
assertFalse(clusterState.getCollection("collection1").getProperties().containsKey("shards"));
diff --git
a/solr/core/src/test/org/apache/solr/cloud/OverseerCollectionConfigSetProcessorTest.java
b/solr/core/src/test/org/apache/solr/cloud/OverseerCollectionConfigSetProcessorTest.java
index 9f5a2f26e8e..ac3df8b4373 100644
---
a/solr/core/src/test/org/apache/solr/cloud/OverseerCollectionConfigSetProcessorTest.java
+++
b/solr/core/src/test/org/apache/solr/cloud/OverseerCollectionConfigSetProcessorTest.java
@@ -685,7 +685,7 @@ public class OverseerCollectionConfigSetProcessorTest
extends SolrTestCaseJ4 {
collectionsSet.put(
collName,
new ClusterState.CollectionRef(
- new DocCollection(
+ DocCollection.create(
collName,
new HashMap<>(),
props.getProperties(),
diff --git
a/solr/core/src/test/org/apache/solr/cloud/overseer/ZkStateReaderTest.java
b/solr/core/src/test/org/apache/solr/cloud/overseer/ZkStateReaderTest.java
index b2b98fa1ea4..52671ed003b 100644
--- a/solr/core/src/test/org/apache/solr/cloud/overseer/ZkStateReaderTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/overseer/ZkStateReaderTest.java
@@ -138,13 +138,13 @@ public class ZkStateReaderTest extends SolrTestCaseJ4 {
ZkWriteCommand c1 =
new ZkWriteCommand(
"c1",
- new DocCollection(
+ DocCollection.create(
"c1",
new HashMap<>(),
Map.of(ZkStateReader.CONFIGNAME_PROP,
ConfigSetsHandler.DEFAULT_CONFIGSET_NAME),
DocRouter.DEFAULT,
0,
- new PerReplicaStatesFetcher.LazyPrsSupplier(
+ PerReplicaStatesFetcher.getZkClientPrsSupplier(
fixture.zkClient, DocCollection.getCollectionPath("c1"))));
writer.enqueueUpdate(reader.getClusterState(),
Collections.singletonList(c1), null);
@@ -165,13 +165,13 @@ public class ZkStateReaderTest extends SolrTestCaseJ4 {
fixture.zkClient.makePath(ZkStateReader.COLLECTIONS_ZKNODE + "/c1", true);
DocCollection state =
- new DocCollection(
+ DocCollection.create(
"c1",
new HashMap<>(),
Map.of(ZkStateReader.CONFIGNAME_PROP,
ConfigSetsHandler.DEFAULT_CONFIGSET_NAME),
DocRouter.DEFAULT,
0,
- new PerReplicaStatesFetcher.LazyPrsSupplier(
+ PerReplicaStatesFetcher.getZkClientPrsSupplier(
fixture.zkClient, DocCollection.getCollectionPath("c1")));
ZkWriteCommand wc = new ZkWriteCommand("c1", state);
writer.enqueueUpdate(reader.getClusterState(),
Collections.singletonList(wc), null);
@@ -184,13 +184,13 @@ public class ZkStateReaderTest extends SolrTestCaseJ4 {
props.put("x", "y");
props.put(ZkStateReader.CONFIGNAME_PROP,
ConfigSetsHandler.DEFAULT_CONFIGSET_NAME);
state =
- new DocCollection(
+ DocCollection.create(
"c1",
new HashMap<>(),
props,
DocRouter.DEFAULT,
0,
- new PerReplicaStatesFetcher.LazyPrsSupplier(
+ PerReplicaStatesFetcher.getZkClientPrsSupplier(
fixture.zkClient, DocCollection.getCollectionPath("c1")));
wc = new ZkWriteCommand("c1", state);
writer.enqueueUpdate(reader.getClusterState(),
Collections.singletonList(wc), null);
@@ -225,13 +225,13 @@ public class ZkStateReaderTest extends SolrTestCaseJ4 {
// create new collection
DocCollection state =
- new DocCollection(
+ DocCollection.create(
"c1",
new HashMap<>(),
Map.of(ZkStateReader.CONFIGNAME_PROP,
ConfigSetsHandler.DEFAULT_CONFIGSET_NAME),
DocRouter.DEFAULT,
0,
- new PerReplicaStatesFetcher.LazyPrsSupplier(
+ PerReplicaStatesFetcher.getZkClientPrsSupplier(
fixture.zkClient, DocCollection.getCollectionPath("c1")));
ZkWriteCommand wc = new ZkWriteCommand("c1", state);
writer.enqueueUpdate(reader.getClusterState(),
Collections.singletonList(wc), null);
@@ -259,7 +259,7 @@ public class ZkStateReaderTest extends SolrTestCaseJ4 {
ClusterState clusterState = reader.getClusterState();
// create new collection
DocCollection state =
- new DocCollection(
+ DocCollection.create(
"c1",
new HashMap<>(),
Map.of(
@@ -269,7 +269,7 @@ public class ZkStateReaderTest extends SolrTestCaseJ4 {
"true"),
DocRouter.DEFAULT,
0,
- new PerReplicaStatesFetcher.LazyPrsSupplier(
+ PerReplicaStatesFetcher.getZkClientPrsSupplier(
fixture.zkClient, DocCollection.getCollectionPath("c1")));
ZkWriteCommand wc = new ZkWriteCommand("c1", state);
writer.enqueueUpdate(clusterState, Collections.singletonList(wc), null);
@@ -383,13 +383,13 @@ public class ZkStateReaderTest extends SolrTestCaseJ4 {
// create new collection
DocCollection state =
- new DocCollection(
+ DocCollection.create(
"c1",
new HashMap<>(),
Map.of(ZkStateReader.CONFIGNAME_PROP,
ConfigSetsHandler.DEFAULT_CONFIGSET_NAME),
DocRouter.DEFAULT,
0,
- new PerReplicaStatesFetcher.LazyPrsSupplier(
+ PerReplicaStatesFetcher.getZkClientPrsSupplier(
fixture.zkClient, DocCollection.getCollectionPath("c1")));
ZkWriteCommand wc = new ZkWriteCommand("c1", state);
writer.enqueueUpdate(reader.getClusterState(),
Collections.singletonList(wc), null);
@@ -405,13 +405,13 @@ public class ZkStateReaderTest extends SolrTestCaseJ4 {
// update the collection
state =
- new DocCollection(
+ DocCollection.create(
"c1",
new HashMap<>(),
Map.of(ZkStateReader.CONFIGNAME_PROP,
ConfigSetsHandler.DEFAULT_CONFIGSET_NAME),
DocRouter.DEFAULT,
ref.get().getZNodeVersion(),
- new PerReplicaStatesFetcher.LazyPrsSupplier(
+ PerReplicaStatesFetcher.getZkClientPrsSupplier(
fixture.zkClient, DocCollection.getCollectionPath("c1")));
wc = new ZkWriteCommand("c1", state);
writer.enqueueUpdate(reader.getClusterState(),
Collections.singletonList(wc), null);
@@ -428,13 +428,13 @@ public class ZkStateReaderTest extends SolrTestCaseJ4 {
fixture.zkClient.makePath(ZkStateReader.COLLECTIONS_ZKNODE + "/c2", true);
state =
- new DocCollection(
+ DocCollection.create(
"c2",
new HashMap<>(),
Map.of(ZkStateReader.CONFIGNAME_PROP,
ConfigSetsHandler.DEFAULT_CONFIGSET_NAME),
DocRouter.DEFAULT,
0,
- new PerReplicaStatesFetcher.LazyPrsSupplier(
+ PerReplicaStatesFetcher.getZkClientPrsSupplier(
fixture.zkClient, DocCollection.getCollectionPath("c2")));
ZkWriteCommand wc2 = new ZkWriteCommand("c2", state);
@@ -544,23 +544,23 @@ public class ZkStateReaderTest extends SolrTestCaseJ4 {
// now create both c1 (watched) and c2 (not watched)
DocCollection state1 =
- new DocCollection(
+ DocCollection.create(
"c1",
new HashMap<>(),
Map.of(ZkStateReader.CONFIGNAME_PROP,
ConfigSetsHandler.DEFAULT_CONFIGSET_NAME),
DocRouter.DEFAULT,
0,
- new PerReplicaStatesFetcher.LazyPrsSupplier(
+ PerReplicaStatesFetcher.getZkClientPrsSupplier(
fixture.zkClient, DocCollection.getCollectionPath("c1")));
ZkWriteCommand wc1 = new ZkWriteCommand("c1", state1);
DocCollection state2 =
- new DocCollection(
+ DocCollection.create(
"c2",
new HashMap<>(),
Map.of(ZkStateReader.CONFIGNAME_PROP,
ConfigSetsHandler.DEFAULT_CONFIGSET_NAME),
DocRouter.DEFAULT,
0,
- new PerReplicaStatesFetcher.LazyPrsSupplier(
+ PerReplicaStatesFetcher.getZkClientPrsSupplier(
fixture.zkClient, DocCollection.getCollectionPath("c1")));
// do not listen to c2
@@ -607,7 +607,7 @@ public class ZkStateReaderTest extends SolrTestCaseJ4 {
int currentVersion = collection != null ?
collection.getZNodeVersion() : 0;
// create new collection
DocCollection state =
- new DocCollection(
+ DocCollection.create(
"c1",
new HashMap<>(),
Map.of(
@@ -615,7 +615,7 @@ public class ZkStateReaderTest extends SolrTestCaseJ4 {
ConfigSetsHandler.DEFAULT_CONFIGSET_NAME),
DocRouter.DEFAULT,
currentVersion,
- new PerReplicaStatesFetcher.LazyPrsSupplier(
+ PerReplicaStatesFetcher.getZkClientPrsSupplier(
fixture.zkClient,
DocCollection.getCollectionPath("c1")));
ZkWriteCommand wc = new ZkWriteCommand("c1", state);
writer.enqueueUpdate(clusterState,
Collections.singletonList(wc), null);
diff --git
a/solr/core/src/test/org/apache/solr/cloud/overseer/ZkStateWriterTest.java
b/solr/core/src/test/org/apache/solr/cloud/overseer/ZkStateWriterTest.java
index 12d5f9eaa02..d99097d8573 100644
--- a/solr/core/src/test/org/apache/solr/cloud/overseer/ZkStateWriterTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/overseer/ZkStateWriterTest.java
@@ -178,13 +178,13 @@ public class ZkStateWriterTest extends SolrTestCaseJ4 {
ZkWriteCommand prs1 =
new ZkWriteCommand(
"prs1",
- new DocCollection(
+ DocCollection.create(
"prs1",
new HashMap<>(),
prsProps,
DocRouter.DEFAULT,
0,
- new PerReplicaStatesFetcher.LazyPrsSupplier(
+ PerReplicaStatesFetcher.getZkClientPrsSupplier(
zkClient, DocCollection.getCollectionPath("c1"))));
ZkStateWriter writer =
new ZkStateWriter(reader, new Stats(), -1,
STATE_COMPRESSION_PROVIDER);
@@ -247,30 +247,30 @@ public class ZkStateWriterTest extends SolrTestCaseJ4 {
ZkWriteCommand c1 =
new ZkWriteCommand(
"c1",
- new DocCollection(
+ DocCollection.create(
"c1", new HashMap<>(), new HashMap<>(), DocRouter.DEFAULT,
0, null));
ZkWriteCommand c2 =
new ZkWriteCommand(
"c2",
- new DocCollection(
+ DocCollection.create(
"c2", new HashMap<>(), new HashMap<>(), DocRouter.DEFAULT,
0, null));
ZkWriteCommand c3 =
new ZkWriteCommand(
"c3",
- new DocCollection(
+ DocCollection.create(
"c3", new HashMap<>(), new HashMap<>(), DocRouter.DEFAULT,
0, null));
Map<String, Object> prsProps = new HashMap<>();
prsProps.put("perReplicaState", Boolean.TRUE);
ZkWriteCommand prs1 =
new ZkWriteCommand(
"prs1",
- new DocCollection(
+ DocCollection.create(
"prs1",
new HashMap<>(),
prsProps,
DocRouter.DEFAULT,
0,
- new PerReplicaStatesFetcher.LazyPrsSupplier(
+ PerReplicaStatesFetcher.getZkClientPrsSupplier(
zkClient, DocCollection.getCollectionPath("prs1"))));
ZkStateWriter writer =
new ZkStateWriter(reader, new Stats(), -1,
STATE_COMPRESSION_PROVIDER);
diff --git
a/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/cloud/DistribStateManager.java
b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/cloud/DistribStateManager.java
index 9374230ac2b..3ec636de1a8 100644
---
a/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/cloud/DistribStateManager.java
+++
b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/cloud/DistribStateManager.java
@@ -125,14 +125,13 @@ public interface DistribStateManager extends
SolrCloseable {
}
default DocCollection.PrsSupplier getPrsSupplier(String collName) {
- return new DocCollection.PrsSupplier(
- () -> {
- try {
- return getReplicaStates(DocCollection.getCollectionPath(collName));
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- });
+ return () -> {
+ try {
+ return getReplicaStates(DocCollection.getCollectionPath(collName));
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ };
}
/**
diff --git
a/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/ZkClientClusterStateProvider.java
b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/ZkClientClusterStateProvider.java
index 98c89b1ee0d..d6005da2a3f 100644
---
a/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/ZkClientClusterStateProvider.java
+++
b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/ZkClientClusterStateProvider.java
@@ -118,7 +118,7 @@ public class ZkClientClusterStateProvider implements
ClusterStateProvider {
version,
stateMap,
liveNodes,
- new PerReplicaStatesFetcher.LazyPrsSupplier(
+ PerReplicaStatesFetcher.getZkClientPrsSupplier(
zkClient, DocCollection.getCollectionPath(coll)));
}
diff --git
a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/PerReplicaStatesFetcher.java
b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/PerReplicaStatesFetcher.java
index c8baa8b4f07..1de41b93b93 100644
---
a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/PerReplicaStatesFetcher.java
+++
b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/PerReplicaStatesFetcher.java
@@ -55,9 +55,8 @@ public class PerReplicaStatesFetcher {
}
}
- public static class LazyPrsSupplier extends DocCollection.PrsSupplier {
- public LazyPrsSupplier(SolrZkClient zkClient, String collectionPath) {
- super(() -> PerReplicaStatesFetcher.fetch(collectionPath, zkClient,
null));
- }
+ public static DocCollection.PrsSupplier getZkClientPrsSupplier(
+ SolrZkClient zkClient, String collectionPath) {
+ return () -> PerReplicaStatesFetcher.fetch(collectionPath, zkClient, null);
}
}
diff --git
a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkStateReader.java
b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkStateReader.java
index 822d713096f..0074ab74762 100644
---
a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkStateReader.java
+++
b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkStateReader.java
@@ -1395,7 +1395,9 @@ public class ZkStateReader implements SolrCloseable {
new PerReplicaStates(collectionPath, stat.getCversion(),
replicaStates);
DocCollection oldState = collectionWatches.getDocCollection(coll);
final DocCollection newState =
- oldState != null ? oldState.copyWith(newStates) :
fetchCollectionState(coll, null);
+ oldState != null
+ ? oldState.setPerReplicaStates(newStates)
+ : fetchCollectionState(coll, null);
collectionWatches.updateDocCollection(coll, newState);
synchronized (getUpdateLock()) {
constructState(Collections.singleton(coll));
diff --git
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/BaseHttpClusterStateProvider.java
b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/BaseHttpClusterStateProvider.java
index 2c6e2e9134a..375b3c38742 100644
---
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/BaseHttpClusterStateProvider.java
+++
b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/BaseHttpClusterStateProvider.java
@@ -172,13 +172,13 @@ public abstract class BaseHttpClusterStateProvider
implements ClusterStateProvid
if (m.containsKey("PRS")) {
Map prs = (Map) m.remove("PRS");
prsSupplier =
- new DocCollection.PrsSupplier(
- () ->
- new PerReplicaStates(
- (String) prs.get("path"),
- (Integer) prs.get("cversion"),
- (List<String>) prs.get("states")));
+ () ->
+ new PerReplicaStates(
+ (String) prs.get("path"),
+ (Integer) prs.get("cversion"),
+ (List<String>) prs.get("states"));
}
+
return ClusterState.collectionFromObjects(e.getKey(), m, znodeVersion,
prsSupplier);
}
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java
b/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java
index 784acecd2ab..6d74dd49015 100644
--- a/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java
+++ b/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java
@@ -302,7 +302,7 @@ public class ClusterState implements JSONWriter.Writable {
router = DocRouter.getDocRouter((String) routerProps.get("name"));
}
- return new DocCollection(name, slices, props, router, version,
prsSupplier);
+ return DocCollection.create(name, slices, props, router, version,
prsSupplier);
}
@Override
diff --git
a/solr/solrj/src/java/org/apache/solr/common/cloud/DocCollection.java
b/solr/solrj/src/java/org/apache/solr/common/cloud/DocCollection.java
index 55068c70aac..40b41ba2171 100644
--- a/solr/solrj/src/java/org/apache/solr/common/cloud/DocCollection.java
+++ b/solr/solrj/src/java/org/apache/solr/common/cloud/DocCollection.java
@@ -29,6 +29,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiConsumer;
import java.util.function.BiPredicate;
import java.util.function.Supplier;
@@ -65,14 +66,20 @@ public class DocCollection extends ZkNodeProps implements
Iterable<Slice> {
private final Boolean readOnly;
private final Boolean perReplicaState;
private final Map<String, Replica> replicaMap = new HashMap<>();
- private PrsSupplier prsSupplier;
+ private AtomicReference<PerReplicaStates> perReplicaStatesRef;
+ /**
+ * @see DocCollection#create(String, Map, Map, DocRouter, int, PrsSupplier)
+ */
@Deprecated
public DocCollection(
String name, Map<String, Slice> slices, Map<String, Object> props,
DocRouter router) {
this(name, slices, props, router, Integer.MAX_VALUE, null);
}
+ /**
+ * @see DocCollection#create(String, Map, Map, DocRouter, int, PrsSupplier)
+ */
@Deprecated
public DocCollection(
String name,
@@ -89,14 +96,15 @@ public class DocCollection extends ZkNodeProps implements
Iterable<Slice> {
* @param props The properties of the slice. This is used directly and a
copy is not made.
* @param zkVersion The version of the Collection node in Zookeeper (used
for conditional
* updates).
+ * @see DocCollection#create(String, Map, Map, DocRouter, int, PrsSupplier)
*/
- public DocCollection(
+ private DocCollection(
String name,
Map<String, Slice> slices,
Map<String, Object> props,
DocRouter router,
int zkVersion,
- PrsSupplier prsSupplier) {
+ AtomicReference<PerReplicaStates> perReplicaStatesRef) {
super(props);
// -1 means any version in ZK CAS, so we choose Integer.MAX_VALUE instead
to avoid accidental
// overwrites
@@ -114,14 +122,14 @@ public class DocCollection extends ZkNodeProps implements
Iterable<Slice> {
this.perReplicaState =
(Boolean) verifyProp(props, CollectionStateProps.PER_REPLICA_STATE,
Boolean.FALSE);
if (this.perReplicaState) {
- if (prsSupplier == null) {
+ if (perReplicaStatesRef == null || perReplicaStatesRef.get() == null) {
throw new RuntimeException(
CollectionStateProps.PER_REPLICA_STATE
- + " = true , but per-replica state supplier is not provided");
+ + " = true , but perReplicatStates param is not provided");
}
- this.prsSupplier = prsSupplier;
- for (Slice s : this.slices.values()) {
- s.setPrsSupplier(prsSupplier);
+ this.perReplicaStatesRef = perReplicaStatesRef;
+ for (Slice s : this.slices.values()) { // set the same reference to all
slices too
+ s.setPerReplicaStatesRef(this.perReplicaStatesRef);
}
}
Boolean readOnly = (Boolean) verifyProp(props,
CollectionStateProps.READ_ONLY);
@@ -147,6 +155,64 @@ public class DocCollection extends ZkNodeProps implements
Iterable<Slice> {
assert name != null && slices != null;
}
+ /**
+ * Builds a DocCollection with an optional PrsSupplier
+ *
+ * @param name The name of the collection
+ * @param slices The logical shards of the collection. This is used directly
and a copy is not
+ * made.
+ * @param props The properties of the slice. This is used directly and a
copy is not made.
+ * @param router router to partition int range into n ranges
+ * @param zkVersion The version of the Collection node in Zookeeper (used
for conditional
+ * updates).
+ * @param prsSupplier optional supplier for PerReplicaStates (PRS) for PRS
enabled collections
+ * @return a newly constructed DocCollection
+ */
+ public static DocCollection create(
+ String name,
+ Map<String, Slice> slices,
+ Map<String, Object> props,
+ DocRouter router,
+ int zkVersion,
+ DocCollection.PrsSupplier prsSupplier) {
+ boolean perReplicaState =
+ (Boolean) verifyProp(props, CollectionStateProps.PER_REPLICA_STATE,
Boolean.FALSE);
+ PerReplicaStates perReplicaStates;
+ if (perReplicaState) {
+ if (prsSupplier == null) {
+ throw new IllegalArgumentException(
+ CollectionStateProps.PER_REPLICA_STATE + " = true , but prsSuppler
is not provided");
+ }
+
+ if (!hasAnyReplica(
+ slices)) { // a special case, if there is no replica, it should not
fetch (first PRS
+ // collection creation with no replicas). Otherwise, it would trigger
exception
+ // on fetching a state.json that does not exist yet
+ perReplicaStates = PerReplicaStates.empty(name);
+ } else {
+ perReplicaStates = prsSupplier.get();
+ }
+ } else {
+ perReplicaStates = null;
+ }
+ return new DocCollection(
+ name,
+ slices,
+ props,
+ router,
+ zkVersion,
+ perReplicaStates != null ? new AtomicReference<>(perReplicaStates) :
null);
+ }
+
+ private static boolean hasAnyReplica(Map<String, Slice> slices) {
+ for (Slice slice : slices.values()) {
+ if (!slice.getReplicasMap().isEmpty()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public static String getCollectionPath(String coll) {
return getCollectionPathRoot(coll) + "/state.json";
}
@@ -156,14 +222,20 @@ public class DocCollection extends ZkNodeProps implements
Iterable<Slice> {
}
/**
- * Update our state with a state of a {@link Replica} Used to create a new
Collection State when
- * only a replica is updated
+ * Update our state with a state of a {@link PerReplicaStates} which could
override states of
+ * {@link Replica}.
+ *
+ * <p>Take note that it updates the underlying AtomicReference such that all
Slice and Replica
+ * that holds the same AtomicReference will see the same update
+ *
+ * <p>This does not create a new DocCollection.
*/
- public DocCollection copyWith(PerReplicaStates newPerReplicaStates) {
- if (this.prsSupplier != null) {
+ public final DocCollection setPerReplicaStates(PerReplicaStates
newPerReplicaStates) {
+ if (this.perReplicaStatesRef != null) {
log.debug("In-place update of PRS: {}", newPerReplicaStates);
- this.prsSupplier.prs = newPerReplicaStates;
+ this.perReplicaStatesRef.set(newPerReplicaStates);
}
+
return this;
}
@@ -216,7 +288,7 @@ public class DocCollection extends ZkNodeProps implements
Iterable<Slice> {
*/
public DocCollection copyWithSlices(Map<String, Slice> slices) {
DocCollection result =
- new DocCollection(getName(), slices, propMap, router, znodeVersion,
prsSupplier);
+ new DocCollection(getName(), slices, propMap, router, znodeVersion,
perReplicaStatesRef);
return result;
}
/** Return collection name. */
@@ -283,8 +355,7 @@ public class DocCollection extends ZkNodeProps implements
Iterable<Slice> {
}
public int getChildNodesVersion() {
- PerReplicaStates prs = prsSupplier == null ? null : prsSupplier.get();
- return prs == null ? 0 : prs.cversion;
+ return perReplicaStatesRef == null ? 0 :
perReplicaStatesRef.get().cversion;
}
public boolean isModified(int dataVersion, int childVersion) {
@@ -321,7 +392,7 @@ public class DocCollection extends ZkNodeProps implements
Iterable<Slice> {
+ "/"
+ znodeVersion
+ " "
- + (prsSupplier == null ? "" : prsSupplier.get())
+ + (perReplicaStatesRef == null ? "" : perReplicaStatesRef.get())
+ ")="
+ toJSONString(this);
}
@@ -468,11 +539,7 @@ public class DocCollection extends ZkNodeProps implements
Iterable<Slice> {
}
public PerReplicaStates getPerReplicaStates() {
- return prsSupplier != null ? prsSupplier.get() : null;
- }
-
- public PrsSupplier getPrsSupplier() {
- return prsSupplier;
+ return perReplicaStatesRef != null ? perReplicaStatesRef.get() : null;
}
public int getExpectedReplicaCount(Replica.Type type, int def) {
@@ -496,26 +563,5 @@ public class DocCollection extends ZkNodeProps implements
Iterable<Slice> {
String PER_REPLICA_STATE = "perReplicaState";
}
- public static class PrsSupplier implements Supplier<PerReplicaStates> {
-
- private volatile PerReplicaStates prs;
-
- private Supplier<PerReplicaStates> supplier;
-
- public PrsSupplier(Supplier<PerReplicaStates> supplier) {
- this.supplier = supplier;
- }
-
- public PrsSupplier(PerReplicaStates prs) {
- this.prs = prs;
- }
-
- @Override
- public PerReplicaStates get() {
- if (prs == null) {
- prs = supplier.get();
- }
- return prs;
- }
- }
+ public interface PrsSupplier extends Supplier<PerReplicaStates> {}
}
diff --git
a/solr/solrj/src/java/org/apache/solr/common/cloud/PerReplicaStates.java
b/solr/solrj/src/java/org/apache/solr/common/cloud/PerReplicaStates.java
index 698da842845..60616d8fd70 100644
--- a/solr/solrj/src/java/org/apache/solr/common/cloud/PerReplicaStates.java
+++ b/solr/solrj/src/java/org/apache/solr/common/cloud/PerReplicaStates.java
@@ -88,6 +88,10 @@ public class PerReplicaStates implements ReflectMapWriter {
this.states = new WrappedSimpleMap<>(tmp);
}
+ public static PerReplicaStates empty(String collectionName) {
+ return new
PerReplicaStates(DocCollection.getCollectionPath(collectionName), 0, List.of());
+ }
+
/** Check and return if all replicas are ACTIVE */
public boolean allActive() {
if (this.allActive != null) return allActive;
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/Replica.java
b/solr/solrj/src/java/org/apache/solr/common/cloud/Replica.java
index 067bd408c03..b54e29f4d6e 100644
--- a/solr/solrj/src/java/org/apache/solr/common/cloud/Replica.java
+++ b/solr/solrj/src/java/org/apache/solr/common/cloud/Replica.java
@@ -24,6 +24,7 @@ import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
import org.apache.solr.common.MapWriter;
import org.apache.solr.common.util.Utils;
import org.noggit.JSONWriter;
@@ -145,13 +146,13 @@ public class Replica extends ZkNodeProps implements
MapWriter {
public final String core;
public final Type type;
public final String shard, collection;
- private DocCollection.PrsSupplier prsSupplier;
+ private AtomicReference<PerReplicaStates> perReplicaStatesRef;
// mutable
private State state;
- void setPrsSupplier(DocCollection.PrsSupplier prsSupplier) {
- this.prsSupplier = prsSupplier;
+ void setPerReplicaStatesRef(AtomicReference<PerReplicaStates>
perReplicaStatesRef) {
+ this.perReplicaStatesRef = perReplicaStatesRef;
}
public Replica(String name, Map<String, Object> map, String collection,
String shard) {
@@ -293,8 +294,8 @@ public class Replica extends ZkNodeProps implements
MapWriter {
/** Returns the {@link State} of this replica. */
public State getState() {
- if (prsSupplier != null) {
- PerReplicaStates.State s = prsSupplier.get().get(name);
+ if (perReplicaStatesRef != null) {
+ PerReplicaStates.State s = perReplicaStatesRef.get().get(name);
if (s != null) {
return s.state;
} else {
@@ -318,8 +319,8 @@ public class Replica extends ZkNodeProps implements
MapWriter {
}
public boolean isLeader() {
- if (prsSupplier != null) {
- PerReplicaStates.State st = prsSupplier.get().get(name);
+ if (perReplicaStatesRef != null) {
+ PerReplicaStates.State st = perReplicaStatesRef.get().get(name);
return st == null ? false : st.isLeader;
}
return getBool(ReplicaStateProps.LEADER, false);
@@ -360,8 +361,8 @@ public class Replica extends ZkNodeProps implements
MapWriter {
}
public PerReplicaStates.State getReplicaState() {
- if (prsSupplier != null) {
- return prsSupplier.get().get(name);
+ if (perReplicaStatesRef != null) {
+ return perReplicaStatesRef.get().get(name);
}
return null;
}
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/Slice.java
b/solr/solrj/src/java/org/apache/solr/common/cloud/Slice.java
index 197d10199cc..0007c679690 100644
--- a/solr/solrj/src/java/org/apache/solr/common/cloud/Slice.java
+++ b/solr/solrj/src/java/org/apache/solr/common/cloud/Slice.java
@@ -29,6 +29,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import org.apache.solr.common.cloud.Replica.Type;
@@ -46,12 +47,12 @@ public class Slice extends ZkNodeProps implements
Iterable<Replica> {
public final String collection;
- private DocCollection.PrsSupplier prsSupplier;
+ private AtomicReference<PerReplicaStates> perReplicaStatesRef;
- void setPrsSupplier(DocCollection.PrsSupplier prsSupplier) {
- this.prsSupplier = prsSupplier;
+ void setPerReplicaStatesRef(AtomicReference<PerReplicaStates>
perReplicaStatesRef) {
+ this.perReplicaStatesRef = perReplicaStatesRef;
for (Replica r : replicas.values()) {
- r.setPrsSupplier(prsSupplier);
+ r.setPerReplicaStatesRef(perReplicaStatesRef);
}
if (leader == null) {
leader = findLeader();
@@ -286,7 +287,7 @@ public class Slice extends ZkNodeProps implements
Iterable<Replica> {
}
public Replica getLeader() {
- if (prsSupplier != null) {
+ if (perReplicaStatesRef != null) {
// this is a PRS collection. leader may keep changing
return findLeader();
} else {