Skip to content

Commit

Permalink
Merge pull request #9612 from neo-technology/neo4j-values-crusade
Browse files Browse the repository at this point in the history
Neo4j values, round 42
  • Loading branch information
jjaderberg authored Sep 25, 2024
2 parents 983334f + ddfb0ba commit a0e2ba7
Show file tree
Hide file tree
Showing 58 changed files with 2,858 additions and 350 deletions.
1 change: 1 addition & 0 deletions algo/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ dependencies {
implementation project(':core')
implementation project(':core-utils')
implementation project(':core-write')
implementation project(':gds-values')
implementation project(':graph-schema-api')
implementation project(':licensing')
implementation project(':logging')
Expand Down
1 change: 1 addition & 0 deletions core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ dependencies {
implementation project(':annotations')
implementation project(':config-api')
implementation project(':core-utils')
implementation project(':gds-values')
implementation project(':licensing')
implementation project(':logging')
implementation project(':graph-schema-api')
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [http://neo4j.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.neo4j.gds.core.loading;

import org.jetbrains.annotations.NotNull;
import org.neo4j.gds.values.Array;
import org.neo4j.gds.values.GdsNoValue;
import org.neo4j.gds.values.GdsValue;
import org.neo4j.gds.values.primitive.PrimitiveValues;
import org.neo4j.values.AnyValue;
import org.neo4j.values.SequenceValue;
import org.neo4j.values.storable.ArrayValue;
import org.neo4j.values.storable.IntegralValue;
import org.neo4j.values.storable.NoValue;
import org.neo4j.values.storable.Value;
import org.neo4j.values.storable.ValueGroup;
import org.neo4j.values.virtual.ListValue;

import static org.neo4j.gds.utils.StringFormatting.formatWithLocale;

public final class GdsNeo4jValueConverter {

public static GdsValue toValue(@NotNull AnyValue value) {
if (value == NoValue.NO_VALUE) {
return GdsNoValue.NO_VALUE;
}
if (value.isSequenceValue()) { // ArrayValue or ListValue
return convertSequenceValueOrFail((SequenceValue) value);
}
if (value instanceof Value storableValue && storableValue.valueGroup() == ValueGroup.NUMBER) {
if (storableValue instanceof org.neo4j.values.storable.FloatValue floatValue) {
return PrimitiveValues.floatingPointValue(floatValue.floatValue());
} else if (storableValue instanceof org.neo4j.values.storable.DoubleValue doubleValue) {
return PrimitiveValues.floatingPointValue(doubleValue.doubleValue());
} else if (storableValue instanceof IntegralValue integralValue) {
return PrimitiveValues.longValue(integralValue.longValue());
}
}
throw new IllegalArgumentException(formatWithLocale(
"Unsupported conversion to GDS Value from Neo4j Value with type `%s`.",
value.getTypeName()
));
}

private static GdsValue convertSequenceValueOrFail(SequenceValue value) {
if (value instanceof ListValue listValue) {
return convertListValueOrFail(listValue);
} else if (value instanceof ArrayValue arrayValue) {
return convertArrayValueOrFail(arrayValue);
} else {
throw failOnBadInput(value);
}
}

@NotNull
private static Array convertListValueOrFail(ListValue listValue) {
if (listValue.isEmpty()) {
// encode as long array
return PrimitiveValues.EMPTY_LONG_ARRAY;
}
try {
return convertArrayValueOrFail(listValue.toStorableArray());
} catch (RuntimeException e) {
throw failOnBadInput(listValue);
}
}

@NotNull
private static Array convertArrayValueOrFail(ArrayValue array) {
if (array.valueGroup() != ValueGroup.NUMBER_ARRAY) {
throw failOnBadInput(array);
}
if (array.isEmpty()) {
return PrimitiveValues.EMPTY_LONG_ARRAY;
}
var arrayCopy = array.asObjectCopy();
if (arrayCopy instanceof long[]) {
return PrimitiveValues.longArray((long[]) arrayCopy);
} else if (arrayCopy instanceof double[]) {
return PrimitiveValues.doubleArray((double[]) arrayCopy);
} else {
throw failOnBadInput(array);
}
}

private static IllegalArgumentException failOnBadInput(SequenceValue badInput) {
return new IllegalArgumentException(
formatWithLocale(
"Unsupported conversion to GDS Value from Neo4j Value `%s`.",
badInput
)
);
}

private GdsNeo4jValueConverter() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,10 @@
import org.neo4j.gds.api.PropertyState;
import org.neo4j.gds.api.RelationshipProperty;
import org.neo4j.gds.api.RelationshipPropertyStore;
import org.neo4j.gds.api.ValueTypes;
import org.neo4j.gds.api.nodeproperties.ValueType;
import org.neo4j.gds.api.schema.Direction;
import org.neo4j.gds.api.schema.MutableRelationshipSchema;
import org.neo4j.gds.api.schema.MutableRelationshipSchemaEntry;
import org.neo4j.values.storable.NumberType;

import java.util.Collection;
import java.util.HashMap;
Expand Down Expand Up @@ -157,7 +155,7 @@ private static RelationshipPropertyStore constructRelationshipPropertyStore(
),
propertyMapping.defaultValue().isUserDefined()
? propertyMapping.defaultValue()
: ValueTypes.fromNumberType(NumberType.FLOATING_POINT).fallbackValue(),
: ValueType.DOUBLE.fallbackValue(),
propertyMapping.aggregation()
)
);
Expand Down
140 changes: 0 additions & 140 deletions core/src/main/java/org/neo4j/gds/core/loading/ValueConverter.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,8 @@
import org.neo4j.gds.core.loading.nodeproperties.NodePropertiesFromStoreBuilder;
import org.neo4j.gds.core.utils.paged.HugeAtomicBitSet;
import org.neo4j.gds.core.utils.paged.HugeAtomicGrowingBitSet;
import org.neo4j.values.storable.Value;
import org.neo4j.values.storable.Values;
import org.neo4j.gds.values.GdsValue;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.concurrent.atomic.LongAdder;
Expand Down Expand Up @@ -148,33 +146,19 @@ public void addNode(long originalId, NodeLabel nodeLabel) {
this.addNode(originalId, NodeLabelTokens.ofNodeLabel(nodeLabel));
}

public void addNodeWithPropertiesAsObjects(long originalId, Map<String, Object> propertiesAsObjects) {
this.addNodeWithPropertiesAsObjects(originalId, propertiesAsObjects, NodeLabelTokens.empty());
}

public void addNodeWithPropertiesAsObjects(long originalId, Map<String, Object> propertiesAsObjects, NodeLabel... nodeLabels) {
this.addNodeWithPropertiesAsObjects(originalId, propertiesAsObjects, NodeLabelTokens.ofNodeLabels(nodeLabels));
}

public void addNodeWithPropertiesAsObjects(long originalId, Map<String, Object> propertiesAsObjects, NodeLabelToken nodeLabels) {
var properties = new HashMap<String, Value>(propertiesAsObjects.size());
propertiesAsObjects.forEach((key, value) -> properties.put(key, Values.of(value)));
this.addNode(originalId, properties, nodeLabels);
}

public void addNode(long originalId, Map<String, Value> properties) {
public void addNode(long originalId, Map<String, GdsValue> properties) {
this.addNode(originalId, properties, NodeLabelTokens.empty());
}

public void addNode(long originalId, Map<String, Value> properties, NodeLabelToken nodeLabels) {
public void addNode(long originalId, Map<String, GdsValue> properties, NodeLabelToken nodeLabels) {
this.addNode(originalId, nodeLabels, PropertyValues.of(properties));
}

public void addNode(long originalId, Map<String, Value> properties, NodeLabel... nodeLabels) {
public void addNode(long originalId, Map<String, GdsValue> properties, NodeLabel... nodeLabels) {
this.addNode(originalId, properties, NodeLabelTokens.ofNodeLabels(nodeLabels));
}

public void addNode(long originalId, Map<String, Value> properties, NodeLabel nodeLabel) {
public void addNode(long originalId, Map<String, GdsValue> properties, NodeLabel nodeLabel) {
this.addNode(originalId, properties, NodeLabelTokens.ofNodeLabel(nodeLabel));
}

Expand Down
Loading

0 comments on commit a0e2ba7

Please sign in to comment.