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

io.debezium.ibmi.db2.journal.retrieve.rnrn0200.ReceiverChain Maven / Gradle / Ivy

There is a newer version: 3.0.3.Final
Show newest version
/*
 * Copyright Debezium Authors.
 *
 * Licensed under the Apache Software License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
 */
package io.debezium.ibmi.db2.journal.retrieve.rnrn0200;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import io.debezium.ibmi.db2.journal.retrieve.JournalReceiver;

public class ReceiverChain {
    DetailedJournalReceiver details;
    Optional next = Optional.empty();
    Optional previous = Optional.empty();

    /**
     * assumed to be unique on DetailedJournalReceiver.info.name
     * @param details
     * @param next
     */
    public ReceiverChain(DetailedJournalReceiver details) {
        super();
        if (details == null || details.info() == null || details.info().receiver() == null || details.info().receiver().name() == null) {
            throw new IllegalArgumentException("neither head, head.info or head.info.name can be null " + details);
        }
        this.details = details;
    }

    @Override
    public int hashCode() { // simplified hashcode and equals so we can lookup based on receiver only
        return Objects.hash(details.info().receiver());
    }

    @Override
    public boolean equals(Object obj) { // simplified hashcode and equals so we can lookup based on name only
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final ReceiverChain other = (ReceiverChain) obj;
        return this.details.info().receiver().equals(other.details.info().receiver());
    }

    @Override
    public String toString() {
        return String.format("ReceiverChain [details=%s, next=%s, previous=%s]", details, next, previous);
    }

    public static List chainContaining(List l, DetailedJournalReceiver needle) {
        final Map m = availableSingleChainElement(l);

        buildReceiverChains(m);

        final Optional lastDetached = findChain(m, needle);

        return lastDetached.map(x -> chainToList(x)).orElse(Collections.emptyList());
    }

    static Map availableSingleChainElement(List l) {
        final List validReceivers = l.stream().filter(x -> switch (x.info().status()) {
            case Attached, OnlineSavedDetached, SavedDetchedNotFreed -> true;
            default -> false;
        }).toList(); // ignore any deleted or unused journals

        final Map m = validReceivers.stream()
                .collect(Collectors. toMap(x -> x.info().receiver(),
                        y -> new ReceiverChain(y)));
        return m;
    }

    /**
     * Finds the first element in the chain with this receiver or empty if not in map
     * @param m
     * @param needle
     * @return
     */
    static Optional findChain(final Map m, DetailedJournalReceiver needle) {
        JournalReceiver key = needle.info().receiver();
        if (m.containsKey(key)) {
            ReceiverChain rc = m.get(key);
            while (rc.previous.isPresent()) {
                rc = rc.previous.get();
            }
            return Optional.of(rc);
        }
        else {
            return Optional.empty();
        }
    }

    static List chainToList(ReceiverChain chain) {
        List l = new ArrayList<>();
        l.add(chain.details);

        while (chain.next.isPresent()) {
            chain = chain.next.get();
            l.add(chain.details);
        }
        return l;
    }

    static Set buildReceiverChains(final Map m) {
        final Set noNext = new HashSet<>(m.values()); // set of all receivers not mentioned by others

        // each receiver lookup nextReceiver in hash and add to next
        // references to other receivers to remove from noNext
        for (final ReceiverChain or : m.values()) {
            or.details.nextReceiver().ifPresent(nextReceiver -> {
                if (m.containsKey(nextReceiver)) {
                    final ReceiverChain nr = m.get(nextReceiver);
                    noNext.remove(nr);
                    or.next = Optional.of(nr);
                    nr.previous = Optional.of(or);
                }
            });
        }
        return noNext;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy