Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

added test for bitsetimpl; fixed clone bug in memorygraphsafe; implem…

…ented memory efficient delete for memorygraphsafe; moved several memorygraph stuff to memorygraphsafe
  • Loading branch information...
commit 9907896fe385b5d25f95a5a5f5ea99dd205dbd2c 1 parent b320569
@karussell authored
Showing with 312 additions and 74 deletions.
  1. +8 −9 README.md
  2. +6 −2 core/src/main/java/de/jetsli/graph/coll/MyBitSet.java
  3. +9 −0 core/src/main/java/de/jetsli/graph/coll/MyBitSetImpl.java
  4. +29 −3 core/src/main/java/de/jetsli/graph/coll/MyOpenBitSet.java
  5. +9 −0 core/src/main/java/de/jetsli/graph/coll/MyTBitSet.java
  6. +3 −3 core/src/main/java/de/jetsli/graph/routing/rideshare/DijkstraMultipleAtOnce.java
  7. +1 −0  core/src/main/java/de/jetsli/graph/storage/MemoryGraph.java
  8. +106 −12 core/src/main/java/de/jetsli/graph/storage/MemoryGraphSafe.java
  9. +1 −0  core/src/main/java/de/jetsli/graph/util/Helper.java
  10. +1 −2  core/src/main/java/de/jetsli/graph/util/TopologicalSorting.java
  11. +30 −2 core/src/test/java/de/jetsli/graph/coll/AbstractMyBitSetTest.java
  12. +33 −0 core/src/test/java/de/jetsli/graph/coll/MyBitSetImplTest.java
  13. +4 −3 core/src/test/java/de/jetsli/graph/reader/PrinctonReaderTest.java
  14. +4 −9 core/src/test/java/de/jetsli/graph/routing/AbstractRoutingAlgorithmTester.java
  15. +4 −7 core/src/test/java/de/jetsli/graph/routing/ContractionHierarchiesTest.java
  16. +2 −2 core/src/test/java/de/jetsli/graph/routing/DijkstraBidirectionRefTest.java
  17. +2 −2 core/src/test/java/de/jetsli/graph/routing/DijkstraBidirectionTest.java
  18. +1 −2  core/src/test/java/de/jetsli/graph/routing/rideshare/DijkstraShortestOf2ToPubTest.java
  19. +49 −8 core/src/test/java/de/jetsli/graph/storage/AbstractGraphTester.java
  20. +1 −1  core/src/test/java/de/jetsli/graph/storage/MemoryGraphSafeTest.java
  21. +6 −5 core/src/test/java/de/jetsli/graph/util/TopologicalSortingTest.java
  22. +3 −2 core/src/test/java/de/jetsli/graph/util/XFirstSearchTest.java
View
17 README.md
@@ -29,13 +29,12 @@ If you want to import a bigger OSM (Germany) then run:
* For Germany it takes approx 25 minutes for the import and roughly 1 minute for the ugly&slow UI to pop up. Probably you'll need to tune the memory settings - send me a mail if this fails!
* At the moment the UI is a bit rough and simple so, don't click or drag too much ;)
-QuadTree Usage
----------------
-
-See the performacen comparison subproject and the articles:
-
-http://karussell.wordpress.com/2012/06/17/failed-experiment-memory-efficient-spatial-hashtable/
-http://karussell.wordpress.com/2012/05/29/tricks-to-speed-up-neighbor-searches-of-quadtrees-geo-spatial-java/
-
-http://karussell.wordpress.com/2012/05/23/spatial-keys-memory-efficient-geohashes/
+Further Links
+---------------
+ * [Spatial Key](http://karussell.wordpress.com/2012/05/23/spatial-keys-memory-efficient-geohashes/)
+ * [Speed up your Quad-tree](http://karussell.wordpress.com/2012/05/29/tricks-to-speed-up-neighbor-searches-of-quadtrees-geo-spatial-java/)
+ * [Spatial Hashtable](http://karussell.wordpress.com/2012/06/17/failed-experiment-memory-efficient-spatial-hashtable/)
+ * [Author@Twitter](https://twitter.com/timetabling)
+ * [Lumeo - Implementing a Graph API via Lucene](https://github.com/karussell/lumeo)
+ * [Cassovary - A production ready (?) in-memory & memory efficient Graph DB](https://github.com/twitter/cassovary)
View
8 core/src/main/java/de/jetsli/graph/coll/MyBitSet.java
@@ -17,7 +17,7 @@
/**
* Wrapper interface for different implementations like OpenBitset, BitSet, ...
- *
+ *
* Supports only integer value indices.
*
* @author Peter Karich, info@jetsli.de
@@ -29,6 +29,10 @@
void add(int index);
int getCardinality();
-
+
void clear();
+
+ void ensureCapacity(int size);
+
+ int next(int index);
}
View
9 core/src/main/java/de/jetsli/graph/coll/MyBitSetImpl.java
@@ -43,4 +43,13 @@ public void add(int index) {
public int getCardinality() {
return super.cardinality();
}
+
+ @Override
+ public void ensureCapacity(int size) {
+ }
+
+ @Override
+ public int next(int index) {
+ return super.nextSetBit(index);
+ }
}
View
32 core/src/main/java/de/jetsli/graph/coll/MyOpenBitSet.java
@@ -24,10 +24,22 @@
*/
public class MyOpenBitSet implements MyBitSet {
- private final OpenBitSet bitSet;
+ private final ProtectedHack bitSet;
public MyOpenBitSet(int no) {
- bitSet = new OpenBitSet(no);
+ bitSet = new ProtectedHack(no);
+ }
+
+ static class ProtectedHack extends OpenBitSet {
+
+ public ProtectedHack(long numBits) {
+ super(numBits);
+ }
+
+ @Override
+ public int expandingWordNum(long index) {
+ return super.expandingWordNum(index);
+ }
}
public MyOpenBitSet() {
@@ -45,12 +57,14 @@ public MyOpenBitSet() {
@Override public String toString() {
try {
StringBuilder sb = new StringBuilder();
+ sb.append("{");
for (DocIdSetIterator iter = bitSet.iterator(); iter.nextDoc() != DocIdSetIterator.NO_MORE_DOCS;) {
- if (sb.length() != 0)
+ if (sb.length() > 1)
sb.append(", ");
sb.append(iter.docID());
}
+ sb.append("}");
return sb.toString();
} catch (Exception ex) {
throw new RuntimeException("error constructing bitset string representation", ex);
@@ -66,4 +80,16 @@ public int getCardinality() {
public void clear() {
bitSet.clear(0, bitSet.length());
}
+
+ @Override
+ public void ensureCapacity(int size) {
+ bitSet.expandingWordNum(size);
+ // this does not update the numBits variable and failse if assertationen are on!
+ // bitSet.ensureCapacity((size);
+ }
+
+ @Override
+ public int next(int index) {
+ return bitSet.nextSetBit(index);
+ }
}
View
9 core/src/main/java/de/jetsli/graph/coll/MyTBitSet.java
@@ -54,4 +54,13 @@ public int getCardinality() {
public void clear() {
tHash.clear();
}
+
+ @Override
+ public void ensureCapacity(int size) {
+ }
+
+ @Override
+ public int next(int index) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
}
View
6 core/src/main/java/de/jetsli/graph/routing/rideshare/DijkstraMultipleAtOnce.java
@@ -15,7 +15,7 @@
*/
package de.jetsli.graph.routing.rideshare;
-import de.jetsli.graph.storage.MemoryGraph;
+import de.jetsli.graph.storage.Graph;
/**
*
@@ -23,9 +23,9 @@
*/
public class DijkstraMultipleAtOnce {
- private MemoryGraph graph;
+ private Graph graph;
- public DijkstraMultipleAtOnce(MemoryGraph graph) {
+ public DijkstraMultipleAtOnce(Graph graph) {
this.graph = graph;
}
View
1  core/src/main/java/de/jetsli/graph/storage/MemoryGraph.java
@@ -64,6 +64,7 @@ private void ensureNodeIndex(int index) {
if (size <= lons.length)
return;
+ deletedNodes.ensureCapacity(size);
refToEdges = growArray(refToEdges, size, FACTOR);
lons = growArray(lons, size, FACTOR);
lats = growArray(lats, size, FACTOR);
View
118 core/src/main/java/de/jetsli/graph/storage/MemoryGraphSafe.java
@@ -20,6 +20,7 @@
import de.jetsli.graph.util.EdgeIdIterator;
import de.jetsli.graph.util.Helper;
import gnu.trove.list.array.TIntArrayList;
+import gnu.trove.map.hash.TIntIntHashMap;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
@@ -79,7 +80,7 @@ public MemoryGraphSafe(String storageDir, int cap, int capEdge) {
initNodes(cap);
initEdges(capEdge);
}
- }
+ }
@Override public int getNodes() {
// readLock.lock();
@@ -124,15 +125,15 @@ private void ensureEdgePointer(int pointer) {
// Use ONLY within a writer lock area
private void ensureNodeIndex(int index) {
- if(index < size)
+ if (index < size)
return;
-
+
size = index + 1;
- if(size <= lats.length)
+ if (size <= lats.length)
return;
-
+
int cap = Math.max(10, Math.round(size * FACTOR));
- // TODO deletedNodes = copy(deletedNodes, cap);
+ deletedNodes.ensureCapacity(cap);
lats = Arrays.copyOf(lats, cap);
lons = Arrays.copyOf(lons, cap);
// priorities = Arrays.copyOf(priorities, cap);
@@ -337,6 +338,7 @@ public Graph clone() {
System.arraycopy(lons, 0, g.lons, 0, lons.length);
System.arraycopy(refToEdges, 0, g.refToEdges, 0, refToEdges.length);
System.arraycopy(edgesArea, 0, g.edgesArea, 0, edgesArea.length);
+ g.nextEdgePointer = nextEdgePointer;
g.size = size;
return g;
}
@@ -371,14 +373,106 @@ public void optimize() {
int deleted = deletedNodes.getCardinality();
if (deleted == 0)
return;
-
- logger.info("lengthy operation: optimizing graph");
+
+
+ if (deleted < size / 5)
+ optimizeIfFewDeletes(deleted);
+ else
+ optimizeIfLotsOfDeletes(deleted);
+ }
+
+ /**
+ * This methods moves the last nodes into the deleted nodes, which is much more memory friendly
+ * but probably slower than optimizeIfLotsOfDeletes for many deletes.
+ */
+ void optimizeIfFewDeletes(int deleted) {
+ // Alternative to this method: use smaller segments for nodes and not one big fat java array?
+ //
+ // Prepare edge-update of nodes which are connected to deleted nodes and
+ // create old- to new-index map.
+ int index = getNodes();
+ int counter = 0;
+ int newIndices[] = new int[deleted];
+ int oldIndices[] = new int[deleted];
+ TIntIntHashMap markedMap = new TIntIntHashMap(deleted, 1.5f, -1, -1);
+ for (int del = deletedNodes.next(0); del >= 0; del = deletedNodes.next(del + 1)) {
+ EdgeIdIterator delEdgesIter = getEdges(del);
+ while (delEdgesIter.next()) {
+ int currNode = delEdgesIter.nodeId();
+ if (deletedNodes.contains(currNode))
+ continue;
+
+ // remove all edges to the deleted nodes
+ EdgeIdIterator nodesConnectedToDelIter = getEdges(currNode);
+ boolean firstNext = nodesConnectedToDelIter.next();
+ if (firstNext) {
+ // this forces new edges to be created => TODO only update the edges. do not create new entries
+ refToEdges[currNode] = -1;
+ do {
+ if (!deletedNodes.contains(nodesConnectedToDelIter.nodeId()))
+ internalAdd(currNode, nodesConnectedToDelIter.nodeId(),
+ nodesConnectedToDelIter.distance(), nodesConnectedToDelIter.flags());
+ } while (nodesConnectedToDelIter.next());
+ }
+ }
+
+ index--;
+ for (; index >= 0; index--) {
+ if (!deletedNodes.contains(index))
+ break;
+ }
+
+ newIndices[counter] = del;
+ oldIndices[counter] = index;
+ markedMap.put(index, del);
+ counter++;
+ }
+
+ // now move marked nodes into deleted nodes
+ for (int i = 0; i < oldIndices.length; i++) {
+ int oldI = oldIndices[i];
+ int newI = newIndices[i];
+
+ EdgeIdIterator toMoveEdgeIter = getEdges(oldI);
+ while (toMoveEdgeIter.next()) {
+ int movedNewIndex = markedMap.get(toMoveEdgeIter.nodeId());
+ // if node not moved at all (<0) or node is not yet moved use the old index
+ if (movedNewIndex < 0 || movedNewIndex >= newI) {
+ movedNewIndex = toMoveEdgeIter.nodeId();
+ }
+
+ // update edges of r to use newI instead of oldI
+ EdgeIdIterator updateIter = getEdges(movedNewIndex);
+ boolean firstNext = updateIter.next();
+ if (firstNext) {
+ // this forces new edges to be created => TODO only update the edges. do not create new entries
+ refToEdges[movedNewIndex] = -1;
+ do {
+ int connNode;
+ if (updateIter.nodeId() == oldI)
+ connNode = newI;
+ else
+ connNode = updateIter.nodeId();
+ internalAdd(movedNewIndex, connNode, updateIter.distance(), updateIter.flags());
+ } while (updateIter.next());
+ }
+ }
+ refToEdges[newI] = refToEdges[oldI];
+ lats[newI] = lats[oldI];
+ lons[newI] = lons[oldI];
+ }
+
+ deletedNodes = null;
+ size -= deleted;
+ }
+
+ /**
+ * This methods creates a new in-memory graph without the specified deleted nodes.
+ */
+ void optimizeIfLotsOfDeletes(int deleted) {
MemoryGraphSafe inMemGraph = new MemoryGraphSafe(null, getNodes() - deleted, getMaxEdges());
- /**
- * This methods creates a new in-memory graph without the specified deleted nodes. see
- * MMapGraph for a near duplicate
- */
+ // see MMapGraph for a near duplicate
int locs = this.getNodes();
int newNodeId = 0;
int[] old2NewMap = new int[locs];
View
1  core/src/main/java/de/jetsli/graph/util/Helper.java
@@ -15,6 +15,7 @@
*/
package de.jetsli.graph.util;
+import de.jetsli.graph.coll.MyBitSet;
import java.io.*;
import java.nio.MappedByteBuffer;
import java.util.*;
View
3  core/src/main/java/de/jetsli/graph/util/TopologicalSorting.java
@@ -17,7 +17,6 @@
import de.jetsli.graph.coll.MyBitSet;
import de.jetsli.graph.coll.MyOpenBitSet;
-import de.jetsli.graph.storage.MemoryGraph;
import de.jetsli.graph.storage.Graph;
import gnu.trove.iterator.TIntIterator;
import gnu.trove.list.array.TIntArrayList;
@@ -32,7 +31,7 @@
/**
* conditions: acyclicGraph and all reachable from 0
*/
- public TIntArrayList sort(MemoryGraph g) {
+ public TIntArrayList sort(Graph g) {
final TIntArrayList list = new TIntArrayList();
if (g.getNodes() == 0)
return list;
View
32 core/src/test/java/de/jetsli/graph/coll/AbstractMyBitSetTest.java
@@ -31,9 +31,37 @@ public void testToString() {
MyBitSet bs = createBitSet(100);
bs.add(12);
bs.add(1);
- assertEquals("1, 12", bs.toString());
+ assertEquals("{1, 12}", bs.toString());
}
-
+
+ @Test
+ public void testNext() {
+ MyBitSet bs = createBitSet(100);
+ bs.add(7);
+ bs.add(90);
+ assertEquals(7, bs.next(0));
+ assertEquals(7, bs.next(7));
+ assertEquals(90, bs.next(8));
+ assertEquals(-1, bs.next(91));
+ }
+
+ @Test
+ public void testEnsureCapacity() {
+ MyBitSet bs = createBitSet(8);
+ bs.add(7);
+ try {
+ bs.add(8);
+ assertTrue(false);
+ } catch (Throwable ex) {
+ }
+ bs.ensureCapacity(16);
+ bs.add(8);
+ bs.add(9);
+ assertFalse(bs.contains(6));
+ assertTrue(bs.contains(7));
+ assertTrue(bs.contains(8));
+ }
+
@Test
public void testClear() {
MyBitSet bs = createBitSet(100);
View
33 core/src/test/java/de/jetsli/graph/coll/MyBitSetImplTest.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2012 Peter Karich info@jetsli.de
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package de.jetsli.graph.coll;
+
+/**
+ *
+ * @author Peter Karich
+ */
+public class MyBitSetImplTest extends AbstractMyBitSetTest {
+
+ @Override
+ public MyBitSet createBitSet(int no) {
+ return new MyBitSetImpl(no);
+ }
+
+ @Override
+ public void testEnsureCapacity() {
+ // nothing to test
+ }
+}
View
7 core/src/test/java/de/jetsli/graph/reader/PrinctonReaderTest.java
@@ -15,8 +15,9 @@
*/
package de.jetsli.graph.reader;
+import de.jetsli.graph.storage.Graph;
import static de.jetsli.graph.util.MyIteratorable.*;
-import de.jetsli.graph.storage.MemoryGraph;
+import de.jetsli.graph.storage.MemoryGraphSafe;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import org.junit.Test;
@@ -30,7 +31,7 @@
@Test
public void testRead() {
- MemoryGraph graph = new MemoryGraph();
+ Graph graph = new MemoryGraphSafe(100);
new PrinctonReader(graph).setStream(PrinctonReader.class.getResourceAsStream("tinyEWD.txt")).read();
assertEquals(8, graph.getNodes());
assertEquals(2, count(graph.getOutgoing(0)));
@@ -39,7 +40,7 @@ public void testRead() {
@Test
public void testMediumRead() throws IOException {
- MemoryGraph graph = new MemoryGraph();
+ Graph graph = new MemoryGraphSafe(100);
new PrinctonReader(graph).setStream(new GZIPInputStream(PrinctonReader.class.getResourceAsStream("mediumEWD.txt.gz"))).read();
assertEquals(250, graph.getNodes());
assertEquals(13, count(graph.getOutgoing(244)));
View
13 core/src/test/java/de/jetsli/graph/routing/AbstractRoutingAlgorithmTester.java
@@ -15,16 +15,11 @@
*/
package de.jetsli.graph.routing;
-import de.jetsli.graph.reader.OSMReader;
import de.jetsli.graph.reader.PrinctonReader;
-import de.jetsli.graph.storage.MemoryGraph;
import de.jetsli.graph.storage.Graph;
-import de.jetsli.graph.storage.Location2IDIndex;
-import de.jetsli.graph.storage.Location2IDQuadtree;
-import de.jetsli.graph.util.CmdArgs;
-import de.jetsli.graph.util.Helper;
+import de.jetsli.graph.storage.MemoryGraph;
+import de.jetsli.graph.storage.MemoryGraphSafe;
import de.jetsli.graph.util.StopWatch;
-import java.io.File;
import java.io.IOException;
import java.util.Random;
import java.util.zip.GZIPInputStream;
@@ -249,7 +244,7 @@ public void testDirectedGraphBug1() {
private static Graph createMatrixAlikeGraph() {
int WIDTH = 10;
int HEIGHT = 15;
- Graph tmp = new MemoryGraph(WIDTH * HEIGHT);
+ Graph tmp = new MemoryGraphSafe(WIDTH * HEIGHT);
int[][] matrix = new int[WIDTH][HEIGHT];
int counter = 0;
Random rand = new Random(12);
@@ -291,6 +286,6 @@ private static Graph createMatrixAlikeGraph() {
}
Graph createGraph(int size) {
- return new MemoryGraph(size);
+ return new MemoryGraphSafe(size);
}
}
View
11 core/src/test/java/de/jetsli/graph/routing/ContractionHierarchiesTest.java
@@ -15,12 +15,9 @@
*/
package de.jetsli.graph.routing;
-import de.jetsli.graph.routing.ContractionHierarchies;
import static de.jetsli.graph.util.MyIteratorable.*;
-import de.jetsli.graph.storage.DistEntry;
-import de.jetsli.graph.storage.MemoryGraph;
import de.jetsli.graph.storage.Graph;
-import gnu.trove.set.hash.TIntHashSet;
+import de.jetsli.graph.storage.MemoryGraphSafe;
import org.junit.Test;
import static org.junit.Assert.*;
@@ -39,7 +36,7 @@
@Test
public void testSuperSimpleContract() {
- Graph g = new MemoryGraph(3);
+ Graph g = new MemoryGraphSafe(3);
g.edge(0, 1, 3, false);
g.edge(1, 2, 4, false);
@@ -63,7 +60,7 @@ public void testSuperSimpleContract() {
@Test
public void testIntroduceShortcut0_2() {
- Graph g = new MemoryGraph(5);
+ Graph g = new MemoryGraphSafe(5);
g.edge(0, 3, 2, false);
g.edge(3, 4, 3, false);
g.edge(4, 2, 1, false);
@@ -81,7 +78,7 @@ public void testIntroduceShortcut0_2() {
//@Test
public void DoNotIntroduceShortCut0_2() {
- Graph g = new MemoryGraph(5);
+ Graph g = new MemoryGraphSafe(5);
g.edge(0, 1, 3, false);
g.edge(1, 2, 4, false);
View
4 core/src/test/java/de/jetsli/graph/routing/DijkstraBidirectionRefTest.java
@@ -15,8 +15,8 @@
*/
package de.jetsli.graph.routing;
-import de.jetsli.graph.storage.MemoryGraph;
import de.jetsli.graph.storage.Graph;
+import de.jetsli.graph.storage.MemoryGraphSafe;
import org.junit.Test;
import static org.junit.Assert.*;
@@ -45,7 +45,7 @@ public void testAddSkipNodes() {
@Test
public void testCannotCalculateSP2() {
- Graph g = new MemoryGraph();
+ Graph g = new MemoryGraphSafe(10);
g.edge(0, 1, 1, false);
g.edge(1, 2, 1, false);
View
4 core/src/test/java/de/jetsli/graph/routing/DijkstraBidirectionTest.java
@@ -15,8 +15,8 @@
*/
package de.jetsli.graph.routing;
-import de.jetsli.graph.storage.MemoryGraph;
import de.jetsli.graph.storage.Graph;
+import de.jetsli.graph.storage.MemoryGraphSafe;
import org.junit.Test;
import static org.junit.Assert.*;
@@ -45,7 +45,7 @@ public void testAddSkipNodes() {
@Test
public void testCannotCalculateSP2() {
- Graph g = new MemoryGraph();
+ Graph g = new MemoryGraphSafe(10);
g.edge(0, 1, 1, false);
g.edge(1, 2, 1, false);
View
3  core/src/test/java/de/jetsli/graph/routing/rideshare/DijkstraShortestOf2ToPubTest.java
@@ -18,7 +18,6 @@
import de.jetsli.graph.routing.DijkstraBidirection;
import de.jetsli.graph.routing.Path;
import de.jetsli.graph.routing.RoutingAlgorithm;
-import de.jetsli.graph.storage.MemoryGraph;
import de.jetsli.graph.storage.Graph;
import org.junit.Test;
import static org.junit.Assert.*;
@@ -29,7 +28,7 @@
*/
public class DijkstraShortestOf2ToPubTest {
- public RoutingAlgorithm createDijkstra(MemoryGraph g) {
+ public RoutingAlgorithm createDijkstra(Graph g) {
return new DijkstraWhichToOne(g);
}
View
57 core/src/test/java/de/jetsli/graph/storage/AbstractGraphTester.java
@@ -16,8 +16,6 @@
package de.jetsli.graph.storage;
import de.jetsli.graph.util.EdgeIdIterator;
-import de.jetsli.graph.util.MyIteratorable;
-import java.util.Iterator;
import org.junit.Test;
import static org.junit.Assert.*;
import static de.jetsli.graph.util.MyIteratorable.*;
@@ -107,9 +105,12 @@ public void testClone() {
Graph g = createGraph(11);
g.edge(1, 2, 10, true);
g.setNode(0, 12, 23);
+ g.edge(1, 3, 10, true);
Graph clone = g.clone();
assertEquals(g.getNodes(), clone.getNodes());
assertEquals(count(g.getOutgoing(1)), count(clone.getOutgoing(1)));
+ clone.edge(1, 4, 10, true);
+ assertEquals(3, count(clone.getOutgoing(1)));
}
@Test
@@ -235,6 +236,11 @@ public void testCheckFirstNode() {
@Test
public void testDeleteNode() {
+ testDeleteNodes(20);
+ testDeleteNodes(6);
+ }
+
+ public void testDeleteNodes(int fillToSize) {
Graph g = createGraph(11);
g.setNode(0, 12, 23);
g.setNode(1, 38.33f, 235.3f);
@@ -243,6 +249,18 @@ public void testDeleteNode() {
g.setNode(4, 2, 1);
g.setNode(5, 2.5f, 1);
+ int deleted = 2;
+ for (int i = 6; i < fillToSize; i++) {
+ g.setNode(i, i * 1.5, i * 1.6);
+ if (i % 3 == 0) {
+ g.markNodeDeleted(i);
+ deleted ++;
+ } else {
+ g.edge(i, 0, 10 * i, true);
+ g.edge(i, fillToSize - 1, 10 * i, true);
+ }
+ }
+
g.edge(0, 1, 10, true);
g.edge(0, 3, 20, false);
g.edge(3, 5, 20, true);
@@ -251,14 +269,37 @@ public void testDeleteNode() {
g.markNodeDeleted(0);
g.markNodeDeleted(2);
// no deletion happend
- assertEquals(6, g.getNodes());
+ assertEquals(fillToSize, g.getNodes());
// now actually perform deletion
g.optimize();
- assertEquals(4, g.getNodes());
- assertEquals(38.33f, g.getLatitude(0), 1e-4);
- assertEquals(78, g.getLatitude(1), 1e-4);
- assertTrue(MyIteratorable.contains(g.getEdges(0), 3));
- assertFalse(MyIteratorable.contains(g.getEdges(0), 1));
+
+ assertEquals(fillToSize - deleted, g.getNodes());
+ int id1 = getIdOf(g, 38.33f);
+ assertEquals(235.3f, g.getLongitude(id1), 1e-4);
+ assertTrue(containsLatitude(g, g.getEdges(id1), 2.5));
+ assertFalse(containsLatitude(g, g.getEdges(id1), 12));
+
+ int id3 = getIdOf(g, 78);
+ assertEquals(89, g.getLongitude(id3), 1e-4);
+ assertTrue(containsLatitude(g, g.getEdges(id3), 2.5));
+ assertFalse(containsLatitude(g, g.getEdges(id3), 12));
+ }
+
+ public boolean containsLatitude(Graph g, EdgeIdIterator iter, double latitude) {
+ while (iter.next()) {
+ if (Math.abs(g.getLatitude(iter.nodeId()) - latitude) < 1e-4)
+ return true;
+ }
+ return false;
+ }
+
+ public int getIdOf(Graph g, double latitude) {
+ int s = g.getNodes();
+ for (int i = 0; i < s; i++) {
+ if (Math.abs(g.getLatitude(i) - latitude) < 1e-4)
+ return i;
+ }
+ return -1;
}
}
View
2  core/src/test/java/de/jetsli/graph/storage/MemoryGraphSafeTest.java
@@ -66,7 +66,7 @@ public void testSave() throws IOException {
assertEquals(3, graph.getNodes());
assertEquals(3, graph.getNodes());
checkGraph(graph);
-
+
graph.edge(3, 4, 123, true);
checkGraph(graph);
}
View
11 core/src/test/java/de/jetsli/graph/util/TopologicalSortingTest.java
@@ -15,7 +15,8 @@
*/
package de.jetsli.graph.util;
-import de.jetsli.graph.storage.MemoryGraph;
+import de.jetsli.graph.storage.Graph;
+import de.jetsli.graph.storage.MemoryGraphSafe;
import gnu.trove.list.array.TIntArrayList;
import org.junit.Test;
import static org.junit.Assert.*;
@@ -28,7 +29,7 @@
@Test
public void testSort() {
- MemoryGraph g = new MemoryGraph();
+ Graph g = new MemoryGraphSafe(20);
g.edge(7, 11, 1, false);
g.edge(7, 8, 1, false);
g.edge(5, 11, 1, false);
@@ -52,7 +53,7 @@ public void testSort() {
@Test
public void testSort2() {
- MemoryGraph g = new MemoryGraph();
+ Graph g = new MemoryGraphSafe(20);
g.edge(1, 2, 1, false);
g.edge(7, 2, 1, false);
g.edge(2, 0, 1, false);
@@ -79,7 +80,7 @@ public void testSort2() {
@Test
public void testSortWithCycle() {
- MemoryGraph g = new MemoryGraph();
+ Graph g = new MemoryGraphSafe(20);
g.edge(0, 1, 1, false);
g.edge(1, 2, 1, false);
g.edge(2, 0, 1, false);
@@ -92,7 +93,7 @@ public void testSortWithCycle() {
}
}
- private void checkOrder(MemoryGraph g, final TIntArrayList res, final int i) {
+ private void checkOrder(Graph g, final TIntArrayList res, final int i) {
final int prev = res.get(i - 1);
final int curr = res.get(i);
XFirstSearch search = new XFirstSearch() {
View
5 core/src/test/java/de/jetsli/graph/util/XFirstSearchTest.java
@@ -15,7 +15,8 @@
*/
package de.jetsli.graph.util;
-import de.jetsli.graph.storage.MemoryGraph;
+import de.jetsli.graph.storage.Graph;
+import de.jetsli.graph.storage.MemoryGraphSafe;
import gnu.trove.set.hash.TIntHashSet;
import org.junit.Before;
import org.junit.Test;
@@ -48,7 +49,7 @@ public boolean goFurther(int v) {
}
};
- MemoryGraph g = new MemoryGraph();
+ Graph g = new MemoryGraphSafe(20);
g.edge(0, 1, 85, true);
g.edge(0, 2, 217, true);
g.edge(0, 3, 173, true);
Please sign in to comment.
Something went wrong with that request. Please try again.