public void addPrefixRange(PrefixRange prefixRange, BitSet bits, int prefixLength, int depth) { if (_prefixRanges.stream().anyMatch(nr -> nr.includesPrefixRange(prefixRange))) { return; } if (prefixLength == depth) { prune(prefixRange); _prefixRanges = ImmutableSet.<PrefixRange>builderWithExpectedSize(_prefixRanges.size() + 1) .addAll(_prefixRanges) .add(prefixRange) .build(); } else { boolean currentBit = bits.get(depth); if (currentBit) { if (_right == null) { _right = new BitTrieNode(); } _right.addPrefixRange(prefixRange, bits, prefixLength, depth + 1); } else { if (_left == null) { _left = new BitTrieNode(); } _left.addPrefixRange(prefixRange, bits, prefixLength, depth + 1); } } }
public void collectPrefixRanges(Set<PrefixRange> prefixRanges) { prefixRanges.addAll(_prefixRanges); if (_left != null) { _left.collectPrefixRanges(prefixRanges); } if (_right != null) { _right.collectPrefixRanges(prefixRanges); } }
private void prune(PrefixRange prefixRange) { if (_left != null) { _left.prune(prefixRange); if (_left.isEmpty()) { _left = null; } } if (_right != null) { _right.prune(prefixRange); if (_right.isEmpty()) { _right = null; } } if (_prefixRanges.stream().anyMatch(prefixRange::includesPrefixRange)) { _prefixRanges = _prefixRanges.stream() .filter(pr -> !prefixRange.includesPrefixRange(pr)) .collect(ImmutableSet.toImmutableSet()); } } }
public boolean containsPrefixRange( PrefixRange prefixRange, BitSet bits, int prefixLength, int depth) { for (PrefixRange nodeRange : _prefixRanges) { if (nodeRange.includesPrefixRange(prefixRange)) { return true; } } if (prefixLength == depth) { return false; } else { boolean currentBit = bits.get(depth); if (currentBit) { if (_right == null) { return false; } else { return _right.containsPrefixRange(prefixRange, bits, prefixLength, depth + 1); } } else { if (_left == null) { return false; } else { return _left.containsPrefixRange(prefixRange, bits, prefixLength, depth + 1); } } } }
public void addPrefixRange(PrefixRange prefixRange) { Prefix prefix = prefixRange.getPrefix(); BitSet bits = getAddressBits(prefix.getStartIp()); // The minimum length of the range may be shorter than the actual prefix length. // If so, we need to specially handle all shorter prefixes with a custom address and bitset. int minLength = prefixRange.getLengthRange().getStart(); int maxLength = Math.min(prefixRange.getLengthRange().getEnd(), prefix.getPrefixLength() - 1); for (int currentLength = minLength; currentLength <= maxLength; currentLength++) { Prefix currentPrefix = Prefix.create(prefix.getStartIp(), currentLength); PrefixRange currentPrefixRange = PrefixRange.fromPrefix(currentPrefix); BitSet currentBits = getAddressBits(currentPrefix.getStartIp()); _root.addPrefixRange(currentPrefixRange, currentBits, currentLength, 0); } // Otherwise, add the prefix range as-is. _root.addPrefixRange(prefixRange, bits, prefix.getPrefixLength(), 0); }
public BitTrie() { _root = new BitTrieNode(); }
public boolean containsPrefixRange(PrefixRange prefixRange) { Prefix prefix = prefixRange.getPrefix(); int prefixLength = prefix.getPrefixLength(); BitSet bits = getAddressBits(prefix.getStartIp()); return _root.containsPrefixRange(prefixRange, bits, prefixLength, 0); }
public Set<PrefixRange> getPrefixRanges() { Set<PrefixRange> prefixRanges = new HashSet<>(); _root.collectPrefixRanges(prefixRanges); return prefixRanges; } }