diff --git a/java/src/main/java/org/softwareheritage/graph/SwhBidirectionalGraph.java b/java/src/main/java/org/softwareheritage/graph/SwhBidirectionalGraph.java --- a/java/src/main/java/org/softwareheritage/graph/SwhBidirectionalGraph.java +++ b/java/src/main/java/org/softwareheritage/graph/SwhBidirectionalGraph.java @@ -139,7 +139,7 @@ @Override public SwhBidirectionalGraph copy() { - return new SwhBidirectionalGraph(forwardGraph.copy(), backwardGraph.copy(), this.properties); + return new SwhBidirectionalGraph(forwardGraph.copy(), backwardGraph.copy(), this.properties.copy()); } @Override diff --git a/java/src/main/java/org/softwareheritage/graph/SwhGraphProperties.java b/java/src/main/java/org/softwareheritage/graph/SwhGraphProperties.java --- a/java/src/main/java/org/softwareheritage/graph/SwhGraphProperties.java +++ b/java/src/main/java/org/softwareheritage/graph/SwhGraphProperties.java @@ -18,6 +18,7 @@ import it.unimi.dsi.fastutil.longs.LongMappedBigList; import it.unimi.dsi.fastutil.shorts.ShortBigList; import it.unimi.dsi.fastutil.shorts.ShortMappedBigList; +import it.unimi.dsi.lang.FlyweightPrototype; import it.unimi.dsi.sux4j.util.EliasFanoLongBigList; import org.apache.commons.configuration2.ex.ConfigurationException; import org.softwareheritage.graph.maps.NodeIdMap; @@ -43,7 +44,7 @@ * @see NodeIdMap * @see NodeTypesMap */ -public class SwhGraphProperties { +public class SwhGraphProperties implements FlyweightPrototype { private final String path; private final NodeIdMap nodeIdMap; @@ -68,6 +69,66 @@ this.nodeTypesMap = nodeTypesMap; } + protected SwhGraphProperties(String path, NodeIdMap nodeIdMap, NodeTypesMap nodeTypesMap, + LongBigList authorTimestamp, ShortBigList authorTimestampOffset, LongBigList committerTimestamp, + ShortBigList committerTimestampOffset, LongBigList contentLength, LongArrayBitVector contentIsSkipped, + IntBigList authorId, IntBigList committerId, ByteBigList messageBuffer, LongBigList messageOffsets, + ByteBigList tagNameBuffer, LongBigList tagNameOffsets, MappedFrontCodedStringBigList edgeLabelNames) { + this.path = path; + this.nodeIdMap = nodeIdMap; + this.nodeTypesMap = nodeTypesMap; + this.authorTimestamp = authorTimestamp; + this.authorTimestampOffset = authorTimestampOffset; + this.committerTimestamp = committerTimestamp; + this.committerTimestampOffset = committerTimestampOffset; + this.contentLength = contentLength; + this.contentIsSkipped = contentIsSkipped; + this.authorId = authorId; + this.committerId = committerId; + this.messageBuffer = messageBuffer; + this.messageOffsets = messageOffsets; + this.tagNameBuffer = tagNameBuffer; + this.tagNameOffsets = tagNameOffsets; + this.edgeLabelNames = edgeLabelNames; + } + + public SwhGraphProperties copy() { + return new SwhGraphProperties(path, nodeIdMap.copy(), nodeTypesMap.copy(), + ((authorTimestamp instanceof LongMappedBigList) + ? ((LongMappedBigList) authorTimestamp).copy() + : authorTimestamp), + ((authorTimestampOffset instanceof ShortMappedBigList) + ? ((ShortMappedBigList) authorTimestampOffset).copy() + : authorTimestampOffset), + ((committerTimestamp instanceof LongMappedBigList) + ? ((LongMappedBigList) committerTimestamp).copy() + : committerTimestamp), + ((committerTimestampOffset instanceof ShortMappedBigList) + ? ((ShortMappedBigList) committerTimestampOffset).copy() + : committerTimestampOffset), + ((contentLength instanceof LongMappedBigList) + ? ((LongMappedBigList) contentLength).copy() + : contentLength), + (contentIsSkipped != null) ? contentIsSkipped.copy() : null, + ((authorId instanceof IntMappedBigList) ? ((IntMappedBigList) authorId).copy() : authorId), + ((committerId instanceof IntMappedBigList) ? ((IntMappedBigList) committerId).copy() : committerId), + ((messageBuffer instanceof ByteMappedBigList) + ? ((ByteMappedBigList) messageBuffer).copy() + : messageBuffer), + ((messageOffsets instanceof LongMappedBigList) + ? ((LongMappedBigList) messageOffsets).copy() + : messageOffsets), + ((tagNameBuffer instanceof ByteMappedBigList) + ? ((ByteMappedBigList) tagNameBuffer).copy() + : tagNameBuffer), + ((tagNameOffsets instanceof LongMappedBigList) + ? ((LongMappedBigList) tagNameOffsets).copy() + : tagNameOffsets), + // TODO: not thread safe!! see https://github.com/vigna/dsiutils/issues/5 + // Once https://github.com/vigna/dsiutils/pull/6 is merged, add a .copy() here: + edgeLabelNames); + } + public static SwhGraphProperties load(String path) throws IOException { return new SwhGraphProperties(path, new NodeIdMap(path), new NodeTypesMap(path)); } diff --git a/java/src/main/java/org/softwareheritage/graph/SwhUnidirectionalGraph.java b/java/src/main/java/org/softwareheritage/graph/SwhUnidirectionalGraph.java --- a/java/src/main/java/org/softwareheritage/graph/SwhUnidirectionalGraph.java +++ b/java/src/main/java/org/softwareheritage/graph/SwhUnidirectionalGraph.java @@ -150,7 +150,7 @@ @Override public SwhUnidirectionalGraph copy() { return new SwhUnidirectionalGraph(this.graph.copy(), - this.labelledGraph != null ? this.labelledGraph.copy() : null, this.properties); + this.labelledGraph != null ? this.labelledGraph.copy() : null, this.properties.copy()); } @Override diff --git a/java/src/main/java/org/softwareheritage/graph/maps/NodeIdMap.java b/java/src/main/java/org/softwareheritage/graph/maps/NodeIdMap.java --- a/java/src/main/java/org/softwareheritage/graph/maps/NodeIdMap.java +++ b/java/src/main/java/org/softwareheritage/graph/maps/NodeIdMap.java @@ -14,6 +14,7 @@ import it.unimi.dsi.fastutil.longs.LongBigList; import it.unimi.dsi.fastutil.longs.LongMappedBigList; import it.unimi.dsi.fastutil.objects.Object2LongFunction; +import it.unimi.dsi.lang.FlyweightPrototype; import org.softwareheritage.graph.SWHID; import org.softwareheritage.graph.compress.NodeMapBuilder; @@ -35,7 +36,7 @@ * @see NodeMapBuilder */ -public class NodeIdMap implements Size64 { +public class NodeIdMap implements Size64, FlyweightPrototype { /** Fixed length of binary SWHID buffer */ public static final int SWHID_BIN_SIZE = 22; @@ -73,6 +74,29 @@ } } + protected NodeIdMap(String graphPath, ByteBigList nodeToSwhMap, Object2LongFunction mph, + LongBigList orderMap) { + this.graphPath = graphPath; + this.nodeToSwhMap = nodeToSwhMap; + this.mph = mph; + this.orderMap = orderMap; + } + + /** Return the number of nodes in the map. */ + @Override + public long size64() { + return nodeToSwhMap.size64(); + } + + @Override + public NodeIdMap copy() { + return new NodeIdMap(graphPath, + ((nodeToSwhMap instanceof ByteMappedBigList) + ? ((ByteMappedBigList) nodeToSwhMap).copy() + : nodeToSwhMap), + mph, ((orderMap instanceof LongMappedBigList) ? ((LongMappedBigList) orderMap).copy() : orderMap)); + } + @SuppressWarnings("unchecked") public static Object2LongFunction loadMph(String path) throws IOException { Object obj; @@ -187,10 +211,4 @@ nodeToSwhMap.getElements(nodeId * SWHID_BIN_SIZE, swhid, 0, SWHID_BIN_SIZE); return SWHID.fromBytes(swhid); } - - /** Return the number of nodes in the map. */ - @Override - public long size64() { - return nodeToSwhMap.size64(); - } } diff --git a/java/src/main/java/org/softwareheritage/graph/maps/NodeTypesMap.java b/java/src/main/java/org/softwareheritage/graph/maps/NodeTypesMap.java --- a/java/src/main/java/org/softwareheritage/graph/maps/NodeTypesMap.java +++ b/java/src/main/java/org/softwareheritage/graph/maps/NodeTypesMap.java @@ -9,6 +9,8 @@ import it.unimi.dsi.fastutil.io.BinIO; import it.unimi.dsi.fastutil.longs.LongBigList; +import it.unimi.dsi.fastutil.longs.LongMappedBigList; +import it.unimi.dsi.lang.FlyweightPrototype; import org.softwareheritage.graph.SwhType; import java.io.IOException; @@ -26,7 +28,7 @@ * @author The Software Heritage developers */ -public class NodeTypesMap { +public class NodeTypesMap implements FlyweightPrototype { /** File extension for the long node id to node type map */ public static final String NODE_TO_TYPE = ".node2type.map"; @@ -48,6 +50,16 @@ } } + public NodeTypesMap(LongBigList nodeTypesMap) { + this.nodeTypesMap = nodeTypesMap; + } + + @Override + public NodeTypesMap copy() { + return new NodeTypesMap( + (nodeTypesMap instanceof LongMappedBigList) ? ((LongMappedBigList) nodeTypesMap).copy() : nodeTypesMap); + } + /** * Returns node type from a node long id. *