From 4b080f12083a5e76f22ec74f385c6320a305711b Mon Sep 17 00:00:00 2001 From: Rudy Alvarez Date: Sat, 10 Sep 2022 17:09:02 +0200 Subject: [PATCH 1/7] speed up hex digitSequence creation --- .../software/amazon/event/ruler/Range.java | 43 ++++++++++++------- .../software/amazon/event/ruler/CIDRTest.java | 31 ++++++------- 2 files changed, 43 insertions(+), 31 deletions(-) diff --git a/src/main/software/amazon/event/ruler/Range.java b/src/main/software/amazon/event/ruler/Range.java index cb09921..949783e 100644 --- a/src/main/software/amazon/event/ruler/Range.java +++ b/src/main/software/amazon/event/ruler/Range.java @@ -1,9 +1,7 @@ package software.amazon.event.ruler; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; import java.util.Arrays; -import java.util.List; /** * Represents a range of numeric values to match against. @@ -56,20 +54,26 @@ private Range(Range range) { public static Range lessThan(final double val) { return new Range(-Constants.FIVE_BILLION, false, val, true); } + public static Range lessThanOrEqualTo(final double val) { return new Range(-Constants.FIVE_BILLION, false, val, false); } + public static Range greaterThan(final double val) { return new Range(val, true, Constants.FIVE_BILLION, false); } + public static Range greaterThanOrEqualTo(final double val) { return new Range(val, false, Constants.FIVE_BILLION, false); } + public static Range between(final double bottom, final boolean openBottom, final double top, final boolean openTop) { return new Range(bottom, openBottom, top, openTop); } - private static Range deepCopy(final Range range) { return new Range(range); } + private static Range deepCopy(final Range range) { + return new Range(range); + } /** * This is necessitated by the fact that we do range comparisons of numbers, fixed-length strings of digits, and @@ -77,32 +81,39 @@ public static Range between(final double bottom, final boolean openBottom, final * "for all digits between '3' and 'C'". This is for that. * * @param first Start one digit higher than this, for example '4' - * @param last Stop one digit lower than this 'B' - * @return The digit list, for example [ '4, '5', '6', '7', '8', '9', '9', 'A' ] (with 'B' for longDigitSequence) + * @param last Stop one digit lower than this, for example 'B' + * @return The digit list, for example [ '4', '5', '6', '7', '8', '9', '9', 'A' ] (with 'B' for longDigitSequence) */ - static List digitSequence(byte first, byte last, boolean includeFirst, boolean includeLast) { - assert first <= last && first <= 'F'&& first >= '0'&& last <= 'F' && last >= '0'; + static byte[] digitSequence(byte first, byte last, boolean includeFirst, boolean includeLast) { + assert first <= last && first <= 'F' && first >= '0' && last <= 'F'; assert !((first == last) && !includeFirst && !includeLast); - final List bytes = new ArrayList<>(); - int i = 0; - while (Constants.HEX_DIGITS[i] < first) { - i++; - } + int i = getHexByteIndex(first); + int j = getHexByteIndex(last); if ((!includeFirst) && (i < (Constants.HEX_DIGITS.length - 1))) { i++; } - while (Constants.HEX_DIGITS[i] < last) { - bytes.add(Constants.HEX_DIGITS[i++]); - } + if (includeLast) { - bytes.add(Constants.HEX_DIGITS[i]); + j++; } + byte[] bytes = new byte[j - i]; + + System.arraycopy(Constants.HEX_DIGITS, i, bytes, 0, j - i); + return bytes; } + private static int getHexByteIndex(byte value) { + // ['0'-'9'] maps to [0-9] indexes + if (value >= 48 && value <= 57) + return value - 48; + // ['A'-'F'] maps to [10-15] indexes + return (value - 65) + 10; + } + @Override public Object clone() { super.clone(); diff --git a/src/test/software/amazon/event/ruler/CIDRTest.java b/src/test/software/amazon/event/ruler/CIDRTest.java index e3b9203..872f9b7 100644 --- a/src/test/software/amazon/event/ruler/CIDRTest.java +++ b/src/test/software/amazon/event/ruler/CIDRTest.java @@ -61,39 +61,40 @@ public void testToStringFailures() { @Test public void TestDigitSequence() { - List l = Range.digitSequence((byte) '4', (byte) 'C', false, false); - byte[] wanted = { '5', '6', '7', '8', '9', 'A', 'B' }; + byte[] l = Range.digitSequence((byte) '4', (byte) 'C', false, false); + byte[] wanted = {'5', '6', '7', '8', '9', 'A', 'B'}; for (int i = 0; i < wanted.length; i++) { - assertEquals(wanted[i], (byte) l.get(i)); + assertEquals(wanted[i], l[i]); } l = Range.digitSequence((byte) '4', (byte) 'C', true, false); - byte[] wanted2 = { '4', '5', '6', '7', '8', '9', 'A', 'B' }; + byte[] wanted2 = {'4', '5', '6', '7', '8', '9', 'A', 'B'}; for (int i = 0; i < wanted2.length; i++) { - assertEquals(wanted2[i], (byte) l.get(i)); + assertEquals(wanted2[i], l[i]); } l = Range.digitSequence((byte) '4', (byte) 'C', false, true); - byte[] wanted3 = { '5', '6', '7', '8', '9', 'A', 'B', 'C' }; + byte[] wanted3 = {'5', '6', '7', '8', '9', 'A', 'B', 'C'}; for (int i = 0; i < wanted3.length; i++) { - assertEquals(wanted3[i], (byte) l.get(i)); + assertEquals(wanted3[i], l[i]); } l = Range.digitSequence((byte) '4', (byte) 'C', true, true); - byte[] wanted4 = { '4', '5', '6', '7', '8', '9', 'A', 'B', 'C' }; + byte[] wanted4 = {'4', '5', '6', '7', '8', '9', 'A', 'B', 'C'}; for (int i = 0; i < wanted4.length; i++) { - assertEquals(wanted4[i], (byte) l.get(i)); + assertEquals(wanted4[i], l[i]); } - Byte F = (byte) 'F'; + byte F = (byte) 'F'; try { - List got; + byte[] got; got = Range.digitSequence((byte) 'F', (byte) 'F', false, true); - assertEquals(1, got.size()); - assertEquals(F, got.get(0)); + assertEquals(1, got.length); + assertEquals(F, got[0]); Range.digitSequence((byte) 'F', (byte) 'F', true, false); - assertEquals(1, got.size()); - assertEquals(F, got.get(0)); + assertEquals(1, got.length); + assertEquals(F, got[0]); } catch (RuntimeException e) { fail("Blew up on F-F seq"); } + } @Test From 35f3ef440029a79bdf0959022ec6651a1a6a5fa7 Mon Sep 17 00:00:00 2001 From: Rudy Alvarez Date: Sat, 10 Sep 2022 17:16:06 +0200 Subject: [PATCH 2/7] avoid Stream.of().collect(Collectors.toSet()) to create sets --- .../software/amazon/event/ruler/ByteMachine.java | 11 +++++++---- .../software/amazon/event/ruler/ByteMap.java | 6 +++--- .../software/amazon/event/ruler/Patterns.java | 16 +++++++++------- .../amazon/event/ruler/ShortcutTransition.java | 4 +--- .../amazon/event/ruler/SingleByteTransition.java | 6 ++---- 5 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/main/software/amazon/event/ruler/ByteMachine.java b/src/main/software/amazon/event/ruler/ByteMachine.java index 8aafe8a..6c01fe0 100644 --- a/src/main/software/amazon/event/ruler/ByteMachine.java +++ b/src/main/software/amazon/event/ruler/ByteMachine.java @@ -12,7 +12,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashSet; -import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; @@ -810,9 +809,13 @@ NameState findPattern(final Patterns pattern) { private NameState findAnythingButPattern(AnythingBut pattern) { - Set nextNameStates = pattern.getValues().stream(). - map(value -> findMatchPattern(getParser().parse(pattern.type(), value), pattern)). - filter(Objects::nonNull).collect(Collectors.toSet()); + Set nextNameStates = new HashSet<>(pattern.getValues().size()); + for (String value : pattern.getValues()) { + NameState matchPattern = findMatchPattern(getParser().parse(pattern.type(), value), pattern); + if (matchPattern != null) { + nextNameStates.add(matchPattern); + } + } if (!nextNameStates.isEmpty()) { assert nextNameStates.size() == 1 : "nextNameStates.size() == 1"; return nextNameStates.iterator().next(); diff --git a/src/main/software/amazon/event/ruler/ByteMap.java b/src/main/software/amazon/event/ruler/ByteMap.java index 94620bb..4d9cf16 100644 --- a/src/main/software/amazon/event/ruler/ByteMap.java +++ b/src/main/software/amazon/event/ruler/ByteMap.java @@ -4,10 +4,8 @@ import java.util.Iterator; import java.util.Map; import java.util.NavigableMap; -import java.util.Objects; import java.util.Set; import java.util.TreeMap; -import java.util.stream.Collectors; import static software.amazon.event.ruler.CompoundByteTransition.coalesce; @@ -193,7 +191,9 @@ ByteTransition getTransitionForAllBytes() { * @return All transitions contained in this map. */ Set getTransitions() { - return map.values().stream().filter(Objects::nonNull).collect(Collectors.toSet()); + Set result = new HashSet<>(map.values()); + result.remove(null); + return result; } /** diff --git a/src/main/software/amazon/event/ruler/Patterns.java b/src/main/software/amazon/event/ruler/Patterns.java index 3c066ce..5bb0d2f 100644 --- a/src/main/software/amazon/event/ruler/Patterns.java +++ b/src/main/software/amazon/event/ruler/Patterns.java @@ -1,8 +1,8 @@ package software.amazon.event.ruler; +import java.util.Collections; +import java.util.HashSet; import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; /** * The Patterns deal pre-processing of rules for the eventual matching against events. @@ -50,12 +50,11 @@ public static ValuePatterns suffixMatch(final String suffix) { } public static AnythingBut anythingButMatch(final String anythingBut) { - return new AnythingBut(Stream.of(anythingBut).collect(Collectors.toSet()), false); + return new AnythingBut(Collections.singleton(anythingBut), false); } public static AnythingBut anythingButMatch(final double anythingBut) { - return new AnythingBut(Stream.of(anythingBut).map(ComparableNumber::generate).collect(Collectors.toSet()), - true); + return new AnythingBut(Collections.singleton(ComparableNumber.generate(anythingBut)), true); } public static AnythingBut anythingButMatch(final Set anythingButs) { @@ -63,8 +62,11 @@ public static AnythingBut anythingButMatch(final Set anythingButs) { } public static AnythingBut anythingButNumberMatch(final Set anythingButs) { - return new AnythingBut(anythingButs.stream().map(ComparableNumber::generate).collect(Collectors.toSet()), - true); + Set normalizedNumbers = new HashSet<>(anythingButs.size()); + for (Double d : anythingButs) { + normalizedNumbers.add(ComparableNumber.generate(d)); + } + return new AnythingBut(normalizedNumbers, true); } public static ValuePatterns anythingButPrefix(final String prefix) { diff --git a/src/main/software/amazon/event/ruler/ShortcutTransition.java b/src/main/software/amazon/event/ruler/ShortcutTransition.java index fee8d3d..5587767 100644 --- a/src/main/software/amazon/event/ruler/ShortcutTransition.java +++ b/src/main/software/amazon/event/ruler/ShortcutTransition.java @@ -2,8 +2,6 @@ import java.util.Collections; import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; // Shortcut transition is designed mainly for exactly match by its memory consuming because the exactly match is always // in the last byte of value, while it will take a lots of memory if we build a traverse path byte by byte. @@ -81,7 +79,7 @@ SingleByteTransition setMatch(ByteMatch match) { @Override public Set getShortcuts() { - return Stream.of(this).collect(Collectors.toSet()); + return Collections.singleton(this); } @Override diff --git a/src/main/software/amazon/event/ruler/SingleByteTransition.java b/src/main/software/amazon/event/ruler/SingleByteTransition.java index e90c5d0..1751e8e 100644 --- a/src/main/software/amazon/event/ruler/SingleByteTransition.java +++ b/src/main/software/amazon/event/ruler/SingleByteTransition.java @@ -2,8 +2,6 @@ import java.util.Collections; import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; /** * This class represents a singular ByteTransition. This is in contrast to a compound ByteTransition that represents @@ -43,7 +41,7 @@ Set getMatches() { if (match == null) { return Collections.emptySet(); } - return Stream.of(match).collect(Collectors.toSet()); + return Collections.singleton(match); } /** @@ -53,7 +51,7 @@ Set getMatches() { */ @Override Set expand() { - return Stream.of(this).collect(Collectors.toSet()); + return Collections.singleton(this); } @Override From efff79a78bf9a65d5570acee2415fd585509ce05 Mon Sep 17 00:00:00 2001 From: Rudy Alvarez Date: Sat, 10 Sep 2022 17:35:56 +0200 Subject: [PATCH 3/7] get away from stepQueue make ACFinder recursive instead --- .../software/amazon/event/ruler/ACFinder.java | 11 +++------- .../software/amazon/event/ruler/ACTask.java | 20 ------------------- .../software/amazon/event/ruler/Range.java | 3 ++- 3 files changed, 5 insertions(+), 29 deletions(-) diff --git a/src/main/software/amazon/event/ruler/ACFinder.java b/src/main/software/amazon/event/ruler/ACFinder.java index 8ee495c..94daabf 100644 --- a/src/main/software/amazon/event/ruler/ACFinder.java +++ b/src/main/software/amazon/event/ruler/ACFinder.java @@ -29,19 +29,14 @@ private static List find(final ACTask task) { if (startState == null) { return Collections.emptyList(); } - moveFrom(startState, 0, task, new ArrayMembership()); - // each iteration removes a Step and adds zero or more new ones - while (task.stepsRemain()) { - tryStep(task); - } + moveFrom(startState, 0, task, new ArrayMembership()); return task.getMatchedRules(); } // remove a step from the work queue and see if there's a transition - private static void tryStep(final ACTask task) { - final ACStep step = task.nextStep(); + private static void tryStep(final ACTask task, final ACStep step) { final Field field = task.event.fields.get(step.fieldIndex); // if we can step from where we are to the new field without violating array consistency @@ -99,7 +94,7 @@ private static void moveFrom(final NameState fromState, int fieldIndex, final AC tryMustNotExistMatch(fromState, task, fieldIndex, arrayMembership); while (fieldIndex < task.fieldCount) { - task.addStep(fieldIndex++, fromState, arrayMembership); + tryStep(task, new ACStep(fieldIndex++, fromState, arrayMembership)); } } diff --git a/src/main/software/amazon/event/ruler/ACTask.java b/src/main/software/amazon/event/ruler/ACTask.java index b6d5ddf..5dae861 100644 --- a/src/main/software/amazon/event/ruler/ACTask.java +++ b/src/main/software/amazon/event/ruler/ACTask.java @@ -1,10 +1,8 @@ package software.amazon.event.ruler; -import java.util.ArrayDeque; import java.util.ArrayList; import java.util.HashSet; import java.util.List; -import java.util.Queue; /** * Represents the state of an Array-Consistent rule-finding project. @@ -18,9 +16,6 @@ class ACTask { // the rules, if we find any private final HashSet rules = new HashSet<>(); - // Steps queued up for processing - private final Queue stepQueue = new ArrayDeque<>(); - // the state machine private final GenericMachine machine; @@ -34,21 +29,6 @@ NameState startState() { return machine.getStartState(); } - ACStep nextStep() { - return stepQueue.remove(); - } - - /* - * Add a step to the queue for later consideration - */ - void addStep(final int fieldIndex, final NameState nameState, final ArrayMembership membershipSoFar) { - stepQueue.add(new ACStep(fieldIndex, nameState, membershipSoFar)); - } - - boolean stepsRemain() { - return !stepQueue.isEmpty(); - } - List getMatchedRules() { return new ArrayList<>(rules); } diff --git a/src/main/software/amazon/event/ruler/Range.java b/src/main/software/amazon/event/ruler/Range.java index 949783e..9fcc307 100644 --- a/src/main/software/amazon/event/ruler/Range.java +++ b/src/main/software/amazon/event/ruler/Range.java @@ -108,8 +108,9 @@ static byte[] digitSequence(byte first, byte last, boolean includeFirst, boolean private static int getHexByteIndex(byte value) { // ['0'-'9'] maps to [0-9] indexes - if (value >= 48 && value <= 57) + if (value >= 48 && value <= 57) { return value - 48; + } // ['A'-'F'] maps to [10-15] indexes return (value - 65) + 10; } From 5c5a35b33befd171716ca5e44a93e823600ac593 Mon Sep 17 00:00:00 2001 From: Rudy Alvarez Date: Mon, 12 Sep 2022 20:27:31 +0200 Subject: [PATCH 4/7] use a consistent style to create a set from a list --- src/main/software/amazon/event/ruler/ByteMachine.java | 3 ++- src/main/software/amazon/event/ruler/ByteMap.java | 9 +++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/software/amazon/event/ruler/ByteMachine.java b/src/main/software/amazon/event/ruler/ByteMachine.java index 6c01fe0..3d9e491 100644 --- a/src/main/software/amazon/event/ruler/ByteMachine.java +++ b/src/main/software/amazon/event/ruler/ByteMachine.java @@ -12,6 +12,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashSet; +import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; @@ -812,7 +813,7 @@ private NameState findAnythingButPattern(AnythingBut pattern) { Set nextNameStates = new HashSet<>(pattern.getValues().size()); for (String value : pattern.getValues()) { NameState matchPattern = findMatchPattern(getParser().parse(pattern.type(), value), pattern); - if (matchPattern != null) { + if (Objects.nonNull(matchPattern)) { nextNameStates.add(matchPattern); } } diff --git a/src/main/software/amazon/event/ruler/ByteMap.java b/src/main/software/amazon/event/ruler/ByteMap.java index 4d9cf16..af856bb 100644 --- a/src/main/software/amazon/event/ruler/ByteMap.java +++ b/src/main/software/amazon/event/ruler/ByteMap.java @@ -4,6 +4,7 @@ import java.util.Iterator; import java.util.Map; import java.util.NavigableMap; +import java.util.Objects; import java.util.Set; import java.util.TreeMap; @@ -191,8 +192,12 @@ ByteTransition getTransitionForAllBytes() { * @return All transitions contained in this map. */ Set getTransitions() { - Set result = new HashSet<>(map.values()); - result.remove(null); + Set result = new HashSet<>(map.values().size()); + for (ByteTransition transition : map.values()) { + if (Objects.nonNull(transition)) { + result.add(transition); + } + } return result; } From 73311cccde978e5192453fffe06560ed9b83cfb0 Mon Sep 17 00:00:00 2001 From: Rudy Alvarez Date: Mon, 12 Sep 2022 21:41:58 +0200 Subject: [PATCH 5/7] add benchmark with deep nested events, bump version minor --- pom.xml | 2 +- .../amazon/event/ruler/Benchmarks.java | 62 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1597a79..597954a 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ software.amazon.event.ruler event-ruler Event Ruler - 1.0.0 + 1.0.1 Event Ruler is a Java library that allows matching Rules to Events. An event is a list of fields, which may be given as name/value pairs or as a JSON object. A rule associates event field names with lists of possible values. There are two reasons to use Ruler: 1/ It's fast; the time it takes to match Events doesn't diff --git a/src/test/software/amazon/event/ruler/Benchmarks.java b/src/test/software/amazon/event/ruler/Benchmarks.java index 3b416b0..6afaaf6 100644 --- a/src/test/software/amazon/event/ruler/Benchmarks.java +++ b/src/test/software/amazon/event/ruler/Benchmarks.java @@ -1,5 +1,6 @@ package software.amazon.event.ruler; +import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; import java.io.BufferedReader; @@ -9,6 +10,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -484,6 +486,66 @@ public void CL2Benchmark() throws Exception { System.out.println("COMBO events/sec: " + String.format("%.1f", bm.getEPS())); } + // make sure we can handle nasty deep events + @Test + public void DeepEventBenchmark() throws Exception { + + // how many levels deep we want to go + int maxLevel = 100; + // we create a rule every time the number of events is a multiple of this number + int ruleEveryNEvents = 10; + + ObjectMapper m = new ObjectMapper(); + + Map root = new HashMap<>(); + + Map ruleRoot = new HashMap<>(); + + List deepEvents = new ArrayList<>(); + List deepRules = new ArrayList<>(); + List deepExpected = new ArrayList<>(); + + Map currentLevel = root; + Map currentRule = ruleRoot; + + for (int i = 0; i < maxLevel; i++) { + currentLevel.put("numeric" + i, i * i); + currentLevel.put("string" + i, "value" + i); + + + if (i % ruleEveryNEvents == 0) { + currentRule.put("string" + i, Collections.singletonList("value" + i)); + deepRules.add(m.writeValueAsString(ruleRoot)); + currentRule.remove("string" + i); + // all the events generated below this point will match this rule. + deepExpected.add(maxLevel - i); + } + + deepEvents.add(m.writeValueAsString(root)); + + HashMap newLevel = new HashMap<>(); + currentLevel.put("level" + i, newLevel); + currentLevel = newLevel; + + HashMap newRuleLevel = new HashMap<>(); + currentRule.put("level" + i, newRuleLevel); + currentRule = newRuleLevel; + } + + // warm up + Benchmarker bm = new Benchmarker(); + bm.addRules(deepRules.toArray(new String[0]), deepExpected.stream().mapToInt(Integer::intValue).toArray()); + bm.run(deepEvents); + + // exercise + bm = new Benchmarker(); + bm.addRules(deepRules.toArray(new String[0]), deepExpected.stream().mapToInt(Integer::intValue).toArray()); + bm.run(deepEvents); + + System.out.println("DEEP EXACT events/sec: " + String.format("%.1f", bm.getEPS())); + + } + private final List citylots2 = new ArrayList<>(); private static class Benchmarker { From 9d34ea8fcad29c8d8b1f49aae4d8fc8ccd039402 Mon Sep 17 00:00:00 2001 From: Rudy Alvarez Date: Mon, 12 Sep 2022 22:08:44 +0200 Subject: [PATCH 6/7] go back to != null instead of Objects.nonNull --- src/main/software/amazon/event/ruler/ByteMachine.java | 3 +-- src/main/software/amazon/event/ruler/ByteMap.java | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/software/amazon/event/ruler/ByteMachine.java b/src/main/software/amazon/event/ruler/ByteMachine.java index 3d9e491..6c01fe0 100644 --- a/src/main/software/amazon/event/ruler/ByteMachine.java +++ b/src/main/software/amazon/event/ruler/ByteMachine.java @@ -12,7 +12,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashSet; -import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; @@ -813,7 +812,7 @@ private NameState findAnythingButPattern(AnythingBut pattern) { Set nextNameStates = new HashSet<>(pattern.getValues().size()); for (String value : pattern.getValues()) { NameState matchPattern = findMatchPattern(getParser().parse(pattern.type(), value), pattern); - if (Objects.nonNull(matchPattern)) { + if (matchPattern != null) { nextNameStates.add(matchPattern); } } diff --git a/src/main/software/amazon/event/ruler/ByteMap.java b/src/main/software/amazon/event/ruler/ByteMap.java index af856bb..5b86439 100644 --- a/src/main/software/amazon/event/ruler/ByteMap.java +++ b/src/main/software/amazon/event/ruler/ByteMap.java @@ -4,7 +4,6 @@ import java.util.Iterator; import java.util.Map; import java.util.NavigableMap; -import java.util.Objects; import java.util.Set; import java.util.TreeMap; @@ -194,7 +193,7 @@ ByteTransition getTransitionForAllBytes() { Set getTransitions() { Set result = new HashSet<>(map.values().size()); for (ByteTransition transition : map.values()) { - if (Objects.nonNull(transition)) { + if (transition != null) { result.add(transition); } } From ab3cb909a54de6c3536802f8bbaff8e6d3b5bbcc Mon Sep 17 00:00:00 2001 From: Rudy Alvarez Date: Tue, 13 Sep 2022 01:15:39 +0200 Subject: [PATCH 7/7] reduce magic constant usage on hex digit sequence generation --- src/main/software/amazon/event/ruler/Range.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/software/amazon/event/ruler/Range.java b/src/main/software/amazon/event/ruler/Range.java index 9fcc307..9a79a86 100644 --- a/src/main/software/amazon/event/ruler/Range.java +++ b/src/main/software/amazon/event/ruler/Range.java @@ -9,7 +9,6 @@ * implementation, the number of digits in the top and bottom of the range is the same. */ public class Range extends Patterns { - /** * Bottom and top of the range. openBottom true means we're looking for > bottom, false means >= * Similarly, openTop true means we're looking for < top, false means <= top. @@ -21,6 +20,8 @@ public class Range extends Patterns { final boolean isCIDR; + private static final int HEX_DIGIT_A_DECIMAL_VALUE = 10; + private Range(final double bottom, final boolean openBottom, final double top, final boolean openTop) { super(MatchType.NUMERIC_RANGE); if (bottom >= top) { @@ -108,11 +109,11 @@ static byte[] digitSequence(byte first, byte last, boolean includeFirst, boolean private static int getHexByteIndex(byte value) { // ['0'-'9'] maps to [0-9] indexes - if (value >= 48 && value <= 57) { - return value - 48; + if (value >= '0' && value <= '9') { + return value - '0'; } // ['A'-'F'] maps to [10-15] indexes - return (value - 65) + 10; + return (value - 'A') + HEX_DIGIT_A_DECIMAL_VALUE; } @Override