Martin Mucha has uploaded a new change for review. Change subject: core: do not iterate over MACs to find multicast one. ......................................................................
core: do not iterate over MACs to find multicast one. Change-Id: I9e71c861a9f71c93f3746269fe23020b7f7cfd4a Signed-off-by: Martin Mucha <mmu...@redhat.com> --- M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/MacPoolManagerRanges.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/MacsStorage.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/Range.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/UsedMacsBitSet.java M backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/DisjointRanges.java M backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/MacAddressRangeUtils.java 6 files changed, 63 insertions(+), 77 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/60/27760/1 diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/MacPoolManagerRanges.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/MacPoolManagerRanges.java index 8bf76bb..fe2c493 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/MacPoolManagerRanges.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/MacPoolManagerRanges.java @@ -61,10 +61,9 @@ private MacsStorage createMacsStorage(String rangesString) { List<Pair<Long, Long>> rangesBoundaries = MacAddressRangeUtils.rangesTextualDefinitionToRangeBoundaries(rangesString); - int macsToCreate = maxMacsInPool; - MacsStorage macsStorage = new MacsStorage(this.allowDuplicates); + MacsStorage macsStorage = new MacsStorage(this.allowDuplicates, maxMacsInPool); for (Pair<Long, Long> rangesBoundary : rangesBoundaries) { - macsToCreate -= macsStorage.addRange(rangesBoundary.getFirst(), rangesBoundary.getSecond(), macsToCreate); + macsStorage.addRange(rangesBoundary.getFirst(), rangesBoundary.getSecond()); } if (macsStorage.noAvailableMacs()) { diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/MacsStorage.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/MacsStorage.java index 1150f62..638d5fb 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/MacsStorage.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/MacsStorage.java @@ -9,35 +9,20 @@ class MacsStorage { private final boolean allowDuplicates; + private int createUpToNMacs; private List<Range> ranges = new LinkedList<>(); private ObjectCounter<Long> customMacs; - public MacsStorage(boolean allowDuplicates) { + public MacsStorage(boolean allowDuplicates, int createUpToNMacs) { this.allowDuplicates = allowDuplicates; + this.createUpToNMacs = createUpToNMacs; customMacs = new ObjectCounter<>(this.allowDuplicates); } - public long addRange(long rangeStart, long rangeEnd, int maxMacsInPool) { - - long i = rangeStart; - int numberOfNonMultiCasts = 0; - - for (; i < rangeEnd && numberOfNonMultiCasts < maxMacsInPool; i++) { - if (!MacAddressRangeUtils.macIsMulticast(i)) { - numberOfNonMultiCasts++; - } - } - - long size = i - rangeStart; - if (size > Integer.MAX_VALUE) { - throw new IllegalArgumentException("Not supported that wide ranges(" + size + ")."); - } - - if (numberOfNonMultiCasts > 0) { - //java. arrays/collections can not be bigger than 2^32. - ranges.add(new Range(rangeStart, (int)size, numberOfNonMultiCasts)); - } - return numberOfNonMultiCasts; + public void addRange(long rangeStart, long rangeEnd) { + int numberOfMacs = Math.min((int)(rangeEnd - rangeStart), createUpToNMacs); + ranges.add(new Range(rangeStart, numberOfMacs)); + createUpToNMacs -= numberOfMacs; } public boolean useMac(long mac) { @@ -113,7 +98,7 @@ private void testForMultiCastMac(long mac) { if (MacAddressRangeUtils.macIsMulticast(mac)) { - throw new IllegalArgumentException("You're trying to work with multicast address."); //TODO MM: should this be prohibited? + throw new IllegalArgumentException("You're trying to work with multicast address."); } } diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/Range.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/Range.java index b9d13f3..927cda1 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/Range.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/Range.java @@ -17,10 +17,10 @@ return offset <= mac && (offset + size) >= mac; } - public Range(long offset, int size, int numberOfNonMultiCasts) { + public Range(long offset, int size) { this.offset = offset; this.size = size; - this.notUsedCount = numberOfNonMultiCasts; + this.notUsedCount = size; macUsageCount = new int[size]; this.usedMacs = new UsedMacsBitSet(size); diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/UsedMacsBitSet.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/UsedMacsBitSet.java index 0e2a036..5968c98 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/UsedMacsBitSet.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/UsedMacsBitSet.java @@ -2,8 +2,6 @@ import java.util.BitSet; -import org.ovirt.engine.core.utils.MacAddressRangeUtils; - class UsedMacsBitSet implements UsedMacs { private BitSet bitSet; @@ -25,19 +23,11 @@ @Override public long unusedMac(long offset) { - int start = 0; - int notUsedMacIndex = 0; - while (notUsedMacIndex != -1) { - notUsedMacIndex = this.bitSet.nextSetBit(start); - start = notUsedMacIndex; - long mac = offset + notUsedMacIndex; - if (MacAddressRangeUtils.macIsMulticast(mac)) { - removeMacFromNotUsed(notUsedMacIndex); - } else { - return mac; - } + int index = this.bitSet.nextSetBit(0); + if (index == -1) { + throw new IllegalStateException("There should be available mac, but there isn't any"); } - throw new IllegalStateException("There should be available mac, but there isn't any"); + return offset + index; } } diff --git a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/DisjointRanges.java b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/DisjointRanges.java index 6dd1eba..1538aff 100644 --- a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/DisjointRanges.java +++ b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/DisjointRanges.java @@ -29,7 +29,7 @@ } public void addRange(long addedLeft, long addedRight) { - if (addedLeft > addedRight) { + if (addedLeft > addedRight || addedLeft < 0 || addedRight < 0) { throw new IllegalArgumentException("badly defined range"); } diff --git a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/MacAddressRangeUtils.java b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/MacAddressRangeUtils.java index 559c1c4..b912a56 100644 --- a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/MacAddressRangeUtils.java +++ b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/MacAddressRangeUtils.java @@ -6,46 +6,14 @@ import org.apache.commons.lang.StringUtils; import org.ovirt.engine.core.common.utils.Pair; -import org.ovirt.engine.core.utils.log.Log; -import org.ovirt.engine.core.utils.log.LogFactory; public class MacAddressRangeUtils { - private static final Log LOGGER = LogFactory.getLog(MacAddressRangeUtils.class); private static final int HEX_RADIX = 16; public static final long MAC_ADDRESS_MULTICAST_BIT = 0x010000000000L; private MacAddressRangeUtils() { - } - - public static List<String> initRange(String start, String end, int size) { - long startNum = macToLong(start); - long endNum = macToLong(end); - - return innerInitRange(size, startNum, endNum); - } - - private static List<String> innerInitRange(int stopAfter, long startNum, long endNum) { - if (startNum > endNum) { - return Collections.emptyList(); - } - - // Initialize ArrayList for all potential records. (ignore that there need not be that many records. - List<String> macAddresses = new ArrayList<>(Math.min(stopAfter, (int) (endNum - startNum))); - for (long i = startNum; i <= endNum; i++) { - if (macIsMulticast(i)) { - continue; - } - - macAddresses.add(macToString(i)); - - if (--stopAfter <= 0) { - return macAddresses; - } - } - - return macAddresses; } public static List<String> macAddressesToStrings(List<Long> macAddresses) { @@ -76,7 +44,7 @@ } } - return disjointRanges.getRanges(); + return clipMultiCastsFromRanges(disjointRanges.getRanges()); } public static boolean macIsMulticast(long mac) { @@ -106,6 +74,50 @@ long startNum = macToLong(start); long endNum = macToLong(end); - return !innerInitRange(1, startNum, endNum).isEmpty(); + if (startNum > endNum) { + return false; + } + + DisjointRanges disjointRanges = new DisjointRanges(); + disjointRanges.addRange(startNum, endNum); + List<Pair<Long, Long>> ranges = clipMultiCastsFromRanges(disjointRanges.getRanges()); + + for (Pair<Long, Long> range : ranges) { + if (range.getSecond() - range.getFirst() > 0) { + return true; + } + } + + return false; + } + + private static List<Pair<Long, Long>> clipMultiCastsFromRanges(List<Pair<Long, Long>> ranges) { + final List<Pair<Long, Long>> result = new ArrayList<>(); + for (Pair<Long, Long> range : ranges) { + result.addAll(clipMultiCastsFromRange(range.getFirst(), range.getSecond())); + } + return result; + } + + private static List<Pair<Long, Long>> clipMultiCastsFromRange(long rangeStart, long rangeEnd) { + long OUI_MULTICAST_BIT = 0x000000010000L; + long startOui = toOui(rangeStart); + long endOui = toOui(rangeEnd); + + List<Pair<Long, Long>> result = new ArrayList<>((int) (endOui - startOui + 1)); + for (long oui = startOui; oui <= endOui; oui++) { + boolean multicast = (oui & OUI_MULTICAST_BIT) != 0; + if (!multicast) { + result.add(new Pair<>(oui << 24, (oui << 24) | 0xffffffL )); + } + } + + result.get(0).setFirst(rangeStart); + result.get(result.size() - 1).setSecond(rangeEnd); + return result; + } + + private static long toOui(long end) { + return (end >> 24); } } -- To view, visit http://gerrit.ovirt.org/27760 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I9e71c861a9f71c93f3746269fe23020b7f7cfd4a Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Martin Mucha <mmu...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches