Search in sources :

Example 1 with EventuallyConsistentMapEvent

use of org.onosproject.store.service.EventuallyConsistentMapEvent in project onos by opennetworkinglab.

the class EventuallyConsistentMapImpl method antiEntropyCheckLocalItems.

/**
 * Processes anti-entropy ad from peer by taking following actions:
 * 1. If peer has an old entry, updates peer.
 * 2. If peer indicates an entry is removed and has a more recent
 * timestamp than the local entry, update local state.
 */
private List<EventuallyConsistentMapEvent<K, V>> antiEntropyCheckLocalItems(AntiEntropyAdvertisement<K> ad) {
    final List<EventuallyConsistentMapEvent<K, V>> externalEvents = Lists.newLinkedList();
    final NodeId sender = ad.sender();
    final List<NodeId> peers = ImmutableList.of(sender);
    Set<K> staleOrMissing = new HashSet<>();
    Set<K> locallyUnknown = new HashSet<>(ad.digest().keySet());
    items.forEach((key, localValue) -> {
        locallyUnknown.remove(key);
        MapValue.Digest remoteValueDigest = ad.digest().get(key);
        if (remoteValueDigest == null || localValue.isNewerThan(remoteValueDigest.timestamp())) {
            // local value is more recent, push to sender
            queueUpdate(new UpdateEntry<>(key, localValue), peers);
        } else if (remoteValueDigest.isNewerThan(localValue.digest()) && remoteValueDigest.isTombstone()) {
            // remote value is more recent and a tombstone: update local value
            MapValue<V> tombstone = MapValue.tombstone(remoteValueDigest.timestamp());
            MapValue<V> previousValue = removeInternal(key, Optional.empty(), Optional.of(tombstone));
            if (previousValue != null && previousValue.isAlive()) {
                externalEvents.add(new EventuallyConsistentMapEvent<>(mapName, REMOVE, key, previousValue.get()));
            }
        } else if (remoteValueDigest.isNewerThan(localValue.digest())) {
            // Not a tombstone and remote is newer
            staleOrMissing.add(key);
        }
    });
    // Keys missing in local map
    staleOrMissing.addAll(locallyUnknown);
    // Request updates that we missed out on
    sendUpdateRequestToPeer(sender, staleOrMissing);
    return externalEvents;
}
Also used : EventuallyConsistentMapEvent(org.onosproject.store.service.EventuallyConsistentMapEvent) NodeId(org.onosproject.cluster.NodeId) HashSet(java.util.HashSet)

Example 2 with EventuallyConsistentMapEvent

use of org.onosproject.store.service.EventuallyConsistentMapEvent in project onos by opennetworkinglab.

the class EventuallyConsistentMapImpl method compute.

@Override
public V compute(K key, BiFunction<K, V, V> recomputeFunction) {
    checkState(!destroyed, destroyedMessage);
    checkNotNull(key, ERROR_NULL_KEY);
    checkNotNull(recomputeFunction, "Recompute function cannot be null");
    AtomicBoolean updated = new AtomicBoolean(false);
    AtomicReference<MapValue<V>> previousValue = new AtomicReference<>();
    MapValue<V> computedValue = items.compute(serializer.copy(key), (k, mv) -> {
        previousValue.set(mv);
        V newRawValue = recomputeFunction.apply(key, mv == null ? null : mv.get());
        if (mv != null && Objects.equals(newRawValue, mv.get())) {
            // value was not updated
            return mv;
        }
        MapValue<V> newValue = new MapValue<>(newRawValue, timestampProvider.apply(key, newRawValue));
        if (mv == null || newValue.isNewerThan(mv)) {
            updated.set(true);
            // This prevents replica divergence due to serialization failures.
            return serializer.copy(newValue);
        } else {
            return mv;
        }
    });
    if (updated.get()) {
        notifyPeers(new UpdateEntry<>(key, computedValue), peerUpdateFunction.apply(key, computedValue.get()));
        EventuallyConsistentMapEvent.Type updateType = computedValue.isTombstone() ? REMOVE : PUT;
        V value = computedValue.isTombstone() ? previousValue.get() == null ? null : previousValue.get().get() : computedValue.get();
        if (value != null) {
            notifyListeners(new EventuallyConsistentMapEvent<>(mapName, updateType, key, value));
        }
    }
    return computedValue.get();
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) EventuallyConsistentMapEvent(org.onosproject.store.service.EventuallyConsistentMapEvent) AtomicReference(java.util.concurrent.atomic.AtomicReference)

Aggregations

EventuallyConsistentMapEvent (org.onosproject.store.service.EventuallyConsistentMapEvent)2 HashSet (java.util.HashSet)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 NodeId (org.onosproject.cluster.NodeId)1