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

com.hazelcast.internal.crdt.ReplicatedVectorClocks Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2008-2024, Hazelcast, Inc. All Rights Reserved.
 *
 * Licensed 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 com.hazelcast.internal.crdt;

import com.hazelcast.cluster.impl.VectorClock;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import static com.hazelcast.internal.util.Preconditions.checkNotNull;

/**
 * Contains the vector clocks for tracking successfully replicated state
 * for all CRDTs and to any replica.
 * 

* The CRDT state updates can either be a mutation invoked by the user or a merge with a * CRDT received by a replication operation. * * @see CRDTReplicationAwareService */ class ReplicatedVectorClocks { /** * Map which contains the information on last successfully replicated CRDT * states for all CRDTs and to all replicas. The map can be used to determine * which CRDT state has not yet been replicated and to which replicas. */ private ConcurrentMap> replicatedVectorClocks = new ConcurrentHashMap<>(); /** * Returns the vector clocks for the given {@code serviceName} and * {@code memberUUID}. * The vector clock map contains mappings from CRDT name to the last * successfully replicated CRDT vector clock. All CRDTs in this map should * be of the same type. * If there are no vector clocks for the given parameters, this method * returns an empty map. * * @param serviceName the service name * @param memberUUID the target member UUID * @return the last successfully replicated CRDT vector clocks or an empty * map if the CRDTs have not yet been replicated to this member * @see CRDTReplicationAwareService */ public Map getReplicatedVectorClock(String serviceName, UUID memberUUID) { final ReplicatedVectorClockId id = new ReplicatedVectorClockId(serviceName, memberUUID); final Map clocks = replicatedVectorClocks.get(id); return clocks != null ? clocks : Collections.emptyMap(); } /** * Sets the vector clock map for the given {@code serviceName} and * {@code memberUUID}. * The vector clock map contains mappings from CRDT name to the last * successfully replicated CRDT state version. All CRDTs in this map should * be of the same type. * * @param serviceName the service name * @param memberUUID the target member UUID * @param vectorClocks the vector clock map to set * @see CRDTReplicationAwareService */ public void setReplicatedVectorClocks(String serviceName, UUID memberUUID, Map vectorClocks) { replicatedVectorClocks.put(new ReplicatedVectorClockId(serviceName, memberUUID), Collections.unmodifiableMap(vectorClocks)); } /** * Returns the vector clock map for the given {@code serviceName}. * For each CRDT belonging to that service, the map contains the latest * successfully replicated vector clocks to any replica. * * @param serviceName the CRDT service name * @return the last successfully replicated vector clock for all CRDTs for * the given {@code serviceName} * @see CRDTReplicationAwareService */ public Map getLatestReplicatedVectorClock(String serviceName) { final HashMap latestVectorClocks = new HashMap<>(); for (Entry> clockEntry : replicatedVectorClocks.entrySet()) { final ReplicatedVectorClockId id = clockEntry.getKey(); final Map clock = clockEntry.getValue(); if (id.serviceName.equals(serviceName)) { for (Entry crdtReplicatedClocks : clock.entrySet()) { final String crdtName = crdtReplicatedClocks.getKey(); final VectorClock vectorClock = crdtReplicatedClocks.getValue(); final VectorClock latestVectorClock = latestVectorClocks.get(crdtName); if (latestVectorClock == null || vectorClock.isAfter(latestVectorClock)) { latestVectorClocks.put(crdtName, vectorClock); } } } } return latestVectorClocks; } /** * An identifier for a CRDT vector clock map. The clock is identified by * the CRDT service name and the target member UUID. * * @see CRDTReplicationAwareService */ private static class ReplicatedVectorClockId { final UUID memberUUID; final String serviceName; ReplicatedVectorClockId(String serviceName, UUID memberUUID) { this.serviceName = checkNotNull(serviceName, "Service name must not be null"); this.memberUUID = checkNotNull(memberUUID, "Member UUID must not be null"); } @Override @SuppressWarnings("checkstyle:innerassignment") public boolean equals(Object o) { final ReplicatedVectorClockId that; return this == o || o instanceof ReplicatedVectorClockId rvci && this.serviceName.equals((that = rvci).serviceName) && this.memberUUID.equals(that.memberUUID); } @Override public int hashCode() { int result = memberUUID.hashCode(); result = 31 * result + serviceName.hashCode(); return result; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy