Skip to content

Commit

Permalink
Add Extended versions of common classes removed from common
Browse files Browse the repository at this point in the history
  • Loading branch information
gem-neo4j committed Dec 16, 2024
1 parent d453d5e commit ac6707d
Show file tree
Hide file tree
Showing 87 changed files with 5,601 additions and 192 deletions.
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[submodule "apoc-core"]
path = apoc-core
url = https://github.com/neo4j/apoc
branch = dev
branch = dev_reduce_common_reliance
5 changes: 3 additions & 2 deletions extended/src/main/java/apoc/algo/PathFindingExtended.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
import org.neo4j.procedure.Procedure;

import java.util.stream.Stream;
import static apoc.algo.PathFindingUtils.buildPathExpander;

import static apoc.algo.PathFindingUtilsExtended.buildPathExpander;

@Extended
public class PathFindingExtended {
Expand All @@ -41,7 +42,7 @@ public Stream<WeightedPathResult> aStarWithPoint(
new BasicEvaluationContext(tx, db),
buildPathExpander(relTypesAndDirs),
CommonEvaluators.doubleCostEvaluator(weightPropertyName),
new PathFindingUtils.GeoEstimateEvaluatorPointCustom(pointPropertyName));
new PathFindingUtilsExtended.GeoEstimateEvaluatorPointCustom(pointPropertyName));
return WeightedPathResult.streamWeightedPathResult(startNode, endNode, algo);
}

Expand Down
94 changes: 94 additions & 0 deletions extended/src/main/java/apoc/algo/PathFindingUtilsExtended.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [http://neo4j.com]
*
* This file is part of Neo4j.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package apoc.algo;

import apoc.path.RelationshipTypeAndDirectionsExtended;
import org.apache.commons.lang3.tuple.Pair;
import org.neo4j.graphalgo.EstimateEvaluator;
import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.PathExpander;
import org.neo4j.graphdb.PathExpanderBuilder;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.values.storable.PointValue;

public class PathFindingUtilsExtended {
public static class GeoEstimateEvaluatorPointCustom implements EstimateEvaluator<Double> {
// -- from org.neo4j.graphalgo.impl.util.GeoEstimateEvaluator
private static final double EARTH_RADIUS = 6371 * 1000; // Meters
private Node cachedGoal;
private final String pointPropertyKey;
private double[] cachedGoalCoordinates;

public GeoEstimateEvaluatorPointCustom(String pointPropertyKey) {
this.pointPropertyKey = pointPropertyKey;
}

@Override
public Double getCost(Node node, Node goal) {
double[] nodeCoordinates = getCoordinates(node);
if (cachedGoal == null || !cachedGoal.equals(goal)) {
cachedGoalCoordinates = getCoordinates(goal);
cachedGoal = goal;
}
return distance(nodeCoordinates[0], nodeCoordinates[1], cachedGoalCoordinates[0], cachedGoalCoordinates[1]);
}

private static double distance(double latitude1, double longitude1, double latitude2, double longitude2) {
latitude1 = Math.toRadians(latitude1);
longitude1 = Math.toRadians(longitude1);
latitude2 = Math.toRadians(latitude2);
longitude2 = Math.toRadians(longitude2);
double cLa1 = Math.cos(latitude1);
double xA = EARTH_RADIUS * cLa1 * Math.cos(longitude1);
double yA = EARTH_RADIUS * cLa1 * Math.sin(longitude1);
double zA = EARTH_RADIUS * Math.sin(latitude1);
double cLa2 = Math.cos(latitude2);
double xB = EARTH_RADIUS * cLa2 * Math.cos(longitude2);
double yB = EARTH_RADIUS * cLa2 * Math.sin(longitude2);
double zB = EARTH_RADIUS * Math.sin(latitude2);
return Math.sqrt((xA - xB) * (xA - xB) + (yA - yB) * (yA - yB) + (zA - zB) * (zA - zB));
}
// -- end from org.neo4j.graphalgo.impl.util.GeoEstimateEvaluator

private double[] getCoordinates(Node node) {
return ((PointValue) node.getProperty(pointPropertyKey)).coordinate();
}
}

public static PathExpander<Double> buildPathExpander(String relationshipsAndDirections) {
PathExpanderBuilder builder = PathExpanderBuilder.empty();
for (Pair<RelationshipType, Direction> pair : RelationshipTypeAndDirectionsExtended.parse(relationshipsAndDirections)) {
if (pair.getLeft() == null) {
if (pair.getRight() == null) {
builder = PathExpanderBuilder.allTypesAndDirections();
} else {
builder = PathExpanderBuilder.allTypes(pair.getRight());
}
} else {
if (pair.getRight() == null) {
builder = builder.add(pair.getLeft());
} else {
builder = builder.add(pair.getLeft(), pair.getRight());
}
}
}
return builder.build();
}
}
4 changes: 2 additions & 2 deletions extended/src/main/java/apoc/coll/CollExtended.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package apoc.coll;

import apoc.Extended;
import apoc.util.CollectionUtils;
import apoc.util.CollectionUtilsExtended;
import org.neo4j.procedure.Description;
import org.neo4j.procedure.Name;
import org.neo4j.procedure.UserFunction;
Expand All @@ -17,7 +17,7 @@ public class CollExtended {
@UserFunction
@Description("apoc.coll.avgDuration([duration('P2DT3H'), duration('PT1H45S'), ...]) - returns the average of a list of duration values")
public DurationValue avgDuration(@Name("durations") List<DurationValue> list) {
if (CollectionUtils.isEmpty(list)) return null;
if (CollectionUtilsExtended.isEmpty(list)) return null;

long count = 0;

Expand Down
139 changes: 139 additions & 0 deletions extended/src/main/java/apoc/coll/SetBackedListExtended.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [http://neo4j.com]
*
* This file is part of Neo4j.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package apoc.coll;

import java.util.AbstractSequentialList;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.Spliterator;

/**
* @author mh
* @since 10.04.16
*/
public class SetBackedListExtended<T> extends AbstractSequentialList<T> implements Set<T> {

private final Set<T> set;

public SetBackedListExtended(Set<T> set) {
this.set = set;
}

@Override
public int size() {
return set.size();
}

public ListIterator<T> listIterator(int index) {
return new ListIterator<T>() {
Iterator<T> it = set.iterator();
T current = null;
int idx = 0;

{
moveTo(index);
}

@Override
public boolean hasNext() {
return it.hasNext();
}

@Override
public T next() {
idx++;
return current = it.next();
}

@Override
public boolean hasPrevious() {
return idx > 0;
}

@Override
public T previous() {
if (!hasPrevious()) throw new NoSuchElementException();
T tmp = current;
moveTo(idx - 1);
return tmp;
}

private void moveTo(int pos) {
Iterator<T> it2 = set.iterator();
T value = null;
int i = 0;
while (i++ < pos) {
value = it2.next();
}
;
this.it = it2;
this.idx = pos;
this.current = value;
}

@Override
public int nextIndex() {
return idx;
}

@Override
public int previousIndex() {
return idx - 1;
}

@Override
public void remove() {
throw new UnsupportedOperationException("remove");
}

@Override
public void set(Object o) {
throw new UnsupportedOperationException("set");
}

@Override
public void add(Object o) {
throw new UnsupportedOperationException("add");
}
};
}

@Override
public boolean contains(Object o) {
return set.contains(o);
}

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

@Override
public boolean equals(Object o) {
if (o instanceof Set) return set.equals(o);
return o instanceof Iterable && super.equals(o);
}

@Override
public Spliterator<T> spliterator() {
return set.spliterator();
}
}
4 changes: 2 additions & 2 deletions extended/src/main/java/apoc/convert/ConvertExtended.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package apoc.convert;

import apoc.Extended;
import apoc.meta.Types;
import apoc.meta.TypesExtended;
import apoc.util.collection.Iterables;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Path;
Expand Down Expand Up @@ -49,7 +49,7 @@ public Object fromYaml(@Name("value") String value, @Name(value = "config", defa
* which handle complex types, like list/map of nodes/rels/paths
*/
private Object writeYamlResult(Object value) {
Types type = Types.of(value);
TypesExtended type = TypesExtended.of(value);
return switch (type) {
case NODE -> nodeToMap((Node) value);
case RELATIONSHIP -> relToMap((Relationship) value);
Expand Down
35 changes: 35 additions & 0 deletions extended/src/main/java/apoc/convert/ConvertExtendedUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import apoc.export.util.DurationValueSerializer;
import apoc.export.util.PointSerializer;
import apoc.export.util.TemporalSerializer;
import apoc.util.collection.Iterables;
import apoc.util.collection.Iterators;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
Expand All @@ -11,7 +13,12 @@
import org.neo4j.graphdb.spatial.Point;
import org.neo4j.values.storable.DurationValue;

import java.lang.reflect.Array;
import java.time.temporal.Temporal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

Expand All @@ -26,6 +33,34 @@ public class ConvertExtendedUtil {
YAML_MODULE.addSerializer(DurationValue.class, new DurationValueSerializer());
}

public static List convertToList(Object list) {
if (list == null) return null;
else if (list instanceof List) return (List) list;
else if (list instanceof Collection) return new ArrayList((Collection) list);
else if (list instanceof Iterable) return Iterables.asList((Iterable) list);
else if (list instanceof Iterator) return Iterators.asList((Iterator) list);
else if (list.getClass().isArray()) {
return convertArrayToList(list);
}
return Collections.singletonList(list);
}

public static List convertArrayToList(Object list) {
final Object[] objectArray;
if (list.getClass().getComponentType().isPrimitive()) {
int length = Array.getLength(list);
objectArray = new Object[length];
for (int i = 0; i < length; i++) {
objectArray[i] = Array.get(list, i);
}
} else {
objectArray = (Object[]) list;
}
List result = new ArrayList<>(objectArray.length);
Collections.addAll(result, objectArray);
return result;
}

/**
* get YAMLFactory with configured enable and disable values
*/
Expand Down
Loading

0 comments on commit ac6707d

Please sign in to comment.