Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speeding up Array Consistency Check by using sorted int-int AVL Tree #55

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,7 @@ Events are processed at over 220K/second except for:
- wildcard matches, which are processed at over 170K/second.
- anything-but matches, which are processed at over 150K/second.
- numeric matches, which are processed at over 120K/second.
- complex array matches, which are processed at over 2.5K/second.
- complex array matches, which are processed at over 5K/second.

### Suggestions for better performance

Expand Down
7 changes: 6 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<properties>
<jdk.version>1.8</jdk.version>
<jackson.version>2.14.0</jackson.version>
<fastutil.version>8.5.9</fastutil.version>
<jsr.version>3.0.2</jsr.version>
<junit.version>4.13.2</junit.version>
<compiler.plugin.version>3.10.1</compiler.plugin.version>
Expand Down Expand Up @@ -98,6 +99,11 @@
<scope>test</scope>
</dependency>

<dependency>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a standard about adopting dependencies? I remember doing quite a bit of work inside AWS to convince myself/others that a dependency was acceptable. Not saying anything about this one, never heard of it before, but have we done any investigation?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have a standard today. Created #57 for it.

On this library, I looked up this library based on this comment on the existing IntIntMap class https://github.com/aws/event-ruler/blob/main/src/main/software/amazon/event/ruler/IntIntMap.java#L12. The library was in active development and had good documentation. I see it used in some performance sensitive libraries so I gave it a try for Ruler.

<groupId>it.unimi.dsi</groupId>
<artifactId>fastutil-core</artifactId>
<version>${fastutil.version}</version>
</dependency>
</dependencies>

<build>
Expand Down Expand Up @@ -147,7 +153,6 @@
<version>${checkstyle.plugin.version}</version>
<configuration>
<configLocation>${basedir}/config/checkstyle/checkstyle.xml</configLocation>
<encoding>${project.build.sourceEncoding}</encoding>
<consoleOutput>true</consoleOutput>
<failsOnError>false</failsOnError>
<linkXRef>false</linkXRef>
Expand Down
33 changes: 22 additions & 11 deletions src/main/software/amazon/event/ruler/ArrayMembership.java
Original file line number Diff line number Diff line change
@@ -1,28 +1,39 @@
package software.amazon.event.ruler;

import it.unimi.dsi.fastutil.ints.Int2IntAVLTreeMap;
import it.unimi.dsi.fastutil.ints.Int2IntMap;

/**
* Represents which JSON arrays within an Event structure a particular field appears within, and at which position.
* The arrays are identified using integers.
*/
class ArrayMembership {
private static final IntIntMap EMPTY = new IntIntMap();
private static final Int2IntAVLTreeMap EMPTY = createNewIntIntMap();
public static final int NO_VALUE = -1; // Keys and values may only be positive.

private IntIntMap membership;
private final Int2IntAVLTreeMap membership;

ArrayMembership() {
membership = new IntIntMap();
this.membership = createNewIntIntMap();
}

ArrayMembership(final ArrayMembership membership) {
if (membership.size() == 0) {
this.membership = EMPTY;
} else {
this.membership = (IntIntMap) membership.membership.clone();
this.membership = createNewIntIntMap();
this.membership.putAll(membership.membership);
}
}

private static Int2IntAVLTreeMap createNewIntIntMap() {
final Int2IntAVLTreeMap membership = new Int2IntAVLTreeMap();
membership.defaultReturnValue(NO_VALUE);
return membership;
}

void putMembership(int array, int index) {
if (index == IntIntMap.NO_VALUE) {
if (index == NO_VALUE) {
membership.remove(array);
} else {
membership.put(array, index);
Expand All @@ -44,8 +55,8 @@ private int size() {
// for debugging
public String toString() {
StringBuilder sb = new StringBuilder();
for (IntIntMap.Entry entry : membership.entries()) {
sb.append(entry.getKey()).append('[').append(entry.getValue()).append("] ");
for (Int2IntMap.Entry entry : membership.int2IntEntrySet()) {
sb.append(entry.getIntKey()).append('[').append(entry.getIntValue()).append("] ");
}
return sb.toString();
}
Expand All @@ -70,12 +81,12 @@ static ArrayMembership checkArrayConsistency(final ArrayMembership membershipSoF

// any change will come from memberships in the new field we're investigating. For each of its memberships
ArrayMembership newMembership = null;
for (IntIntMap.Entry arrayEntry : fieldMembership.membership.entries()) {
final int array = arrayEntry.getKey();
final int indexInThisArrayOfThisField = arrayEntry.getValue();
for (Int2IntMap.Entry arrayEntry : fieldMembership.membership.int2IntEntrySet()) {
final int array = arrayEntry.getIntKey();
final int indexInThisArrayOfThisField = arrayEntry.getIntValue();
final int indexInThisArrayPreviouslyAppearingInMatch = membershipSoFar.getMembership(array);

if (indexInThisArrayPreviouslyAppearingInMatch == IntIntMap.NO_VALUE) {
if (indexInThisArrayPreviouslyAppearingInMatch == NO_VALUE) {

// if there's no membership so far, this is an acceptable delta. Update the new memberships, first
// creating it if necessary
Expand Down
Loading