<commit_before>/*******************************************************************************
 * This file is part of OpenNMS(R).
 *
 * Copyright (C) 2014 The OpenNMS Group, Inc.
 * OpenNMS(R) is Copyright (C) 1999-2014 The OpenNMS Group, Inc.
 *
 * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.
 *
 * OpenNMS(R) is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published
 * by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 *
 * OpenNMS(R) is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with OpenNMS(R).  If not, see:
 *      http://www.gnu.org/licenses/
 *
 * For more information contact:
 *     OpenNMS(R) Licensing <<EMAIL>>
 *     http://www.opennms.org/
 *     http://www.opennms.com/
 *******************************************************************************/

package org.opennms.netmgt.model.topology;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class BroadcastDomain implements Topology {
    
    public static int maxlevel = 30;
    public static final int DOMAIN_MATCH_MIN_SIZE = 20;
    public static final float DOMAIN_MATCH_MIN_RATIO = 0.5f;
        
    public static void addforwarders(BroadcastDomain domain, BridgeForwardingTable bridgeFT) {
        Set<String> macs = new HashSet<String>(domain.getMacsOnSegments());
        domain.cleanForwarders(bridgeFT.getNodeId());
        for (String forward:  bridgeFT.getMactoport().keySet()) {
            if (macs.contains(forward)) {
                continue;
            }
            domain.addForwarding(bridgeFT.getMactoport().get(forward), forward);
        }
    }

    public static boolean checkMacSets(Set<String> setA, Set<String> setB) {
        Set<String>retainedSet = new HashSet<String>(setB);
        retainedSet.retainAll(setA);
        // should contain at list 20 or 50% of the all size
        if (retainedSet.size() > DOMAIN_MATCH_MIN_SIZE
            || retainedSet.size() > setA.size() * DOMAIN_MATCH_MIN_RATIO
            || retainedSet.size() > setB.size() * DOMAIN_MATCH_MIN_RATIO
                ) {
            return true;
        }
        return false;
    }

    public static Bridge electRootBridge(BroadcastDomain domain) throws BridgeTopologyException {
        if (domain.getBridges().size() == 1) {
            return domain.getBridges().iterator().next();
        }
        //well only one root bridge should be defined....
        //otherwise we need to skip calculation
        //so here is the place were we can
        //manage multi stp domains...
        //ignoring for the moment....
        for (Bridge electable: domain.getBridges()) {
            if (electable.getDesignated() != null) {
                return getUpperBridge(domain,electable,0);
            }
        }
        return null;
    }

    public static Bridge getUpperBridge(BroadcastDomain domain, Bridge electableroot, int level) throws BridgeTopologyException {
        if (level == maxlevel) {
            throw new BridgeTopologyException("getUpperBridge, too many iterations", electableroot);
        }
        for (Bridge electable: domain.getBridges()) {
            if (electable.getIdentifiers().contains(electableroot.getDesignated())) {
                return getUpperBridge(domain,electable, ++level);
            }
        }
        return electableroot;        
    }

    public static Map<Integer,Integer> getUpperForwardingBridgePorts(BroadcastDomain domain, Bridge bridge, Map<Integer,Integer> downports, int level) throws BridgeTopologyException {
        if (level == maxlevel) {
            throw new BridgeTopologyException("getUpperForwardingBridgePorts: too many iteration", bridge);
        }
        
        if (bridge.isRootBridge()) {
            return downports;
        }

        SharedSegment upSegment = domain.getSharedSegment(bridge.getNodeId(), bridge.getRootPort());
        if (upSegment == null) {
            throw new BridgeTopologyException("getUpperForwardingBridgePorts: no up segment", bridge);
        }
        
        Bridge upBridge = domain.getBridge(upSegment.getDesignatedBridge());
        if (upBridge == null) {
            throw new BridgeTopologyException("getUpperForwardingBridgePorts: no designated bridge on segment", bridge);
        }
        BridgePort bp = upSegment.getBridgePort(upBridge.getNodeId());
        downports.put(bp.getNodeId(),bp.getBridgePort());
        return getUpperForwardingBridgePorts(domain, upBridge, downports,++level);
    }
    
    public static Set<BridgeForwardingTableEntry> calculateBFT(
            BroadcastDomain domain, Bridge bridge)
            throws BridgeTopologyException {

        if ( domain == null ) {
            throw new BridgeTopologyException("calculateBFT: domain cannot be null");
        }

        if ( bridge == null ) {
            throw new BridgeTopologyException("calculateBFT: bridge cannot be null", domain);
        }
        Integer bridgeId = bridge.getNodeId();
        if ( bridgeId == null ) {
            throw new BridgeTopologyException("calculateBFT: bridge Id cannot be null", bridge);
        }
        Map<Integer, Set<String>> bft = new HashMap<Integer, Set<String>>();
        Map<Integer, BridgePort> portifindexmap = new HashMap<Integer, BridgePort>();

        Map<Integer,Integer> upperForwardingBridgePorts = getUpperForwardingBridgePorts(domain, bridge,new HashMap<Integer,Integer>(),0);
        
        Map<Integer,Integer> bridgeIdtobridgePortOnBridge = new HashMap<Integer, Integer>();
        
        for (Integer upperbridgeid: upperForwardingBridgePorts.keySet()) {
            bridgeIdtobridgePortOnBridge.put(upperbridgeid, bridge.getRootPort());
        }
                
        // 
        for (SharedSegment segment : domain.getSharedSegments()) {
            
           Integer bridgeport = null;
            
            if (segment.getBridgeIdsOnSegment().contains(bridgeId)) {
                BridgePort bport = segment.getBridgePort(bridgeId);
                portifindexmap.put(bport.getBridgePort(), bport);
                bridgeport = bport.getBridgePort();
            } else {
                bridgeport = getCalculateBFT(domain, segment, bridge, bridgeIdtobridgePortOnBridge,new HashSet<Integer>(),0);
            }

            if (!bft.containsKey(bridgeport)) {
                bft.put(bridgeport, new HashSet<String>());
            }
            bft.get(bridgeport).addAll(segment.getMacsOnSegment());
        }

        List<BridgePortWithMacs> links = new ArrayList<BridgePortWithMacs>(domain.getForwarders(bridgeId));        
        
        links.stream().forEach(link -> System.err.println("for:"+link.printTopology()));
        for (Integer bridgePort : bft.keySet()) {
            BridgePortWithMacs link = BridgePortWithMacs.create(portifindexmap.get(bridgePort), bft.get(bridgePort));
            links.add(link);
            System.err.println("bft:"+link.printTopology());
        }
        
        Set<BridgeForwardingTableEntry> entries=new HashSet<BridgeForwardingTableEntry>();
        links.stream().filter( bfti -> bfti.getMacs().size() > 0).forEach( bfti -> {
            entries.addAll(BridgeForwardingTableEntry.get(bfti));
        });
        return entries;
    }
    
    public static Integer getCalculateBFT(BroadcastDomain domain, SharedSegment segment,Bridge bridge, Map<Integer,Integer> bridgetobridgeport, Set<Integer> downBridgeIds,int level) throws BridgeTopologyException {
        if (level == maxlevel) {
            throw new BridgeTopologyException("getCalculateBFT: too many iteration", domain);
        }
        
        for (Integer bridgeIdOnsegment: segment.getBridgeIdsOnSegment()) {
            if (bridgetobridgeport.containsKey(bridgeIdOnsegment)) {
                Integer bridgeport = bridgetobridgeport.get(bridgeIdOnsegment);
                for (Integer bridgeidonsegment: downBridgeIds) {
                    bridgetobridgeport.put(bridgeidonsegment, bridgeport);
                }

                return bridgeport;
            }
        }        
        // if segment is on the bridge then...
        Integer upBridgeId = segment.getDesignatedBridge();<commit_msg>NMS-10258: enlinkd prints bridge forwarding table debug messages in output.log<commit_after>/*******************************************************************************
 * This file is part of OpenNMS(R).
 *
 * Copyright (C) 2014 The OpenNMS Group, Inc.
 * OpenNMS(R) is Copyright (C) 1999-2014 The OpenNMS Group, Inc.
 *
 * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.
 *
 * OpenNMS(R) is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published
 * by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 *
 * OpenNMS(R) is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with OpenNMS(R).  If not, see:
 *      http://www.gnu.org/licenses/
 *
 * For more information contact:
 *     OpenNMS(R) Licensing <<EMAIL>>
 *     http://www.opennms.org/
 *     http://www.opennms.com/
 *******************************************************************************/

package org.opennms.netmgt.model.topology;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class BroadcastDomain implements Topology {
    
    public static int maxlevel = 30;
    public static final int DOMAIN_MATCH_MIN_SIZE = 20;
    public static final float DOMAIN_MATCH_MIN_RATIO = 0.5f;
        
    public static void addforwarders(BroadcastDomain domain, BridgeForwardingTable bridgeFT) {
        Set<String> macs = new HashSet<String>(domain.getMacsOnSegments());
        domain.cleanForwarders(bridgeFT.getNodeId());
        for (String forward:  bridgeFT.getMactoport().keySet()) {
            if (macs.contains(forward)) {
                continue;
            }
            domain.addForwarding(bridgeFT.getMactoport().get(forward), forward);
        }
    }

    public static boolean checkMacSets(Set<String> setA, Set<String> setB) {
        Set<String>retainedSet = new HashSet<String>(setB);
        retainedSet.retainAll(setA);
        // should contain at list 20 or 50% of the all size
        if (retainedSet.size() > DOMAIN_MATCH_MIN_SIZE
            || retainedSet.size() > setA.size() * DOMAIN_MATCH_MIN_RATIO
            || retainedSet.size() > setB.size() * DOMAIN_MATCH_MIN_RATIO
                ) {
            return true;
        }
        return false;
    }

    public static Bridge electRootBridge(BroadcastDomain domain) throws BridgeTopologyException {
        if (domain.getBridges().size() == 1) {
            return domain.getBridges().iterator().next();
        }
        //well only one root bridge should be defined....
        //otherwise we need to skip calculation
        //so here is the place were we can
        //manage multi stp domains...
        //ignoring for the moment....
        for (Bridge electable: domain.getBridges()) {
            if (electable.getDesignated() != null) {
                return getUpperBridge(domain,electable,0);
            }
        }
        return null;
    }

    public static Bridge getUpperBridge(BroadcastDomain domain, Bridge electableroot, int level) throws BridgeTopologyException {
        if (level == maxlevel) {
            throw new BridgeTopologyException("getUpperBridge, too many iterations", electableroot);
        }
        for (Bridge electable: domain.getBridges()) {
            if (electable.getIdentifiers().contains(electableroot.getDesignated())) {
                return getUpperBridge(domain,electable, ++level);
            }
        }
        return electableroot;        
    }

    public static Map<Integer,Integer> getUpperForwardingBridgePorts(BroadcastDomain domain, Bridge bridge, Map<Integer,Integer> downports, int level) throws BridgeTopologyException {
        if (level == maxlevel) {
            throw new BridgeTopologyException("getUpperForwardingBridgePorts: too many iteration", bridge);
        }
        
        if (bridge.isRootBridge()) {
            return downports;
        }

        SharedSegment upSegment = domain.getSharedSegment(bridge.getNodeId(), bridge.getRootPort());
        if (upSegment == null) {
            throw new BridgeTopologyException("getUpperForwardingBridgePorts: no up segment", bridge);
        }
        
        Bridge upBridge = domain.getBridge(upSegment.getDesignatedBridge());
        if (upBridge == null) {
            throw new BridgeTopologyException("getUpperForwardingBridgePorts: no designated bridge on segment", bridge);
        }
        BridgePort bp = upSegment.getBridgePort(upBridge.getNodeId());
        downports.put(bp.getNodeId(),bp.getBridgePort());
        return getUpperForwardingBridgePorts(domain, upBridge, downports,++level);
    }
    
    public static Set<BridgeForwardingTableEntry> calculateBFT(
            BroadcastDomain domain, Bridge bridge)
            throws BridgeTopologyException {

        if ( domain == null ) {
            throw new BridgeTopologyException("calculateBFT: domain cannot be null");
        }

        if ( bridge == null ) {
            throw new BridgeTopologyException("calculateBFT: bridge cannot be null", domain);
        }
        Integer bridgeId = bridge.getNodeId();
        if ( bridgeId == null ) {
            throw new BridgeTopologyException("calculateBFT: bridge Id cannot be null", bridge);
        }
        Map<Integer, Set<String>> bft = new HashMap<Integer, Set<String>>();
        Map<Integer, BridgePort> portifindexmap = new HashMap<Integer, BridgePort>();

        Map<Integer,Integer> upperForwardingBridgePorts = getUpperForwardingBridgePorts(domain, bridge,new HashMap<Integer,Integer>(),0);
        
        Map<Integer,Integer> bridgeIdtobridgePortOnBridge = new HashMap<Integer, Integer>();
        
        for (Integer upperbridgeid: upperForwardingBridgePorts.keySet()) {
            bridgeIdtobridgePortOnBridge.put(upperbridgeid, bridge.getRootPort());
        }
                
        // 
        for (SharedSegment segment : domain.getSharedSegments()) {
            
           Integer bridgeport = null;
            
            if (segment.getBridgeIdsOnSegment().contains(bridgeId)) {
                BridgePort bport = segment.getBridgePort(bridgeId);
                portifindexmap.put(bport.getBridgePort(), bport);
                bridgeport = bport.getBridgePort();
            } else {
                bridgeport = getCalculateBFT(domain, segment, bridge, bridgeIdtobridgePortOnBridge,new HashSet<Integer>(),0);
            }

            if (!bft.containsKey(bridgeport)) {
                bft.put(bridgeport, new HashSet<String>());
            }
            bft.get(bridgeport).addAll(segment.getMacsOnSegment());
        }

        List<BridgePortWithMacs> links = new ArrayList<BridgePortWithMacs>(domain.getForwarders(bridgeId));        
        
        for (Integer bridgePort : bft.keySet()) {
            BridgePortWithMacs link = BridgePortWithMacs.create(portifindexmap.get(bridgePort), bft.get(bridgePort));
            links.add(link);
        }
        
        Set<BridgeForwardingTableEntry> entries=new HashSet<BridgeForwardingTableEntry>();
        links.stream().filter( bfti -> bfti.getMacs().size() > 0).forEach( bfti -> {
            entries.addAll(BridgeForwardingTableEntry.get(bfti));
        });
        return entries;
    }
    
    public static Integer getCalculateBFT(BroadcastDomain domain, SharedSegment segment,Bridge bridge, Map<Integer,Integer> bridgetobridgeport, Set<Integer> downBridgeIds,int level) throws BridgeTopologyException {
        if (level == maxlevel) {
            throw new BridgeTopologyException("getCalculateBFT: too many iteration", domain);
        }
        
        for (Integer bridgeIdOnsegment: segment.getBridgeIdsOnSegment()) {
            if (bridgetobridgeport.containsKey(bridgeIdOnsegment)) {
                Integer bridgeport = bridgetobridgeport.get(bridgeIdOnsegment);
                for (Integer bridgeidonsegment: downBridgeIds) {
                    bridgetobridgeport.put(bridgeidonsegment, bridgeport);
                }

                return bridgeport;
            }
        }        
        // if segment is on the bridge then...
        Integer upBridgeId = segment.getDesignatedBridge();
{'fraction_non_alphanumeric': 0.1129473377945883, 'fraction_numerical': 0.0035496072155949956, 'mean_word_length': 2.6730070527890577, 'pattern_counts': {'":': 0, '<': 61, '<?xml version=': 0, '>': 74, 'https://': 0, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1377168', 'n_tokens_mistral': 4712, 'n_tokens_neox': 4495, 'n_words': 1139}