/* * Copyright (c) 2015 Hewlett Packard Enterprise Development Company, L.P. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.nic.graph.impl; import org.opendaylight.nic.graph.api.Classifer; import java.util.*; public class ClassifierImpl implements Classifer{ /* Class to implement classifier map to application port numbers */ private final Set<ExpressionImpl> expressions; @Override public Set<ExpressionImpl> getExpressions() { return expressions; } @Override public boolean isEmpty() { return (expressions.isEmpty()); } public static ClassifierImpl getInstance(ExpressionImpl exp) { Collection<ExpressionImpl> co = new HashSet<ExpressionImpl>(); co.add(exp); return getInstance(co); } public static ClassifierImpl getInstance( Collection<ExpressionImpl> expressioncollection) { return new ClassifierImpl(expressioncollection); } public ClassifierImpl () { expressions = new HashSet<ExpressionImpl>(); } public ClassifierImpl(Collection<ExpressionImpl> co) { expressions = new HashSet<ExpressionImpl>(); expressions.addAll(co); // TODO // while (removeOverlaps(self.expressions) == True): // continue // self.expressions.sort(key = lambda e: e.expression, reverse=True) } @Override public String toString() { return "{" + expressions + "}"; } /** * Operator <em>sub</em> finds the difference between two Classifiers. * <p> * Calculates this - other. Subtracting or'd items in a list is done using * subtraction Each subtracted item can do 1 of 4 things to the 'self' * items: * <ul> * <li>1. miss - have no impact * <li>2. overlap and remove part of it * <li>3. split the 'self' item and remove some * <li>4. remove the entire 'self' item * </ul> * @param other classifier expression * @return ClassifierImpl */ public ClassifierImpl sub(ClassifierImpl other) { List<ExpressionImpl> workList = new LinkedList<ExpressionImpl>( this.expressions); List<ExpressionImpl> difference = new LinkedList<ExpressionImpl>(); while (!workList.isEmpty()) { ExpressionImpl eleft = workList.get(0); boolean noOverlap = true; for (ExpressionImpl eother : other.getExpressions()) { Set<ExpressionImpl> resultSet = eleft.sub(eother); if (resultSet.isEmpty()) { // case #4: subtraction removed entire expression noOverlap = false; workList.remove(0); break; } else if ((resultSet.size() == 1) && resultSet.contains(eleft)) { // case #1: subtraction had no impact continue; } else { // cases 2,3: overlap happened. Add result to work list. noOverlap = false; workList.remove(eleft); workList.addAll(resultSet); break; } } if (noOverlap) { difference.add(eleft); workList.remove(eleft); } } return getInstance(difference); } public boolean greaterThan(ClassifierImpl other) { ClassifierImpl difference = this.sub(other); return !difference.isEmpty(); } public boolean lessThan(ClassifierImpl other) { return other.greaterThan(this); } public boolean greaterThanOrEqual(ClassifierImpl other) { return (this.equals(other)) || greaterThan(other); } public ClassifierImpl and(ClassifierImpl other) { Collection<ExpressionImpl> result = new HashSet<ExpressionImpl>(); for (ExpressionImpl exp : this.expressions) { for (ExpressionImpl oe : other.getExpressions()) { ExpressionImpl overlap = exp.and(oe); if (overlap.isNull()) { continue; } result.add(overlap); } } return getInstance(result); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((expressions == null) ? 0 : expressions.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } ClassifierImpl other = (ClassifierImpl) obj; if (expressions == null) { if (other.expressions != null) { return false; } } else if (!expressions.equals(other.expressions)) { return false; } return true; } }