From 27347325b0b49bdb3feccf0fbe57031cb7842fa9 Mon Sep 17 00:00:00 2001 From: Paul Horn Date: Wed, 27 Mar 2024 10:01:16 +0100 Subject: [PATCH] Use the highest value from NODE and DYNAMIC_NODE id types on block format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Sören Reichardt --- .../neo4j/gds/compat/_44/Neo4jProxyImpl.java | 4 +- .../gds/compat/_5x/CommonNeo4jProxyImpl.java | 43 +++++++++++-------- .../org/neo4j/gds/compat/InternalReadOps.java | 25 +++++++---- 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/compatibility/4.4/neo4j-kernel-adapter/src/main/java/org/neo4j/gds/compat/_44/Neo4jProxyImpl.java b/compatibility/4.4/neo4j-kernel-adapter/src/main/java/org/neo4j/gds/compat/_44/Neo4jProxyImpl.java index 17c34105e0..98f8b5995b 100644 --- a/compatibility/4.4/neo4j-kernel-adapter/src/main/java/org/neo4j/gds/compat/_44/Neo4jProxyImpl.java +++ b/compatibility/4.4/neo4j-kernel-adapter/src/main/java/org/neo4j/gds/compat/_44/Neo4jProxyImpl.java @@ -537,14 +537,14 @@ public ProcedureSignature procedureSignature( public long getHighestPossibleNodeCount( Read read, IdGeneratorFactory idGeneratorFactory ) { - return countByIdGenerator(idGeneratorFactory, RecordIdType.NODE, RecordIdType.NODE); + return countByIdGenerator(idGeneratorFactory, RecordIdType.NODE); } @Override public long getHighestPossibleRelationshipCount( Read read, IdGeneratorFactory idGeneratorFactory ) { - return countByIdGenerator(idGeneratorFactory, RecordIdType.RELATIONSHIP, RecordIdType.RELATIONSHIP); + return countByIdGenerator(idGeneratorFactory, RecordIdType.RELATIONSHIP); } @Override diff --git a/compatibility/5-common/neo4j-kernel-adapter/src/main/java17/org/neo4j/gds/compat/_5x/CommonNeo4jProxyImpl.java b/compatibility/5-common/neo4j-kernel-adapter/src/main/java17/org/neo4j/gds/compat/_5x/CommonNeo4jProxyImpl.java index d9435d6198..1cf0f2177a 100644 --- a/compatibility/5-common/neo4j-kernel-adapter/src/main/java17/org/neo4j/gds/compat/_5x/CommonNeo4jProxyImpl.java +++ b/compatibility/5-common/neo4j-kernel-adapter/src/main/java17/org/neo4j/gds/compat/_5x/CommonNeo4jProxyImpl.java @@ -178,7 +178,7 @@ public List> entityCursorScan( int batchSize, boolean allowPartitionedScan ) { - return PartitionedStoreScan.createScans(transaction, batchSize, this, labelIds); + return PartitionedStoreScan.createScans(transaction, batchSize, this, labelIds); } @Override @@ -187,7 +187,7 @@ public List> partitionedCursorScan( int batchSize, int... labelIds ) { - return PartitionedStoreScan.createScans(transaction, batchSize, this, labelIds); + return PartitionedStoreScan.createScans(transaction, batchSize, this, labelIds); } @Override @@ -453,44 +453,49 @@ public Long pageCacheMemoryValue(String value) { public long getHighestPossibleNodeCount( Read read, IdGeneratorFactory idGeneratorFactory ) { - return countByIdGenerator(idGeneratorFactory, RecordIdType.NODE, BlockFormat.INSTANCE.nodeType); + return countByIdGenerator( + idGeneratorFactory, + RecordIdType.NODE, + BlockFormat.INSTANCE.nodeType, + BlockFormat.INSTANCE.dynamicNodeType + ); } @Override public long getHighestPossibleRelationshipCount( Read read, IdGeneratorFactory idGeneratorFactory ) { - return countByIdGenerator(idGeneratorFactory, RecordIdType.RELATIONSHIP, BlockFormat.INSTANCE.relationshipType); + return countByIdGenerator( + idGeneratorFactory, + RecordIdType.RELATIONSHIP, + BlockFormat.INSTANCE.relationshipType, + BlockFormat.INSTANCE.dynamicRelationshipType + ); } private static final class BlockFormat { private static final BlockFormat INSTANCE = new BlockFormat(); - private final org.neo4j.internal.id.IdType nodeType; - private final org.neo4j.internal.id.IdType relationshipType; + private org.neo4j.internal.id.IdType nodeType = null; + private org.neo4j.internal.id.IdType dynamicNodeType = null; + private org.neo4j.internal.id.IdType relationshipType = null; + private org.neo4j.internal.id.IdType dynamicRelationshipType = null; BlockFormat() { - org.neo4j.internal.id.IdType nodeType = null; - org.neo4j.internal.id.IdType relationshipType = null; - try { var blockIdType = Class.forName("com.neo4j.internal.blockformat.BlockIdType"); var blockTypes = Objects.requireNonNull(blockIdType.getEnumConstants()); for (Object blockType : blockTypes) { var type = (Enum) blockType; - if (type.name().equals("NODE")) { - nodeType = (org.neo4j.internal.id.IdType) type; - } else if (type.name().equals("RELATIONSHIP")) { - relationshipType = (org.neo4j.internal.id.IdType) type; + switch (type.name()) { + case "NODE" -> this.nodeType = (org.neo4j.internal.id.IdType) type; + case "DYNAMIC_NODE" -> this.dynamicNodeType = (org.neo4j.internal.id.IdType) type; + case "RELATIONSHIP" -> this.relationshipType = (org.neo4j.internal.id.IdType) type; + case "DYNAMIC_RELATIONSHIP" -> this.dynamicRelationshipType = (org.neo4j.internal.id.IdType) type; } } - } catch (ClassNotFoundException | NullPointerException | ClassCastException e) { - nodeType = null; - relationshipType = null; + } catch (ClassNotFoundException | NullPointerException | ClassCastException ignored) { } - - this.nodeType = Objects.requireNonNullElse(nodeType, RecordIdType.NODE); - this.relationshipType = Objects.requireNonNullElse(relationshipType, RecordIdType.RELATIONSHIP); } } diff --git a/neo4j-adapter/src/main/java/org/neo4j/gds/compat/InternalReadOps.java b/neo4j-adapter/src/main/java/org/neo4j/gds/compat/InternalReadOps.java index 5d195f75da..c08e296069 100644 --- a/neo4j-adapter/src/main/java/org/neo4j/gds/compat/InternalReadOps.java +++ b/neo4j-adapter/src/main/java/org/neo4j/gds/compat/InternalReadOps.java @@ -30,18 +30,25 @@ public final class InternalReadOps { public static long countByIdGenerator( @Nullable IdGeneratorFactory idGeneratorFactory, - IdType idType, - IdType idType2 + IdType... idTypes ) { - return countByIdGenerator(idGeneratorFactory, idType) - .orElseGet(() -> countByIdGenerator(idGeneratorFactory, idType2) - .orElseThrow(() -> new IllegalStateException( - "Unsupported store format for GDS; GDS cannot read data from this database. " + - "Please try to use Cypher projection instead."))); + long highestId = Long.MIN_VALUE; + for (IdType idType : idTypes) { + final OptionalLong count = countByIdGenerator(idGeneratorFactory, idType); + if (count.isPresent()) { + highestId = Math.max(highestId, count.getAsLong()); + } + } + if (highestId == Long.MIN_VALUE) { + throw new IllegalStateException( + "Unsupported store format for GDS; GDS cannot read data from this database. " + + "Please try to use Cypher projection instead."); + } + return highestId; } - private static OptionalLong countByIdGenerator(@Nullable IdGeneratorFactory idGeneratorFactory, IdType idType) { - if (idGeneratorFactory != null) { + private static OptionalLong countByIdGenerator(@Nullable IdGeneratorFactory idGeneratorFactory, @Nullable IdType idType) { + if (idGeneratorFactory != null && idType != null) { try { final IdGenerator idGenerator = idGeneratorFactory.get(idType); if (idGenerator != null) {