bdeggleston commented on code in PR #4708:
URL: https://github.com/apache/cassandra/pull/4708#discussion_r3443833004


##########
src/java/org/apache/cassandra/locator/AbstractReplicationStrategy.java:
##########
@@ -437,4 +461,376 @@ public RangesAtEndpoint getLocalRanges(ClusterMetadata cm)
                 return newRanges;
         }
     }
+
+    protected CoordinationPlan.ForWrite planForWriteInternal(ClusterMetadata 
metadata,
+                                                                          
Keyspace keyspace,
+                                                                          
ConsistencyLevel consistencyLevel,
+                                                                          
Function<ClusterMetadata, ReplicaLayout.ForTokenWrite> liveAndDown,
+                                                                          
ReplicaPlans.Selector selector)
+    {
+        ReplicaPlan.ForWrite plan = ReplicaPlans.forWrite(metadata, keyspace, 
consistencyLevel, liveAndDown, selector);
+        ResponseTracker tracker = createTrackerForWrite(consistencyLevel, 
plan, plan.pending, metadata);
+        return new CoordinationPlan.ForWrite(plan, tracker);
+    }
+
+    public CoordinationPlan.ForWriteWithIdeal planForWrite(ClusterMetadata 
metadata,
+                                                           Keyspace keyspace,
+                                                           ConsistencyLevel 
consistencyLevel,
+                                                           
Function<ClusterMetadata, ReplicaLayout.ForTokenWrite> liveAndDown,
+                                                           
ReplicaPlans.Selector selector)
+    {
+        CoordinationPlan.ForWrite actual = planForWriteInternal(metadata, 
keyspace, consistencyLevel, liveAndDown, selector);
+
+        CoordinationPlan.ForWrite ideal = null;
+        ConsistencyLevel idealCL = 
DatabaseDescriptor.getIdealConsistencyLevel();
+        if (idealCL != null)
+        {
+            if (idealCL == consistencyLevel)
+            {
+                ideal = actual;
+            }
+            else
+            {
+                ideal = planForWriteInternal(metadata, keyspace, idealCL, 
liveAndDown, selector);
+            }
+        }
+
+        return new CoordinationPlan.ForWriteWithIdeal(metadata, 
actual.replicas(), actual.responses(), ideal);
+    }
+
+    public CoordinationPlan.ForWriteWithIdeal planForWrite(ClusterMetadata 
metadata,
+                                                           Keyspace keyspace,
+                                                           ConsistencyLevel 
consistencyLevel,
+                                                           Token token,
+                                                           
ReplicaPlans.Selector selector)
+    {
+        return planForWrite(metadata, keyspace, consistencyLevel,
+                            (newClusterMetadata) -> 
ReplicaLayout.forTokenWriteLiveAndDown(newClusterMetadata, keyspace, token), 
selector);
+    }
+
+    /**
+     * Create coordination plan for forwarding a counter write to the leader 
replica.
+     *
+     * In cases where the original coordinator is not a replica of the counter 
key, the counter
+     * mutation is forwarded to a leader replica that will coordinate the 
actual counter update.
+     */
+    public CoordinationPlan.ForWrite 
planForForwardingCounterWrite(ClusterMetadata metadata,
+                                                                   Keyspace 
keyspace,
+                                                                   Token token,
+                                                                   
Function<ClusterMetadata, Replica> replicaSupplier)
+    {
+        ReplicaPlan.ForWrite plan = 
ReplicaPlans.forSingleReplicaWrite(metadata, keyspace, token, replicaSupplier);
+        ResponseTracker tracker = 
createTrackerForWrite(plan.consistencyLevel(), plan, plan.pending, metadata);
+
+        return new CoordinationPlan.ForWriteWithIdeal(metadata, plan, tracker, 
null);
+    }
+
+    /**
+     * Create coordination plan for replaying a mutation from the batchlog.
+     *
+     * When recovering failed batches, mutations are replayed to remote 
replicas only
+     * (local replica is handled separately). This method creates a replica 
plan
+     * targeting live remote replicas with CL.ONE, and a response tracker that 
waits on
+     * all contacts
+     */
+    public CoordinationPlan.ForWriteWithIdeal 
planForReplayMutation(ClusterMetadata metadata,
+                                                                    Keyspace 
keyspace,
+                                                                    Token 
token)
+    {
+        Preconditions.checkState(!replicationType.isTracked(), "Batch replay 
not supported with tracked keyspaces");
+
+        ReplicaPlan.ForWrite plan = ReplicaPlans.forReplayMutation(metadata, 
keyspace, token);
+
+        // wait until all contacts respond
+        int blockFor = plan.contacts().size();
+        ResponseTracker tracker = new SimpleResponseTracker(blockFor, 
blockFor);
+
+        return new CoordinationPlan.ForWriteWithIdeal(metadata, plan, tracker, 
null);
+    }
+
+    /**
+     * Create coordination plan for a single-partition token read.
+     */
+    public CoordinationPlan.ForTokenRead planForTokenRead(ClusterMetadata 
metadata,
+                                                          Keyspace keyspace,
+                                                          TableId tableId,
+                                                          Token token,
+                                                          @Nullable 
Index.QueryPlan indexQueryPlan,
+                                                          ConsistencyLevel 
consistencyLevel,
+                                                          
SpeculativeRetryPolicy retry,
+                                                          ReadCoordinator 
coordinator)
+    {
+        ReplicaPlan.ForTokenRead plan = ReplicaPlans.forRead(metadata, 
keyspace, tableId, token, indexQueryPlan, consistencyLevel, retry, coordinator);
+        ReplicaPlan.SharedForTokenRead shared = ReplicaPlan.shared(plan);
+        ResponseTracker tracker = createTrackerForRead(plan);
+        return new CoordinationPlan.ForTokenRead(shared, tracker);
+    }
+
+    /**
+     * Create coordination plan for a range read.
+     */
+    public CoordinationPlan.ForRangeRead planForRangeRead(ClusterMetadata 
metadata,
+                                                          Keyspace keyspace,
+                                                          TableId tableId,
+                                                          @Nullable 
Index.QueryPlan indexQueryPlan,
+                                                          ConsistencyLevel 
consistencyLevel,
+                                                          
AbstractBounds<PartitionPosition> range,
+                                                          int vnodeCount)
+    {
+        ReplicaPlan.ForRangeRead plan = ReplicaPlans.forRangeRead(metadata, 
keyspace, tableId, indexQueryPlan, consistencyLevel, range, vnodeCount, true);
+        ReplicaPlan.SharedForRangeRead shared = ReplicaPlan.shared(plan);
+        ResponseTracker tracker = createTrackerForRead(plan);
+        return new CoordinationPlan.ForRangeRead(shared, tracker);
+    }
+
+    /**
+     * Attempt to merge two adjacent range read coordination plans into one.
+     *
+     * If the two plans share enough live endpoints to satisfy the consistency 
level
+     * and the merge is worthwhile returns a merged plan otherwise returns 
null.
+     */
+    public CoordinationPlan.ForRangeRead maybeMergeRangeReads(ClusterMetadata 
metadata,
+                                                               Keyspace 
keyspace,
+                                                               TableId tableId,
+                                                               
ConsistencyLevel consistencyLevel,
+                                                               
ReplicaPlan.ForRangeRead left,
+                                                               
ReplicaPlan.ForRangeRead right)
+    {
+        ReplicaPlan.ForRangeRead merged = ReplicaPlans.maybeMerge(metadata, 
keyspace, tableId, consistencyLevel, left, right);
+        if (merged == null)
+            return null;
+
+        ReplicaPlan.SharedForRangeRead shared = ReplicaPlan.shared(merged);
+        ResponseTracker tracker = createTrackerForRead(merged);
+        return new CoordinationPlan.ForRangeRead(shared, tracker);
+    }
+
+    /**
+     * Create coordination plan for a full range read
+     */
+    public CoordinationPlan.ForRangeRead planForFullRangeRead(Keyspace 
keyspace,
+                                                              ConsistencyLevel 
consistencyLevel,
+                                                              
AbstractBounds<PartitionPosition> range,
+                                                              
Set<InetAddressAndPort> endpointsToContact,
+                                                              int vnodeCount)
+    {
+        ReplicaPlan.ForRangeRead plan = 
ReplicaPlans.forFullRangeRead(keyspace, consistencyLevel, range, 
endpointsToContact, vnodeCount);
+        ReplicaPlan.SharedForRangeRead shared = ReplicaPlan.shared(plan);
+        ResponseTracker tracker = createTrackerForRead(plan);
+        return new CoordinationPlan.ForRangeRead(shared, tracker);
+    }
+
+    /**
+     * Create coordination plan for a single-replica token read.
+     */
+    public CoordinationPlan.ForTokenRead 
planForSingleReplicaTokenRead(Keyspace keyspace, Token token, Replica replica)
+    {
+        ReplicaPlan.ForTokenRead plan = 
ReplicaPlans.forSingleReplicaRead(keyspace, token, replica);
+        ReplicaPlan.SharedForTokenRead shared = ReplicaPlan.shared(plan);
+        ResponseTracker tracker = createTrackerForRead(plan);
+        return new CoordinationPlan.ForTokenRead(shared, tracker);
+    }
+
+    /**
+     * Create coordination plan for a single-replica range read.
+     *
+     * Used by short read protection to fetch additional partitions from a
+     * specific replica. blockFor=1, totalReplicas=1.
+     */
+    public CoordinationPlan.ForRangeRead 
planForSingleReplicaRangeRead(Keyspace keyspace,
+                                                                       
AbstractBounds<PartitionPosition> range,
+                                                                       Replica 
replica,
+                                                                       int 
vnodeCount)
+    {
+        ReplicaPlan.ForRangeRead plan = 
ReplicaPlans.forSingleReplicaRead(keyspace, range, replica, vnodeCount);
+        ReplicaPlan.SharedForRangeRead shared = ReplicaPlan.shared(plan);
+        ResponseTracker tracker = createTrackerForRead(plan);
+        return new CoordinationPlan.ForRangeRead(shared, tracker);
+    }
+
+    /**
+     * Create ResponseTracker for read operation.
+     */
+    public <E extends Endpoints<E>, P extends ReplicaPlan.ForRead<E, P>> 
ResponseTracker createTrackerForRead(P plan)
+    {
+        int blockFor = plan.readQuorum();
+
+        // Use candidates.size() for totalReplicas to allow for speculation
+        // (speculation can contact additional candidates beyond initial 
contacts)
+        int totalReplicas = plan.readCandidates().size();
+
+        return new SimpleResponseTracker(blockFor, totalReplicas);
+    }
+
+    public Paxos.Participants paxosParticipants(ClusterMetadata metadata,
+                                                TableMetadata table,
+                                                Token token,
+                                                ConsistencyLevel 
consistencyForConsensus,
+                                                Predicate<Replica> 
isReplicaAlive)
+    {
+
+        KeyspaceMetadata keyspaceMetadata = 
metadata.schema.getKeyspaceMetadata(table.keyspace);
+        // MetaStrategy distributes the entire keyspace to all replicas. In 
addition, its tables (currently only
+        // the dist log table) don't use the globally configured partitioner. 
For these reasons we don't lookup the
+        // replicas using the supplied token as this can actually be of the 
incorrect type (for example when
+        // performing Paxos repair).
+        final Token actualToken = table.partitioner == 
MetaStrategy.partitioner ? MetaStrategy.entireRange.right : token;
+        ReplicaLayout.ForTokenWrite all = 
forTokenWriteLiveAndDown(keyspaceMetadata, actualToken);

Review Comment:
   There's a few pieces of metadata flying around here. ClusterMetadata and 
TableMetadata are passed into the method as arguments. However we need 
KeyspaceMetadata to get the replica layout, and we get that from the combo of 
cluster and table metadata in the line at the top of them method, 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to