2929import org .neo4j .gds .api .properties .nodes .NodeProperty ;
3030import org .neo4j .gds .api .properties .nodes .NodePropertyStore ;
3131import org .neo4j .gds .api .properties .nodes .NodePropertyValues ;
32+ import org .neo4j .gds .api .schema .NodeSchema ;
3233import org .neo4j .gds .api .schema .PropertySchema ;
3334import org .neo4j .gds .compat .LongPropertyReference ;
3435import org .neo4j .gds .core .concurrency .ParallelUtil ;
5657import java .util .concurrent .atomic .LongAdder ;
5758import java .util .function .Function ;
5859import java .util .function .LongPredicate ;
60+ import java .util .stream .Collectors ;
5961
6062import static java .util .stream .Collectors .toMap ;
6163
@@ -77,12 +79,14 @@ public final class NodesBuilder {
7779 private final NodeImporter nodeImporter ;
7880
7981 private final ConcurrentMap <String , NodePropertiesFromStoreBuilder > propertyBuildersByPropertyKey ;
80- private final boolean hasProperties ;
82+
83+ private final NodeLabelTokenToPropertyKeys nodeLabelTokenToPropertyKeys ;
8184
8285 NodesBuilder (
8386 long maxOriginalId ,
8487 int concurrency ,
8588 TokenToNodeLabelMap tokenToNodeLabelMap ,
89+ NodeLabelTokenToPropertyKeys nodeLabelTokenToPropertyKeys ,
8690 ConcurrentMap <String , NodePropertiesFromStoreBuilder > propertyBuildersByPropertyKey ,
8791 IdMapBuilder idMapBuilder ,
8892 boolean hasLabelInformation ,
@@ -92,13 +96,13 @@ public final class NodesBuilder {
9296 ) {
9397 this .maxOriginalId = maxOriginalId ;
9498 this .concurrency = concurrency ;
99+ this .nodeLabelTokenToPropertyKeys = nodeLabelTokenToPropertyKeys ;
95100 this .idMapBuilder = idMapBuilder ;
96101 this .propertyStates = propertyStates ;
97102 this .labelInformationBuilder = !hasLabelInformation
98103 ? LabelInformationBuilders .allNodes ()
99104 : LabelInformationBuilders .multiLabelWithCapacity (maxOriginalId + 1 );
100105 this .propertyBuildersByPropertyKey = propertyBuildersByPropertyKey ;
101- this .hasProperties = hasProperties ;
102106 this .importedNodes = new LongAdder ();
103107 this .nodeImporter = new NodeImporter (
104108 idMapBuilder ,
@@ -123,6 +127,7 @@ public final class NodesBuilder {
123127 hasLabelInformation ,
124128 hasProperties ,
125129 tokenToNodeLabelMap ,
130+ nodeLabelTokenToPropertyKeys ,
126131 propertyBuilderFn
127132 )
128133 );
@@ -200,13 +205,28 @@ public Nodes build(long highestNeoId) {
200205 this .threadLocalBuilder .close ();
201206
202207 var idMap = this .idMapBuilder .build (labelInformationBuilder , highestNeoId , concurrency );
208+ var nodeProperties = buildProperties (idMap );
209+ var nodeSchema = buildNodeSchema (idMap , nodeProperties );
210+ var nodePropertyStore = NodePropertyStore .builder ().properties (nodeProperties ).build ();
211+
212+ return ImmutableNodes .builder ()
213+ .schema (nodeSchema )
214+ .idMap (idMap )
215+ .properties (nodePropertyStore )
216+ .build ();
217+ }
203218
204- var nodeImportResultBuilder = ImmutableNodes .builder ().idMap (idMap );
205- if (hasProperties ) {
206- var nodeProperties = buildProperties (idMap );
207- nodeImportResultBuilder .properties (NodePropertyStore .builder ().properties (nodeProperties ).build ());
208- }
209- return nodeImportResultBuilder .build ();
219+ private NodeSchema buildNodeSchema (IdMap idMap , Map <String , NodeProperty > nodeProperties ) {
220+ var nodeSchema = NodeSchema .empty ();
221+ var importPropertySchemas = nodeProperties
222+ .entrySet ()
223+ .stream ()
224+ .collect (Collectors .toMap (Map .Entry ::getKey , entry -> entry .getValue ().propertySchema ()));
225+
226+ idMap .availableNodeLabels ().forEach (label -> {
227+ nodeSchema .addLabel (label , this .nodeLabelTokenToPropertyKeys .propertySchemas (label , importPropertySchemas ));
228+ });
229+ return nodeSchema ;
210230 }
211231
212232 private Map <String , NodeProperty > buildProperties (IdMap idMap ) {
@@ -216,7 +236,11 @@ private Map<String, NodeProperty> buildProperties(IdMap idMap) {
216236 ));
217237 }
218238
219- private static NodeProperty entryToNodeProperty (Map .Entry <String , NodePropertiesFromStoreBuilder > entry , PropertyState propertyState , IdMap idMap ) {
239+ private static NodeProperty entryToNodeProperty (
240+ Map .Entry <String , NodePropertiesFromStoreBuilder > entry ,
241+ PropertyState propertyState ,
242+ IdMap idMap
243+ ) {
220244 var nodePropertyValues = entry .getValue ().build (idMap );
221245 var valueType = nodePropertyValues .valueType ();
222246 return ImmutableNodeProperty .builder ()
@@ -264,6 +288,7 @@ private static class ThreadLocalBuilder implements AutoCloseable {
264288 private final LongAdder importedNodes ;
265289 private final LongPredicate seenNodeIdPredicate ;
266290 private final TokenToNodeLabelMap tokenToNodeLabelMap ;
291+ private final NodeLabelTokenToPropertyKeys nodeLabelTokenToPropertyKeys ;
267292 private final NodesBatchBuffer buffer ;
268293 private final Function <String , NodePropertiesFromStoreBuilder > propertyBuilderFn ;
269294 private final NodeImporter nodeImporter ;
@@ -277,11 +302,13 @@ private static class ThreadLocalBuilder implements AutoCloseable {
277302 boolean hasLabelInformation ,
278303 boolean hasProperties ,
279304 TokenToNodeLabelMap tokenToNodeLabelMap ,
305+ NodeLabelTokenToPropertyKeys nodeLabelTokenToPropertyKeys ,
280306 Function <String , NodePropertiesFromStoreBuilder > propertyBuilderFn
281307 ) {
282308 this .importedNodes = importedNodes ;
283309 this .seenNodeIdPredicate = seenNodeIdPredicate ;
284310 this .tokenToNodeLabelMap = tokenToNodeLabelMap ;
311+ this .nodeLabelTokenToPropertyKeys = nodeLabelTokenToPropertyKeys ;
285312 this .propertyBuilderFn = propertyBuilderFn ;
286313
287314 this .buffer = new NodesBatchBufferBuilder ()
@@ -309,6 +336,7 @@ public void addNode(long originalId, NodeLabelToken nodeLabels) {
309336 public void addNode (long originalId , NodeLabelToken nodeLabels , PropertyValues properties ) {
310337 if (!seenNodeIdPredicate .test (originalId )) {
311338 long [] labels = labelTokens (nodeLabels );
339+ this .nodeLabelTokenToPropertyKeys .add (nodeLabels , properties .propertyKeys ());
312340
313341 int propertyReference = batchNodeProperties .size ();
314342 batchNodeProperties .add (properties );
0 commit comments