diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/traversal/algorithm/IdMapping.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/traversal/algorithm/IdMapping.java index cec5eabf50..58f23afee6 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/traversal/algorithm/IdMapping.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/traversal/algorithm/IdMapping.java @@ -19,34 +19,39 @@ package com.baidu.hugegraph.traversal.algorithm; -import org.eclipse.collections.impl.map.mutable.primitive.LongObjectHashMap; -import org.eclipse.collections.impl.map.mutable.primitive.ObjectLongHashMap; +import org.eclipse.collections.impl.map.mutable.primitive.IntObjectHashMap; +import com.baidu.hugegraph.HugeException; import com.baidu.hugegraph.backend.id.Id; public class IdMapping { - private LongObjectHashMap long2IdMap; - private ObjectLongHashMap id2LongMap; - private long nextLong; + private static final int MAGIC = 1 << 16; + private IntObjectHashMap int2IdMap; public IdMapping() { - this.long2IdMap = new LongObjectHashMap(); - this.id2LongMap = new ObjectLongHashMap(); - this.nextLong = 0L; + this.int2IdMap = new IntObjectHashMap(); } - public long getLong(Id id) { - if (this.id2LongMap.containsKey(id)) { - return this.id2LongMap.get(id); + public int getCode(Id id) { + int key = id.hashCode(); + for (int i = 1; i > 0; i <<= 1) { + for (int j = 0; i >= MAGIC && j < 10; j++) { + Id existed = (Id) this.int2IdMap.get(key); + if (existed == null) { + this.int2IdMap.put(key, id); + return key; + } + if (existed.equals(id)) { + return key; + } + key = key + i + j; + } } - this.nextLong++; - this.id2LongMap.put(id, this.nextLong); - this.long2IdMap.put(this.nextLong, id); - return this.nextLong; + throw new HugeException("Failed to get code for id: %s", id); } - public Id getId(long code) { - return (Id) this.long2IdMap.get(code); + public Id getId(int code) { + return (Id) this.int2IdMap.get(code); } } diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/traversal/algorithm/ShortestPathTraverser.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/traversal/algorithm/ShortestPathTraverser.java index 4ae89f72d5..8fc89b5436 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/traversal/algorithm/ShortestPathTraverser.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/traversal/algorithm/ShortestPathTraverser.java @@ -28,8 +28,8 @@ import org.apache.tinkerpop.gremlin.structure.Edge; import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils; -import org.eclipse.collections.api.iterator.LongIterator; -import org.eclipse.collections.impl.map.mutable.primitive.LongLongHashMap; +import org.eclipse.collections.api.iterator.IntIterator; +import org.eclipse.collections.impl.map.mutable.primitive.IntIntHashMap; import org.eclipse.collections.impl.set.mutable.primitive.LongHashSet; import com.baidu.hugegraph.HugeGraph; @@ -142,8 +142,8 @@ private class Traverser { // TODO: change Map to Set to reduce memory cost private IdMapping idMapping; - private Stack sourceLayers; - private Stack targetLayers; + private Stack sourceLayers; + private Stack targetLayers; private LongHashSet accessed = new LongHashSet(); @@ -161,12 +161,12 @@ public Traverser(Id sourceV, Id targetV, Directions dir, Map labels, long degree, long skipDegree, long capacity) { this.idMapping = new IdMapping(); - long sourceCode = this.code(sourceV); - long targetCode = this.code(targetV); - LongLongHashMap firstSourceLayer = new LongLongHashMap(); - LongLongHashMap firstTargetLayer = new LongLongHashMap(); - firstSourceLayer.put(sourceCode, 0L); - firstTargetLayer.put(targetCode, 0L); + int sourceCode = this.code(sourceV); + int targetCode = this.code(targetV); + IntIntHashMap firstSourceLayer = new IntIntHashMap(); + IntIntHashMap firstTargetLayer = new IntIntHashMap(); + firstSourceLayer.put(sourceCode, 0); + firstTargetLayer.put(targetCode, 0); this.sourceLayers = new Stack<>(); this.targetLayers = new Stack<>(); this.sourceLayers.push(firstSourceLayer); @@ -188,17 +188,17 @@ public Traverser(Id sourceV, Id targetV, Directions dir, */ public PathSet forward(boolean all) { PathSet paths = new PathSet(); - LongLongHashMap newLayer = new LongLongHashMap(); + IntIntHashMap newLayer = new IntIntHashMap(); long degree = this.skipDegree > 0L ? this.skipDegree : this.degree; assert !this.sourceLayers.isEmpty(); assert !this.targetLayers.isEmpty(); - LongLongHashMap sourceTopLayer = this.sourceLayers.peek(); - LongLongHashMap targetTopLayer = this.targetLayers.peek(); + IntIntHashMap sourceTopLayer = this.sourceLayers.peek(); + IntIntHashMap targetTopLayer = this.targetLayers.peek(); - LongIterator iterator = sourceTopLayer.keySet().longIterator(); + IntIterator iterator = sourceTopLayer.keySet().intIterator(); while (iterator.hasNext()) { - long sourceCode = iterator.next(); + int sourceCode = iterator.next(); Iterator edges = edgesOfVertex(this.id(sourceCode), this.direction, this.labels, degree); @@ -207,7 +207,7 @@ public PathSet forward(boolean all) { while (edges.hasNext()) { HugeEdge edge = (HugeEdge) edges.next(); Id target = edge.id().otherVertexId(); - long targetCode = this.code(target); + int targetCode = this.code(target); // If cross point exists, shortest path found, concat them if (targetTopLayer.containsKey(targetCode)) { @@ -247,19 +247,19 @@ public PathSet forward(boolean all) { */ public PathSet backward(boolean all) { PathSet paths = new PathSet(); - LongLongHashMap newLayer = new LongLongHashMap(); + IntIntHashMap newLayer = new IntIntHashMap(); long degree = this.skipDegree > 0L ? this.skipDegree : this.degree; assert !this.sourceLayers.isEmpty(); assert !this.targetLayers.isEmpty(); - LongLongHashMap sourceTopLayer = this.targetLayers.peek(); - LongLongHashMap targetTopLayer = this.sourceLayers.peek(); + IntIntHashMap sourceTopLayer = this.targetLayers.peek(); + IntIntHashMap targetTopLayer = this.sourceLayers.peek(); Directions opposite = this.direction.opposite(); - LongIterator iterator = sourceTopLayer.keySet().longIterator(); + IntIterator iterator = sourceTopLayer.keySet().intIterator(); while (iterator.hasNext()) { - long sourceCode = iterator.next(); + int sourceCode = iterator.next(); Iterator edges = edgesOfVertex(this.id(sourceCode), opposite, this.labels, degree); @@ -268,7 +268,7 @@ public PathSet backward(boolean all) { while (edges.hasNext()) { HugeEdge edge = (HugeEdge) edges.next(); Id target = edge.id().otherVertexId(); - long targetCode = this.code(target); + int targetCode = this.code(target); // If cross point exists, shortest path found, concat them if (targetTopLayer.containsKey(targetCode)) { @@ -311,16 +311,16 @@ private boolean superNode(Id vertex, Directions direction) { return IteratorUtils.count(edges) >= this.skipDegree; } - private Path getPath(long source, long target) { + private Path getPath(int source, int target) { int sourceLayerSize = this.sourceLayers.size(); int targetLayerSize = this.targetLayers.size(); List ids = new ArrayList<>(sourceLayerSize + targetLayerSize); ids.add(this.id(source)); - long value = source; + int value = source; for (int i = sourceLayerSize - 1; i > 0 ; i--) { - LongLongHashMap layer = this.sourceLayers.elementAt(i); + IntIntHashMap layer = this.sourceLayers.elementAt(i); value = layer.get(value); ids.add(this.id(value)); } @@ -328,19 +328,19 @@ private Path getPath(long source, long target) { ids.add(this.id(target)); value = target; for (int i = this.targetLayers.size() - 1; i > 0 ; i--) { - LongLongHashMap layer = this.targetLayers.elementAt(i); + IntIntHashMap layer = this.targetLayers.elementAt(i); value = layer.get(value); ids.add(this.id(value)); } return new Path(ids); } - private Id id(long code) { + private Id id(int code) { return this.idMapping.getId(code); } - private long code(Id id) { - return this.idMapping.getLong(id); + private int code(Id id) { + return this.idMapping.getCode(id); } } }