Skip to content

Commit 86c6a8c

Browse files
author
Hendrik Leuschner
committed
Use bitset to store borderness data 8 times as dense as before
1 parent 710d374 commit 86c6a8c

File tree

2 files changed

+28
-15
lines changed

2 files changed

+28
-15
lines changed

openrouteservice/src/main/java/org/heigit/ors/fastisochrones/partitioning/storage/IsochroneNodeStorage.java

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@
2323
import com.graphhopper.storage.Directory;
2424
import com.graphhopper.storage.Storable;
2525

26-
import static org.heigit.ors.fastisochrones.storage.ByteConversion.byteArrayToInteger;
27-
import static org.heigit.ors.fastisochrones.storage.ByteConversion.intToByteArray;
26+
import java.util.BitSet;
27+
28+
import static org.heigit.ors.fastisochrones.storage.ByteConversion.*;
2829

2930
/**
3031
* Storage that maps nodeIds to their respective cells and borderness.
@@ -41,10 +42,10 @@ public class IsochroneNodeStorage implements Storable<IsochroneNodeStorage> {
4142
public IsochroneNodeStorage(int nodeCount, Directory dir) {
4243
isochroneNodes = dir.find("isochronenodes");
4344
this.nodeCount = nodeCount;
44-
// 1 byte for isBordernode,
4545
// 4 bytes per node for its cell id.
4646
// Maximum cell id = Integer.MAX_VALUE
47-
this.cellBytes = 5;
47+
// Borderness of nodes is stored in a block after cellIds block. As it is one bit per node, it is condensed into blocks of 8 node information per byte.
48+
this.cellBytes = 4;
4849
}
4950

5051
@Override
@@ -60,24 +61,21 @@ public boolean loadExisting() {
6061
public void setBorderness(boolean[] borderness) {
6162
if (nodeCount != borderness.length)
6263
throw new IllegalStateException("Nodecount and borderness array do not match");
63-
isochroneNodes.ensureCapacity((long) cellBytes * nodeCount);
64-
for (int node = 0; node < borderness.length; node++) {
65-
if (borderness[node])
66-
isochroneNodes.setBytes((long) node * cellBytes, new byte[]{(byte) 1}, 1);
67-
else
68-
isochroneNodes.setBytes((long) node * cellBytes, new byte[]{(byte) 0}, 1);
69-
}
64+
BitSet bordernessBits = booleanArrayToBitSet(borderness);
65+
byte[] denseBorderness = bordernessBits.toByteArray();
66+
isochroneNodes.ensureCapacity((long) cellBytes * nodeCount + denseBorderness.length);
67+
isochroneNodes.setBytes(nodeCount * cellBytes + 1 , denseBorderness, denseBorderness.length);
7068
}
7169

7270
public boolean getBorderness(int node) {
7371
byte[] buffer = new byte[1];
74-
isochroneNodes.getBytes((long) node * cellBytes, buffer, 1);
75-
return buffer[0] == 1;
72+
isochroneNodes.getBytes((long) nodeCount * cellBytes + 1 + node / 8, buffer, 1);
73+
return isByteSetAtPosition(buffer[0], (byte)(node % 8));
7674
}
7775

7876
public int getCellId(int node) {
7977
byte[] buffer = new byte[4];
80-
isochroneNodes.getBytes((long) node * cellBytes + 1, buffer, 4);
78+
isochroneNodes.getBytes((long) node * cellBytes, buffer, 4);
8179
return byteArrayToInteger(buffer);
8280
}
8381

@@ -93,7 +91,7 @@ public void setCellIds(int[] cellIds) {
9391
for (int node = 0; node < cellIds.length; node++) {
9492
int cellId = cellIds[node];
9593
cellIdsSet.add(cellId);
96-
isochroneNodes.setBytes((long) node * cellBytes + 1, intToByteArray(cellId), 4);
94+
isochroneNodes.setBytes((long) node * cellBytes, intToByteArray(cellId), 4);
9795
}
9896
}
9997

openrouteservice/src/main/java/org/heigit/ors/fastisochrones/storage/ByteConversion.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.heigit.ors.fastisochrones.storage;
22

33
import java.nio.ByteBuffer;
4+
import java.util.BitSet;
45

56
public class ByteConversion {
67
private ByteConversion() {
@@ -41,4 +42,18 @@ public static int byteArrayToInteger(byte[] bytes) {
4142
throw new IllegalArgumentException("Byte counts do not match, expected " + Integer.BYTES + " but is " + bytes.length);
4243
return ByteBuffer.wrap(bytes).getInt();
4344
}
45+
46+
public static BitSet booleanArrayToBitSet(boolean[] bits) {
47+
BitSet bitset = new BitSet(bits.length);
48+
for (int i = 0; i < bits.length; i++)
49+
bitset.set(i, bits[i]);
50+
51+
return bitset;
52+
}
53+
54+
public static boolean isByteSetAtPosition(byte byteToCheck, byte position)
55+
{
56+
int newByte = byteToCheck >> position;
57+
return (newByte & 1) == 1;
58+
}
4459
}

0 commit comments

Comments
 (0)