From c1297f79d8f42790442a367b6076518ec4f71131 Mon Sep 17 00:00:00 2001 From: M Sazzadul Hoque <7600764+sazzad16@users.noreply.github.com> Date: Sun, 14 Aug 2022 13:47:46 +0600 Subject: [PATCH] Optimize Entities capacity to avoid reallocation (#145) * Optimize Entities capacity to avoid reallocation --- .../redisgraph/graph_entities/Edge.java | 13 ++++++- .../graph_entities/GraphEntity.java | 14 +++++++- .../redisgraph/graph_entities/Node.java | 19 ++++++++++- .../impl/resultset/ResultSetImpl.java | 34 ++++++++++++------- 4 files changed, 64 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/redislabs/redisgraph/graph_entities/Edge.java b/src/main/java/com/redislabs/redisgraph/graph_entities/Edge.java index 6eebdf8..b36db16 100644 --- a/src/main/java/com/redislabs/redisgraph/graph_entities/Edge.java +++ b/src/main/java/com/redislabs/redisgraph/graph_entities/Edge.java @@ -9,11 +9,22 @@ public class Edge extends GraphEntity { //members - private String relationshipType; + private String relationshipType; private long source; private long destination; + public Edge() { + super(); + } + /** + * Use this constructor to reduce memory allocations + * when properties are added to the edge + * @param propertiesCapacity preallocate the capacity for the properties + */ + public Edge(int propertiesCapacity) { + super(propertiesCapacity); + } //getters & setters /** diff --git a/src/main/java/com/redislabs/redisgraph/graph_entities/GraphEntity.java b/src/main/java/com/redislabs/redisgraph/graph_entities/GraphEntity.java index e86e302..2919747 100644 --- a/src/main/java/com/redislabs/redisgraph/graph_entities/GraphEntity.java +++ b/src/main/java/com/redislabs/redisgraph/graph_entities/GraphEntity.java @@ -10,8 +10,20 @@ public abstract class GraphEntity { //members protected long id; - protected final Map> propertyMap = new HashMap<>(); + protected final Map> propertyMap; + public GraphEntity() { + propertyMap = new HashMap<>(); + } + + /** + * Use this constructor to reduce memory allocations + * when properties are added to the edge + * @param propertiesCapacity preallocate the capacity for the properties + */ + public GraphEntity(int propertiesCapacity) { + propertyMap = new HashMap<>(propertiesCapacity); + } //setters & getters diff --git a/src/main/java/com/redislabs/redisgraph/graph_entities/Node.java b/src/main/java/com/redislabs/redisgraph/graph_entities/Node.java index 91b9a4f..3185b43 100644 --- a/src/main/java/com/redislabs/redisgraph/graph_entities/Node.java +++ b/src/main/java/com/redislabs/redisgraph/graph_entities/Node.java @@ -10,7 +10,24 @@ public class Node extends GraphEntity { //members - private final List labels = new ArrayList<>(); + private final List labels; + + public Node() { + super(); + labels = new ArrayList<>(); + } + + /** + * Use this constructor to reduce memory allocations + * when labels or properties are added to the node + * @param labelsCapacity preallocate the capacity for the node labels + * @param propertiesCapacity preallocate the capacity for the properties + */ + public Node(int labelsCapacity, int propertiesCapacity) { + super(propertiesCapacity); + this.labels = new ArrayList<>(labelsCapacity); + } + /** * @param label - a label to be add diff --git a/src/main/java/com/redislabs/redisgraph/impl/resultset/ResultSetImpl.java b/src/main/java/com/redislabs/redisgraph/impl/resultset/ResultSetImpl.java index df77cdd..62a9e2f 100644 --- a/src/main/java/com/redislabs/redisgraph/impl/resultset/ResultSetImpl.java +++ b/src/main/java/com/redislabs/redisgraph/impl/resultset/ResultSetImpl.java @@ -140,26 +140,28 @@ public Header getHeader() { */ @SuppressWarnings("unchecked") private Node deserializeNode(List rawNodeData) { - Node node = new Node(); - deserializeGraphEntityId(node, rawNodeData.get(0)); + List labelsIndices = (List) rawNodeData.get(1); + List> rawProperties = (List>) rawNodeData.get(2); + + Node node = new Node(labelsIndices.size(), rawProperties.size()); + deserializeGraphEntityId(node, (Long) rawNodeData.get(0)); + for (Long labelIndex : labelsIndices) { String label = cache.getLabel(labelIndex.intValue(), redisGraph); node.addLabel(label); } - deserializeGraphEntityProperties(node, (List>) rawNodeData.get(2)); - return node; + deserializeGraphEntityProperties(node, rawProperties); + return node; } /** * @param graphEntity graph entity - * @param rawEntityId raw representation of entity id to be set to the graph - * entity + * @param id entity id to be set to the graph entity */ - private void deserializeGraphEntityId(GraphEntity graphEntity, Object rawEntityId) { - long id = (Long) rawEntityId; + private void deserializeGraphEntityId(GraphEntity graphEntity, long id) { graphEntity.setId(id); } @@ -172,8 +174,11 @@ private void deserializeGraphEntityId(GraphEntity graphEntity, Object rawEntityI */ @SuppressWarnings("unchecked") private Edge deserializeEdge(List rawEdgeData) { - Edge edge = new Edge(); - deserializeGraphEntityId(edge, rawEdgeData.get(0)); + + List> rawProperties = (List>) rawEdgeData.get(4); + + Edge edge = new Edge(rawProperties.size()); + deserializeGraphEntityId(edge, (Long) rawEdgeData.get(0)); String relationshipType = cache.getRelationshipType(((Long) rawEdgeData.get(1)).intValue(), redisGraph); edge.setRelationshipType(relationshipType); @@ -181,7 +186,7 @@ private Edge deserializeEdge(List rawEdgeData) { edge.setSource((long) rawEdgeData.get(2)); edge.setDestination((long) rawEdgeData.get(3)); - deserializeGraphEntityProperties(edge, (List>) rawEdgeData.get(4)); + deserializeGraphEntityProperties(edge, rawProperties); return edge; } @@ -256,8 +261,11 @@ private Object deserializePoint(Object rawScalarData) { @SuppressWarnings("unchecked") private Map deserializeMap(Object rawScalarData) { List keyTypeValueEntries = (List) rawScalarData; - Map map = new HashMap<>(); - for (int i = 0; i < keyTypeValueEntries.size(); i += 2) { + + int size = keyTypeValueEntries.size(); + Map map = new HashMap<>(size >> 1); // set the capacity to half of the list + + for (int i = 0; i < size; i += 2) { String key = SafeEncoder.encode((byte[]) keyTypeValueEntries.get(i)); Object value = deserializeScalar((List) keyTypeValueEntries.get(i + 1)); map.put(key, value);