Skip to content

Commit

Permalink
Merge pull request #403 from parsingdata/#402_hash_improvements
Browse files Browse the repository at this point in the history
#402: Hash calculation improvements
  • Loading branch information
mvanaken authored Nov 24, 2023
2 parents 16f7df2 + 4a3e8d8 commit f90d79f
Show file tree
Hide file tree
Showing 55 changed files with 279 additions and 97 deletions.
26 changes: 26 additions & 0 deletions core/src/main/java/io/parsingdata/metal/ImmutableObject.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package io.parsingdata.metal;

/**
* When objects are immutable, that means their hash code will stay the same the moment it is created.
* It will improve performance if these objects cache their hash code.
* <p>
* This is a lazy implementation, instead of calculating the hash once within the constructor, to avoid
* performance decrease during parsing. In most implementations the hash code is not actually used/needed.
*/
public abstract class ImmutableObject {

private Integer hashCode;

public abstract int immutableHashCode();

@Override
public abstract boolean equals(final Object obj);

@Override
public int hashCode() {
if (hashCode == null) {
hashCode = immutableHashCode();
}
return hashCode;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public boolean equals(final Object obj) {
}

@Override
public int hashCode() {
public int immutableHashCode() {
return Objects.hash(getClass(), input);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public boolean equals(final Object obj) {
}

@Override
public int hashCode() {
public int immutableHashCode() {
return Objects.hash(getClass(), values, length);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public boolean equals(final Object obj) {
}

@Override
public int hashCode() {
public int immutableHashCode() {
return Objects.hash(getClass(), Arrays.hashCode(data));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public boolean equals(Object obj) {
}

@Override
public int hashCode() {
public int immutableHashCode() {
return Objects.hash(getClass(), dataExpression, index, parseState, encoding);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@

import java.util.Objects;

import io.parsingdata.metal.ImmutableObject;
import io.parsingdata.metal.Trampoline;
import io.parsingdata.metal.Util;

public class ImmutableList<T> {
public class ImmutableList<T> extends ImmutableObject {

public final T head;
public final ImmutableList<T> tail;
Expand Down Expand Up @@ -104,7 +105,7 @@ public boolean equals(final Object obj) {
}

@Override
public int hashCode() {
public int immutableHashCode() {
return Objects.hash(getClass(), head, tail);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@

import java.util.Objects;

import io.parsingdata.metal.ImmutableObject;
import io.parsingdata.metal.Util;

public class ImmutablePair<L, R> {
public class ImmutablePair<L, R> extends ImmutableObject {

public final L left;
public final R right;
Expand All @@ -45,7 +46,7 @@ public boolean equals(final Object obj) {
}

@Override
public int hashCode() {
public int immutableHashCode() {
return Objects.hash(getClass(), left, right);
}

Expand Down
5 changes: 3 additions & 2 deletions core/src/main/java/io/parsingdata/metal/data/ParseGraph.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@
import java.util.Objects;
import java.util.Optional;

import io.parsingdata.metal.ImmutableObject;
import io.parsingdata.metal.Trampoline;
import io.parsingdata.metal.Util;
import io.parsingdata.metal.token.Token;

public class ParseGraph implements ParseItem {
public class ParseGraph extends ImmutableObject implements ParseItem {

public final ParseItem head;
public final ParseGraph tail;
Expand Down Expand Up @@ -143,7 +144,7 @@ public boolean equals(final Object obj) {
}

@Override
public int hashCode() {
public int immutableHashCode() {
return Objects.hash(getClass(), head, tail, branched, definition);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@
import java.util.Objects;
import java.util.Optional;

import io.parsingdata.metal.ImmutableObject;
import io.parsingdata.metal.Util;
import io.parsingdata.metal.token.Token;

public class ParseReference implements ParseItem {
public class ParseReference extends ImmutableObject implements ParseItem {

public final BigInteger location;
public final Source source;
Expand Down Expand Up @@ -61,7 +62,7 @@ public boolean equals(final Object obj) {
}

@Override
public int hashCode() {
public int immutableHashCode() {
return Objects.hash(getClass(), location, source, definition);
}

Expand Down
5 changes: 3 additions & 2 deletions core/src/main/java/io/parsingdata/metal/data/ParseState.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@
import java.util.Objects;
import java.util.Optional;

import io.parsingdata.metal.ImmutableObject;
import io.parsingdata.metal.Util;
import io.parsingdata.metal.token.Token;

public class ParseState {
public class ParseState extends ImmutableObject {

public final ParseGraph order;
public final ParseValueCache cache;
Expand Down Expand Up @@ -120,7 +121,7 @@ public boolean equals(final Object obj) {
}

@Override
public int hashCode() {
public int immutableHashCode() {
return Objects.hash(getClass(), order, cache, offset, source, iterations, references);
}

Expand Down
4 changes: 2 additions & 2 deletions core/src/main/java/io/parsingdata/metal/data/ParseValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ public boolean equals(final Object obj) {
}

@Override
public int hashCode() {
return Objects.hash(super.hashCode(), name, definition);
public int immutableHashCode() {
return Objects.hash(super.immutableHashCode(), name, definition);
}

}
5 changes: 3 additions & 2 deletions core/src/main/java/io/parsingdata/metal/data/Slice.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@
import java.util.Objects;
import java.util.Optional;

import io.parsingdata.metal.ImmutableObject;
import io.parsingdata.metal.Util;

public class Slice {
public class Slice extends ImmutableObject {

public final Source source;
public final BigInteger offset;
Expand Down Expand Up @@ -75,7 +76,7 @@ public boolean equals(final Object obj) {
}

@Override
public int hashCode() {
public int immutableHashCode() {
return Objects.hash(getClass(), source, offset, length);
}

Expand Down
4 changes: 3 additions & 1 deletion core/src/main/java/io/parsingdata/metal/data/Source.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@

import java.math.BigInteger;

public abstract class Source {
import io.parsingdata.metal.ImmutableObject;

public abstract class Source extends ImmutableObject {

protected abstract byte[] getData(BigInteger offset, BigInteger length);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@
import java.nio.charset.StandardCharsets;
import java.util.Objects;

import io.parsingdata.metal.ImmutableObject;
import io.parsingdata.metal.Util;

public class Encoding {
public class Encoding extends ImmutableObject {

public static final Sign DEFAULT_SIGN = Sign.UNSIGNED;
public static final Charset DEFAULT_CHARSET = StandardCharsets.US_ASCII;
Expand Down Expand Up @@ -68,7 +69,7 @@ public boolean equals(final Object obj) {
}

@Override
public int hashCode() {
public int immutableHashCode() {
return Objects.hash(getClass(), sign, charset, byteOrder);
}

Expand Down
5 changes: 3 additions & 2 deletions core/src/main/java/io/parsingdata/metal/expression/True.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package io.parsingdata.metal.expression;

import io.parsingdata.metal.ImmutableObject;
import io.parsingdata.metal.Util;
import io.parsingdata.metal.data.ParseState;
import io.parsingdata.metal.encoding.Encoding;
Expand All @@ -24,7 +25,7 @@
* An {@link Expression} that always evaluates to <code>true</code>. Generally
* used as default on undefined predicates.
*/
public class True implements Expression {
public class True extends ImmutableObject implements Expression {

@Override
public boolean eval(final ParseState parseState, final Encoding encoding) {
Expand All @@ -42,7 +43,7 @@ public boolean equals(final Object obj) {
}

@Override
public int hashCode() {
public int immutableHashCode() {
return getClass().hashCode();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

import java.util.Objects;

import io.parsingdata.metal.ImmutableObject;
import io.parsingdata.metal.Trampoline;
import io.parsingdata.metal.Util;
import io.parsingdata.metal.data.ImmutableList;
Expand All @@ -44,7 +45,7 @@
* not evaluated and the output value is substituted with a list containing
* only the {@link Value} most recently added to the {@link ParseState}.
*/
public abstract class ComparisonExpression implements Expression {
public abstract class ComparisonExpression extends ImmutableObject implements Expression {

public final ValueExpression value;
public final ValueExpression predicate;
Expand Down Expand Up @@ -97,7 +98,7 @@ public boolean equals(final Object obj) {
}

@Override
public int hashCode() {
public int immutableHashCode() {
return Objects.hash(getClass(), value, predicate);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import java.util.Objects;

import io.parsingdata.metal.ImmutableObject;
import io.parsingdata.metal.Util;
import io.parsingdata.metal.expression.Expression;

Expand All @@ -31,7 +32,7 @@
* their results combined using the operator the concrete expression
* implements and then returned.
*/
public abstract class BinaryLogicalExpression implements LogicalExpression {
public abstract class BinaryLogicalExpression extends ImmutableObject implements LogicalExpression {

public final Expression left;
public final Expression right;
Expand All @@ -54,7 +55,7 @@ public boolean equals(final Object obj) {
}

@Override
public int hashCode() {
public int immutableHashCode() {
return Objects.hash(getClass(), left, right);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import java.util.Objects;

import io.parsingdata.metal.ImmutableObject;
import io.parsingdata.metal.Util;
import io.parsingdata.metal.expression.Expression;

Expand All @@ -31,7 +32,7 @@
* {@link Expression}). The <code>operand</code> is evaluated, the concrete
* implementation's operator is applied to the result and returned.
*/
public abstract class UnaryLogicalExpression implements LogicalExpression {
public abstract class UnaryLogicalExpression extends ImmutableObject implements LogicalExpression {

public final Expression operand;

Expand All @@ -51,7 +52,7 @@ public boolean equals(final Object obj) {
}

@Override
public int hashCode() {
public int immutableHashCode() {
return Objects.hash(getClass(), operand);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.Objects;
import java.util.Optional;

import io.parsingdata.metal.ImmutableObject;
import io.parsingdata.metal.Trampoline;
import io.parsingdata.metal.Util;
import io.parsingdata.metal.data.ImmutableList;
Expand Down Expand Up @@ -52,7 +53,7 @@
*
* @see UnaryValueExpression
*/
public abstract class BinaryValueExpression implements ValueExpression {
public abstract class BinaryValueExpression extends ImmutableObject implements ValueExpression {

public final ValueExpression left;
public final ValueExpression right;
Expand Down Expand Up @@ -108,7 +109,7 @@ public boolean equals(final Object obj) {
}

@Override
public int hashCode() {
public int immutableHashCode() {
return Objects.hash(getClass(), left, right);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.math.BigInteger;
import java.util.Objects;

import io.parsingdata.metal.ImmutableObject;
import io.parsingdata.metal.Trampoline;
import io.parsingdata.metal.Util;
import io.parsingdata.metal.data.ImmutableList;
Expand All @@ -47,7 +48,7 @@
* 2 and 3 bytes respectively, the Bytes expression turns this into a list of
* 5 values, representing the individual bytes of the original results.
*/
public class Bytes implements ValueExpression {
public class Bytes extends ImmutableObject implements ValueExpression {

public final ValueExpression operand;

Expand Down Expand Up @@ -89,7 +90,7 @@ public boolean equals(final Object obj) {
}

@Override
public int hashCode() {
public int immutableHashCode() {
return Objects.hash(getClass(), operand);
}

Expand Down
Loading

0 comments on commit f90d79f

Please sign in to comment.