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

Load encoded values from disk #2542

Merged
merged 13 commits into from Mar 22, 2022
Expand Up @@ -24,9 +24,12 @@
* number of bits that determine the maximum value.
*/
public final class DecimalEncodedValueImpl extends IntEncodedValueImpl implements DecimalEncodedValue {
private final double factor;
private final boolean defaultIsInfinity;
private final boolean useMaximumAsInfinity;
private double factor;
private boolean defaultIsInfinity;
private boolean useMaximumAsInfinity;

DecimalEncodedValueImpl() {
}

/**
* @see #DecimalEncodedValueImpl(String, int, double, double, boolean, boolean, boolean, boolean)
Expand Down
Expand Up @@ -17,22 +17,33 @@
*/
package com.graphhopper.routing.ev;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.util.StdConverter;
import com.graphhopper.storage.IntsRef;

import java.util.Arrays;

/**
* This class allows to store distinct values via an enum. I.e. it stores just the indices
*/
@JsonDeserialize(converter = EnumEncodedValue.EnumConstantsSetter.class)
public final class EnumEncodedValue<E extends Enum> extends IntEncodedValueImpl {
private final E[] arr;
public Class<E> enumType;
@JsonIgnore
public E[] arr;

EnumEncodedValue() {
// for jackson
}

public EnumEncodedValue(String name, Class<E> enumType) {
this(name, enumType, false);
}

public EnumEncodedValue(String name, Class<E> enumType, boolean storeTwoDirections) {
super(name, 32 - Integer.numberOfLeadingZeros(enumType.getEnumConstants().length - 1), storeTwoDirections);
this.enumType = enumType;
arr = enumType.getEnumConstants();
}

Expand Down Expand Up @@ -61,4 +72,12 @@ public boolean equals(Object o) {
public int getVersion() {
return 31 * super.getVersion() + staticHashCode(arr);
}

public static class EnumConstantsSetter<T extends Enum> extends StdConverter<EnumEncodedValue<T>, EnumEncodedValue<T>> {
@Override
public EnumEncodedValue<T> convert(EnumEncodedValue<T> value) {
value.arr = value.enumType.getEnumConstants();
return value;
}
}
}
Expand Up @@ -36,23 +36,27 @@
*/
public class IntEncodedValueImpl implements IntEncodedValue {

private final String name;
private String name;

/**
* There are multiple int values possible per edge. Here we specify the index into this integer array.
*/
private int fwdDataIndex;
private int bwdDataIndex;
private final boolean storeTwoDirections;
final int bits;
final boolean negateReverseDirection;
final int minValue;
final int maxValue;
private boolean storeTwoDirections;
int bits;
boolean negateReverseDirection;
int minValue;
int maxValue;
int fwdShift = -1;
int bwdShift = -1;
int fwdMask;
int bwdMask;

IntEncodedValueImpl() {
// for jackson
}

/**
* @see #IntEncodedValueImpl(String, int, int, boolean, boolean)
*/
Expand Down
Expand Up @@ -23,6 +23,10 @@
* This class implements a simple boolean storage via an UnsignedIntEncodedValue with 1 bit.
*/
public final class SimpleBooleanEncodedValue extends IntEncodedValueImpl implements BooleanEncodedValue {
private final String type = "simple_boolean";

SimpleBooleanEncodedValue() {
}

public SimpleBooleanEncodedValue(String name) {
this(name, false);
Expand Down
@@ -1,8 +1,16 @@
package com.graphhopper.routing.ev;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.graphhopper.storage.IntsRef;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class EnumEncodedValueTest {
Expand Down Expand Up @@ -32,4 +40,36 @@ public void testSize() {
assertEquals(4, 32 - Integer.numberOfLeadingZeros(16 - 1));
assertEquals(5, 32 - Integer.numberOfLeadingZeros(17 - 1));
}

@Test
public void serializationAndDeserialization() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);

List<EncodedValue> encodedValues = new ArrayList<>();
// add enum, int, decimal and boolean encoded values
encodedValues.add(new EnumEncodedValue<>(RoadClass.KEY, RoadClass.class));
encodedValues.add(Lanes.create());
encodedValues.add(MaxWidth.create());
encodedValues.add(GetOffBike.create());

String serializedEVs = mapper.writeValueAsString(encodedValues);
System.out.println(serializedEVs);

List<EncodedValue> deserializedEVs = new ArrayList<>();
JsonNode jsonNode = mapper.readTree(serializedEVs);
for (JsonNode jsonEV : jsonNode) {
if (jsonEV.has("enumType"))
deserializedEVs.add(mapper.treeToValue(jsonEV, EnumEncodedValue.class));
else if (jsonEV.has("factor"))
deserializedEVs.add(mapper.treeToValue(jsonEV, DecimalEncodedValueImpl.class));
else if (jsonEV.has("type") && "simple_boolean".equals(jsonEV.get("type").asText()))
deserializedEVs.add(mapper.treeToValue(jsonEV, SimpleBooleanEncodedValue.class));
else
deserializedEVs.add(mapper.treeToValue(jsonEV, IntEncodedValueImpl.class));
}
System.out.println(deserializedEVs);
easbar marked this conversation as resolved.
Show resolved Hide resolved
}

}