Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

LinkBlock

  • Loading branch information...
commit a179320bf1841272463f9f2ad36a07a647033ffc 1 parent 4165990
@tinwelint authored
View
2  community/kernel/src/main/java/org/neo4j/helpers/Enc128.java
@@ -31,7 +31,7 @@
*/
public int encode( ByteBuffer target, long value )
{
- assert value >= 0;
+ assert value >= 0 : "Invalid value " + value;
int startPosition = target.position();
while ( true )
View
130 community/kernel/src/main/java/org/neo4j/helpers/LinkBlock.java
@@ -0,0 +1,130 @@
+/**
+ * Copyright (c) 2002-2013 "Neo Technology,"
+ * Network Engine for Objects in Lund AB [http://neotechnology.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.neo4j.helpers;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.Comparator;
+
+public class LinkBlock
+{
+ private static final int HEADER_SIZE = 8+8+4+4;
+ private final Enc128 encoder = new Enc128();
+ private final Type type;
+ private final ByteBuffer buffer;
+ private int idCount;
+ private long firstRelId, lastRelId;
+
+ public LinkBlock( Type type )
+ {
+ this.type = type;
+ this.buffer = type.allocateBuffer();
+ }
+
+ public void set( long[][] relAndNodeIdPairs )
+ {
+ Arrays.sort( relAndNodeIdPairs, SORTER );
+
+ // Header
+ buffer.putLong( (firstRelId = relAndNodeIdPairs[0][0]) );
+ buffer.putLong( (lastRelId = relAndNodeIdPairs[relAndNodeIdPairs.length-1][0]) );
+ buffer.putInt( (idCount = relAndNodeIdPairs.length) );
+
+ // Ids
+ long previousRelId = relAndNodeIdPairs[0][0], previousRelNodeDelta = relAndNodeIdPairs[0][1] - previousRelId;
+ encoder.encode( buffer, previousRelId );
+ encoder.encode( buffer, previousRelNodeDelta );
+ for ( int i = 1; i < relAndNodeIdPairs.length; i++ )
+ {
+ long[] pair = relAndNodeIdPairs[i];
+ long relDelta = pair[0]-previousRelId;
+ long relNodeDelta = pair[1]-pair[0];
+ long derivativeRelNodeDelta = relNodeDelta-previousRelNodeDelta;
+ encoder.encode( buffer, relDelta );
+ encoder.encode( buffer, derivativeRelNodeDelta );
+ previousRelId = pair[0];
+ previousRelNodeDelta = relNodeDelta;
+ }
+ }
+
+ public void get( long[][] target )
+ {
+ assert target.length >= idCount;
+
+ // Header
+ buffer.position( HEADER_SIZE );
+
+ target[0][0] = encoder.decode( buffer );
+ target[0][1] = target[0][0] + encoder.decode( buffer );
+ for ( int i = 1; i < target.length; i++ )
+ {
+ long relDelta = encoder.decode( buffer );
+ long relId = target[i-1][0] + relDelta;
+ long derivativeRelNodeDelta = encoder.decode( buffer );
+ long previousRelNodeDelta = target[i-1][1] - target[i-1][0];
+ target[i][0] = relId;
+ target[i][1] = previousRelNodeDelta + relId + derivativeRelNodeDelta;
+ }
+ }
+
+ // TODO method for looking up a node for a relationship
+
+ private static final Comparator<long[]> SORTER = new Comparator<long[]>()
+ {
+ @Override
+ public int compare( long[] o1, long[] o2 )
+ {
+ return Long.compare( o1[0], o2[0] );
+ }
+ };
+
+ public static enum Type
+ {
+ // TODO think about sizes
+ SMALL( 256 ),
+ MEDIUM( 256*256 ),
+ LARGE( 256*256*256 );
+
+ private final int byteSize;
+
+ private Type( int byteSize )
+ {
+ this.byteSize = byteSize;
+ }
+
+ int byteSize()
+ {
+ return byteSize;
+ }
+
+ ByteBuffer allocateBuffer()
+ {
+ ByteBuffer result = ByteBuffer.allocate( byteSize );
+ result.putInt( byteSize() );
+ return result;
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return getClass().getSimpleName() + "[" + buffer + "]";
+ }
+}
View
73 community/kernel/src/test/java/org/neo4j/helpers/LinkBlockTest.java
@@ -0,0 +1,73 @@
+/**
+ * Copyright (c) 2002-2013 "Neo Technology,"
+ * Network Engine for Objects in Lund AB [http://neotechnology.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.neo4j.helpers;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import org.junit.Test;
+
+public class LinkBlockTest
+{
+ @Test
+ public void setSinglePair() throws Exception
+ {
+ // GIVEN
+ LinkBlock block = new LinkBlock( LinkBlock.Type.SMALL );
+ long[][] expected = idPairs( 10, 10, 1 );
+ block.set( expected );
+
+ // WHEN
+ long[][] read = new long[1][2];
+ block.get( read );
+
+ // THEN
+ assertArrayEquals( expected[0], read[0] );
+ }
+
+ @Test
+ public void setManyPairs() throws Exception
+ {
+ // GIVEN
+ LinkBlock block = new LinkBlock( LinkBlock.Type.LARGE );
+ long[][] expected = idPairs( 5, 10, 10000 );
+ block.set( expected );
+ System.out.println( block );
+
+ // WHEN
+ long[][] read = new long[expected.length][2];
+ block.get( read );
+
+ for ( int i = 0; i < read.length; i++ )
+ {
+ assertArrayEquals( "At index " + i, expected[i], read[i] );
+ }
+ }
+
+ private long[][] idPairs( long firstRelId, long firstNodeId, int count )
+ {
+ long result[][] = new long[count][2];
+ for ( int i = 0; i < count; i++ )
+ {
+ result[i][0] = firstRelId+i;
+ result[i][1] = firstNodeId+i;
+ }
+ return result;
+ }
+}

0 comments on commit a179320

Please sign in to comment.
Something went wrong with that request. Please try again.