From 0ed8b640e1d75b15245d7039c9a49a94942a738a Mon Sep 17 00:00:00 2001
From: Michael Pollmeier <michael@michaelpollmeier.com>
Date: Thu, 11 Jul 2024 12:18:48 +0200
Subject: [PATCH] edge property hack: prereq for flatgraph -> odb converter

 In order to prepare for a potential rollback to overflowdb in the future, we're creating a
flatgraph->overflowdb converter. Since flatgraph supports exactly one edge property only,
there are no edge property names. So when we deserialise and find exactly one edge property with
the name `EDGE_PROPERTY`, and the schema defines exactly one edge property, then we assume that's the one.
Let's be clear: this is a dirty hack, but since we're phasing out overflowdb in favor of flatgraph, it's
arguably ok.
---
 .../overflowdb/storage/NodeDeserializer.java  | 28 ++++++++++++++-----
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/core/src/main/java/overflowdb/storage/NodeDeserializer.java b/core/src/main/java/overflowdb/storage/NodeDeserializer.java
index a8621ca1..8417b0f5 100644
--- a/core/src/main/java/overflowdb/storage/NodeDeserializer.java
+++ b/core/src/main/java/overflowdb/storage/NodeDeserializer.java
@@ -14,16 +14,14 @@
 import overflowdb.util.StringInterner;
 
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 public class NodeDeserializer extends BookKeeper {
   protected final Graph graph;
   private final Map<String, NodeFactory> nodeFactoryByLabel;
   private final OdbStorage storage;
   private final StringInterner stringInterner;
+  private static final String FLATGRAPH_DEFAULT_EDGE_PROPERTY_NAME = "EDGE_PROPERTY";
 
   public NodeDeserializer(Graph graph, Map<String, NodeFactory> nodeFactoryByLabel, boolean statsEnabled, OdbStorage storage) {
     super(statsEnabled);
@@ -68,7 +66,9 @@ private void deserializeEdges(MessageUnpacker unpacker, NodeDb node, Direction d
       for (int edgeIdx = 0; edgeIdx < edgeCount; edgeIdx++) {
         long adjacentNodeId = unpacker.unpackLong();
         NodeRef adjacentNode = (NodeRef) graph.node(adjacentNodeId);
-        Object[] edgeProperties = unpackProperties(unpacker);
+        // hack for flatgraph->odb converter, see `maybeReviseKeyForFlatgraph` below
+        Set<String> allowedEdgePropertyKeys = node.layoutInformation().edgePropertyKeys(edgeLabel);
+        Object[] edgeProperties = unpackProperties(unpacker, allowedEdgePropertyKeys);
         node.storeAdjacentNode(direction, edgeLabel, adjacentNode, edgeProperties);
       }
     }
@@ -87,7 +87,7 @@ public final NodeRef deserializeRef(byte[] bytes) throws IOException {
     }
   }
 
-  private final Object[] unpackProperties(MessageUnpacker unpacker) throws IOException {
+  private final Object[] unpackProperties(MessageUnpacker unpacker, Set<String> allowedEdgePropertyKeys) throws IOException {
     int propertyCount = unpacker.unpackMapHeader();
     Object[] res = new Object[propertyCount * 2];
     int resIdx = 0;
@@ -96,12 +96,26 @@ private final Object[] unpackProperties(MessageUnpacker unpacker) throws IOExcep
       final String key = storage.reverseLookupStringToIntMapping(keyId);
       final ImmutableValue unpackedValue = unpacker.unpackValue();
       final Object unpackedProperty = unpackValue(unpackedValue.asArrayValue());
-      res[resIdx++] = key;
+      final String keyRevised = maybeReviseKeyForFlatgraph(key, allowedEdgePropertyKeys);
+      res[resIdx++] = keyRevised;
       res[resIdx++] = unpackedProperty;
     }
     return res;
   }
 
+  /** In order to prepare for a potential rollback to overflowdb in the future, we're creating a
+   * flatgraph->overflowdb converter. Since flatgraph supports exactly one edge property only,
+   * there are no edge property names. So when we deserialise and find exactly one edge property with
+   * the name `EDGE_PROPERTY`, and the schema defines exactly one edge property, then we assume that's the one.
+   * Let's be clear: this is a dirty hack, but since we're phasing out overflowdb in favor of flatgraph, it's
+   * arguably ok.
+   */
+  private String maybeReviseKeyForFlatgraph(String key, Set<String> allowedEdgePropertyKeys) {
+    if (FLATGRAPH_DEFAULT_EDGE_PROPERTY_NAME.equals(key) && allowedEdgePropertyKeys.size() == 1) {
+      return allowedEdgePropertyKeys.iterator().next();
+    } else return key;
+  }
+
   private final Object unpackValue(final ArrayValue packedValueAndType) {
     final Iterator<Value> iter = packedValueAndType.iterator();
    final byte valueTypeId = iter.next().asIntegerValue().asByte();