All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.cassandra.locator.Endpoints Maven / Gradle / Ivy

Go to download

The Apache Cassandra Project develops a highly scalable second-generation distributed database, bringing together Dynamo's fully distributed design and Bigtable's ColumnFamily-based data model.

There is a newer version: 5.0-rc1
Show newest version
/*
 * 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.cassandra.locator;

import org.apache.cassandra.locator.ReplicaCollection.Builder.Conflict;
import org.apache.cassandra.utils.FBUtilities;

import java.util.AbstractList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import com.google.common.collect.Lists;

/**
 * A collection of Endpoints for a given ring position.  This will typically reside in a ReplicaLayout,
 * representing some subset of the endpoints for the Token or Range
 * @param  The concrete type of Endpoints, that will be returned by the modifying methods
 */
public abstract class Endpoints> extends AbstractReplicaCollection
{
    static ReplicaMap endpointMap(ReplicaList list) { return new ReplicaMap<>(list, Replica::endpoint); }
    static final ReplicaMap EMPTY_MAP = endpointMap(EMPTY_LIST);

    // volatile not needed, as has only final members,
    // besides (transitively) those that cache objects that themselves have only final members
    ReplicaMap byEndpoint;

    Endpoints(ReplicaList list, ReplicaMap byEndpoint)
    {
        super(list);
        this.byEndpoint = byEndpoint;
    }

    @Override
    public Set endpoints()
    {
        return byEndpoint().keySet();
    }

    public List endpointList()
    {
        return new AbstractList()
        {
            public InetAddressAndPort get(int index)
            {
                return list.get(index).endpoint();
            }

            public int size()
            {
                return list.size;
            }
        };
    }

    public Map byEndpoint()
    {
        ReplicaMap map = byEndpoint;
        if (map == null)
            byEndpoint = map = endpointMap(list);
        return map;
    }

    @Override
    public boolean contains(Replica replica)
    {
        return replica != null
                && Objects.equals(
                        byEndpoint().get(replica.endpoint()),
                        replica);
    }

    public E withoutSelf()
    {
        InetAddressAndPort self = FBUtilities.getBroadcastAddressAndPort();
        return filter(r -> !self.equals(r.endpoint()));
    }

    public Replica selfIfPresent()
    {
        InetAddressAndPort self = FBUtilities.getBroadcastAddressAndPort();
        return byEndpoint().get(self);
    }

    /**
     * @return a collection without the provided endpoints, otherwise in the same order as this collection
     */
    public E without(Set remove)
    {
        return filter(r -> !remove.contains(r.endpoint()));
    }

    /**
     * @return a collection with only the provided endpoints (ignoring any not present), otherwise in the same order as this collection
     */
    public E keep(Set keep)
    {
        return filter(r -> keep.contains(r.endpoint()));
    }

    /**
     * @return a collection containing the Replica from this collection for the provided endpoints, in the order of the provided endpoints
     */
    public E select(Iterable endpoints, boolean ignoreMissing)
    {
        Builder copy = newBuilder(
                endpoints instanceof Collection
                        ? ((Collection) endpoints).size()
                        : size()
        );
        Map byEndpoint = byEndpoint();
        for (InetAddressAndPort endpoint : endpoints)
        {
            Replica select = byEndpoint.get(endpoint);
            if (select == null)
            {
                if (!ignoreMissing)
                    throw new IllegalArgumentException(endpoint + " is not present in " + this);
                continue;
            }
            copy.add(select, Builder.Conflict.DUPLICATE);
        }
        return copy.build();
    }

    /**
     * Care must be taken to ensure no conflicting ranges occur in pending and natural.
     * Conflicts can occur for two reasons:
     *   1) due to lack of isolation when reading pending/natural
     *   2) because a movement that changes the type of replication from transient to full must be handled
     *      differently for reads and writes (with the reader treating it as transient, and writer as full)
     *
     * The method {@link ReplicaLayout#haveWriteConflicts} can be used to detect and resolve any issues
     */
    public static > E concat(E natural, E pending)
    {
        return AbstractReplicaCollection.concat(natural, pending, Conflict.NONE);
    }

    public static > E append(E replicas, Replica extraReplica)
    {
        Builder builder = replicas.newBuilder(replicas.size() + 1);
        builder.addAll(replicas);
        builder.add(extraReplica, Conflict.NONE);
        return builder.build();
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy