Repository navigation
Port /data/query/enhanced/{id} to node; map results depth first as SDN does - #475
Merged
Merged
Conversation
/query/enhanced/{id} is graph-core's findOldEnhancedObjectById, written by
the domain serialiser. It returns the object, everything related to it,
those objects' species, and one step more of their regulations, physical
entities, references and markers. The entity popup, the website's content
pages and the IDG panel read it.
Rules, each measured against Java:
- Relationships go both ways unless needsIncomingRelationship says not.
That reads the id as it came: a padded or overflowing dbId fails
Long.valueOf and goes outgoing only.
- Java collects every row's nodes, repeats included. Node collects each
list DISTINCT, which keeps the only thing the mapping uses, each node's
first appearance.
- /query/enhanced/{id} ranks above /query/{id}/{attribute}, so
/query/enhanced/stId is the enhanced object with the id `stId`. node
registers it first; a test pins that and fails on the old order.
One mapping rule was wrong for every endpoint and only showed here.
SDN's extractNodes lists the nodes of list columns first, then
single-node columns. So the root sits where it first appears in a list,
and otherwise last; node had put it first. A reaction regulated by its
own root regulation and three others lists the root third, and node
listed it first (16 of 3,000). A single-valued field also takes the
first value found, not the last.
Against Java, byte for byte after the fix:
- enhanced: 3,000 of 3,000 and another 3,000 of 3,000. Node takes 25s
in all against Java's 46s.
- Re-checked: /query/{id} 20,279 of 20,279; in-depth 1,179 of 1,179.
Tests failed before the change; the root-position and precedence tests
fail on the old code. nginx -t passes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…reaches it
A node's class is decided by the field that first reaches it, and SDN's
DefaultNeo4jEntityConverter goes depth first: an entity met in a field
has its own fields filled before that field moves on. mapResult had
filled every entity flatly and chosen classes up front from the root's
fields. That was right over 20,279 /query/{id} answers, but wrong in
enhanced answers. Deleted 9034526's two replacement regulations are both
plain PositiveRegulations:
- the first is reached through replacementInstances, an interface
(Deletable), so SDN takes its store's first fitting class:
PositiveGeneExpressionRegulation;
- mapping the first reaches its reaction, whose regulatedBy (a class)
reaches the second before the deleted object's loop does, so the second
keeps its labels' class.
Java writes them that way and the flat mapper did not.
mapResult now follows createInstanceOfRelationships:
- candidates by the target's label in result order;
- each field's relationships counted per direction, dropped from the
result after a second use;
- each new entity filled before its parent field goes on.
It runs on a stack of frames, not recursion: a recursive version
overflowed on a 20,000-deep chain.
Against Java, byte for byte:
- enhanced: 6 of 6 hard cases, 9034526 among them, and 500 of 500.
- /query/{id}: 500 of 500.
- in-depth at depth 4: 99 of 100. The last differs only in the
getter-only key order Java changed on today's restart.
The test for the two regulations fails on the flat mapper. The deep-chain
test overflowed on the recursive one.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review of #475: the mapper's comment said SDN's processed-count removal "decides what some fields of highly linked objects hold". On this model it cannot fire. Only PhysicalEntity has fields sharing a relationship type and direction (three INCOMING `regulator`), a node matches at most two, and each owner is mapped once. It is kept for fidelity, and the comment now says so. It also records the one SDN behaviour not reproduced: a list column's relationships iterate in HashSet order. That only matters for parallel same-type edges between two nodes, and whether any exist is unchecked, because finding out needs a scan of the shared graph. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Port /data/query/enhanced/{id} to node; place the root as SDN does
/query/enhanced/{id} is graph-core's findOldEnhancedObjectById, written by
the domain serialiser. It returns the object, everything related to it,
those objects' species, and one step more of their regulations, physical
entities, references and markers. The entity popup, the website's content
pages and the IDG panel read it.
Rules, each measured against Java:
That reads the id as it came: a padded or overflowing dbId fails
Long.valueOf and goes outgoing only.
list DISTINCT, which keeps the only thing the mapping uses, each node's
first appearance.
/query/enhanced/stId is the enhanced object with the id
stId. noderegisters it first; a test pins that and fails on the old order.
One mapping rule was wrong for every endpoint and only showed here.
SDN's extractNodes lists the nodes of list columns first, then
single-node columns. So the root sits where it first appears in a list,
and otherwise last; node had put it first. A reaction regulated by its
own root regulation and three others lists the root third, and node
listed it first (16 of 3,000). A single-valued field also takes the
first value found, not the last.
Against Java, byte for byte after the fix:
in all against Java's 46s.
Tests failed before the change; the root-position and precedence tests
fail on the old code. nginx -t passes.
domain: map a result as SDN does -- depth first, from the field that reaches it
A node's class is decided by the field that first reaches it, and SDN's
DefaultNeo4jEntityConverter goes depth first: an entity met in a field
has its own fields filled before that field moves on. mapResult had
filled every entity flatly and chosen classes up front from the root's
fields. That was right over 20,279 /query/{id} answers, but wrong in
enhanced answers. Deleted 9034526's two replacement regulations are both
plain PositiveRegulations:
(Deletable), so SDN takes its store's first fitting class:
PositiveGeneExpressionRegulation;
reaches the second before the deleted object's loop does, so the second
keeps its labels' class.
Java writes them that way and the flat mapper did not.
mapResult now follows createInstanceOfRelationships:
result after a second use;
It runs on a stack of frames, not recursion: a recursive version
overflowed on a 20,000-deep chain.
Against Java, byte for byte:
getter-only key order Java changed on today's restart.
The test for the two regulations fails on the flat mapper. The deep-chain
test overflowed on the recursive one.
🤖 Generated with Claude Code