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

io.vlingo.actors.pubsub.Subscriptions Maven / Gradle / Ivy

Go to download

Type safe Actor Model toolkit for reactive concurrency and resiliency using Java and other JVM languages.

There is a newer version: 1.7.5
Show newest version
// Copyright © 2012-2018 Vaughn Vernon. All rights reserved.
//
// This Source Code Form is subject to the terms of the
// Mozilla Public License, v. 2.0. If a copy of the MPL
// was not distributed with this file, You can obtain
// one at https://mozilla.org/MPL/2.0/.

package io.vlingo.actors.pubsub;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class Subscriptions {

    private Map>> index = new HashMap<>();

    public AffectedSubscriptions create(final Topic topic, final Subscriber subscriber) {

        if(!index.containsKey(topic)) {
            index.put(topic, new HashSet<>());
        }

        return performOperation(topic, subscriber, defaultCondition(), insertOperation());
    }

    public AffectedSubscriptions cancel(final Topic topic, final Subscriber subscriber) {
        return performOperation(topic, subscriber, defaultCondition(), removalOperation());
    }

    public AffectedSubscriptions cancelAll(final Subscriber subscriber) {
        return performOperation(null, subscriber, noCondition(), removalOperation());
    }

    public Set> forTopic(final Topic topic) {

        final Set> subscribers = new HashSet<>();

        index.entrySet().forEach(subscription -> {

            final Topic subscribedTopic = subscription.getKey();

            if(subscribedTopic.equals(topic) || subscribedTopic.isSubTopic(topic)) {
                subscribers.addAll(subscription.getValue());
            }
        });

        return subscribers;
    }

    private Operation insertOperation() {
        return (existingValues, givenValue) -> existingValues.add(givenValue);
    }

    private Operation removalOperation() {
        return (existingValues, givenValue) -> existingValues.remove(givenValue);
    }

    private Condition defaultCondition() {
        return (subscription, topic, subscriber) -> subscription.getKey().equals(topic);
    }

    private Condition noCondition() {
        return (subscription, topic, subscriber) -> true;
    }

    private AffectedSubscriptions performOperation(final Topic topic, final Subscriber subscriber, final Condition condition, final Operation operation) {

        final AffectedSubscriptions affectedSubscriptions = new AffectedSubscriptions();

        index.entrySet().forEach(subscription -> {
            if(condition.should(subscription, topic, subscriber) &&
                    operation.perform(subscription.getValue(), subscriber)) {
                affectedSubscriptions.add(topic, subscriber);
            }
        });

        return affectedSubscriptions;
    }

    @FunctionalInterface
    private interface Operation {
        boolean perform(final Set> existingSubscriber, final Subscriber givenSubscriber);
    }

    @FunctionalInterface
    private interface Condition {
        boolean should(final Entry>> subscription, final Topic topic, final Subscriber subscriber);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy