Skip to content

Commit

Permalink
Use the highest value from NODE and DYNAMIC_NODE id types on block fo…
Browse files Browse the repository at this point in the history
…rmat

Co-Authored-By: Sören Reichardt <[email protected]>
  • Loading branch information
knutwalker and soerenreichardt committed Mar 27, 2024
1 parent 6866721 commit 2734732
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ public List<StoreScan<NodeLabelIndexCursor>> entityCursorScan(
int batchSize,
boolean allowPartitionedScan
) {
return PartitionedStoreScan.createScans(transaction, batchSize, this, labelIds);
return PartitionedStoreScan.createScans(transaction, batchSize, this, labelIds);
}

@Override
Expand All @@ -187,7 +187,7 @@ public List<StoreScan<NodeLabelIndexCursor>> partitionedCursorScan(
int batchSize,
int... labelIds
) {
return PartitionedStoreScan.createScans(transaction, batchSize, this, labelIds);
return PartitionedStoreScan.createScans(transaction, batchSize, this, labelIds);
}

@Override
Expand Down Expand Up @@ -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);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit 2734732

Please sign in to comment.