Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
systay committed May 22, 2018
1 parent 4c8d46d commit e126e5d
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 49 deletions.
Expand Up @@ -59,25 +59,4 @@ static boolean validValue( long[] arr, int width )
return true;
}

static Pair<LongArrayHashTable,Object[]> doubleInSize( LongArrayHashTable srcTable, Object[] srcValues )
{
LongArrayHashTable dstTable = new LongArrayHashTable( srcTable.capacity * 2, srcTable.width );
Object[] dstValues = new Object[srcTable.capacity * 2];
long[] srcKeys = srcTable.keys;
long[] dstKeys = dstTable.keys;
dstTable.numberOfEntries = srcTable.numberOfEntries;
for ( int fromSlot = 0; fromSlot < srcTable.capacity; fromSlot = fromSlot + 1 )
{
int width = srcTable.width;
int fromOffset = fromSlot * width;
if ( srcKeys[fromOffset] != NOT_IN_USE )
{
int toSlot = LongArrayHash.hashCode( srcKeys, fromOffset, width ) & dstTable.tableMask;
toSlot = dstTable.findUnusedSlot( toSlot );
System.arraycopy( srcKeys, fromOffset, dstKeys, toSlot * width, width );
dstValues[toSlot] = srcValues[fromSlot];
}
}
return Pair.of( dstTable, dstValues );
}
}
Expand Up @@ -128,7 +128,7 @@ public boolean isEmpty()

private void resize()
{
Pair<LongArrayHashTable,Object[]> resized = LongArrayHash.doubleInSize( table, values );
Pair<LongArrayHashTable,Object[]> resized = table.doubleCapacity( values );
table = resized.first();
values = resized.other();
}
Expand Down
Expand Up @@ -117,7 +117,7 @@ public boolean isEmpty()

private void resize()
{
Pair<LongArrayHashTable,Object[]> resized = LongArrayHash.doubleInSize( table, values );
Pair<LongArrayHashTable,Object[]> resized = table.doubleCapacity( values );
table = resized.first();
values = resized.other();
}
Expand Down
Expand Up @@ -22,7 +22,6 @@
import org.opencypher.v9_0.util.InternalException;

import static org.neo4j.cypher.internal.runtime.LongArrayHash.CONTINUE_PROBING;
import static org.neo4j.cypher.internal.runtime.LongArrayHash.NOT_IN_USE;
import static org.neo4j.cypher.internal.runtime.LongArrayHash.SLOT_EMPTY;
import static org.neo4j.cypher.internal.runtime.LongArrayHash.VALUE_FOUND;

Expand Down Expand Up @@ -72,7 +71,7 @@ public boolean add( long[] value )
if ( table.timeToResize() )
{
// We know we need to add the value to the set, but there is no space left
resize();
table = table.doubleCapacity();
// Need to restart linear probe after resizing
slotNr = slotFor( value );
}
Expand Down Expand Up @@ -117,26 +116,6 @@ public boolean contains( long[] value )
return result == VALUE_FOUND;
}

private void resize()
{
int oldSize = table.capacity;
int oldNumberEntries = table.numberOfEntries;
long[] srcArray = table.keys;
table = new LongArrayHashTable( oldSize * 2, width );
long[] dstArray = table.keys;
table.numberOfEntries = oldNumberEntries;

for ( int fromOffset = 0; fromOffset < oldSize * width; fromOffset = fromOffset + width )
{
if ( srcArray[fromOffset] != NOT_IN_USE )
{
int toSlot = LongArrayHash.hashCode( srcArray, fromOffset, width ) & table.tableMask;
toSlot = table.findUnusedSlot( toSlot );
System.arraycopy( srcArray, fromOffset, dstArray, toSlot * width, width );
}
}
}

private int slotFor( long[] value )
{
return LongArrayHash.hashCode( value, 0, width ) & table.tableMask;
Expand Down
Expand Up @@ -19,6 +19,8 @@
*/
package org.neo4j.cypher.internal.runtime;

import org.neo4j.helpers.collection.Pair;

import static org.neo4j.cypher.internal.runtime.LongArrayHash.CONTINUE_PROBING;
import static org.neo4j.cypher.internal.runtime.LongArrayHash.NOT_IN_USE;
import static org.neo4j.cypher.internal.runtime.LongArrayHash.SLOT_EMPTY;
Expand All @@ -32,7 +34,7 @@ class LongArrayHashTable
public final long[] keys;
public final int width;
public final int capacity;
int numberOfEntries;
private int numberOfEntries;
private int resizeLimit;

private static final double LOAD_FACTOR = 0.75;
Expand All @@ -52,6 +54,7 @@ class LongArrayHashTable
/**
* Signals whether it's time to size up or not. The actual resizing is done slightly differently depending on if this is a map or set. Maps have, in
* addition to a hash table also a separate array for the values.
*
* @return true if the number of keys in the hash table has reached capacity.
*/
boolean timeToResize()
Expand Down Expand Up @@ -91,6 +94,7 @@ int checkSlot( int slot, long[] key )

/**
* Writes the key to this slot.
*
* @param slot The slot to write to.
* @param key Le key.
*/
Expand All @@ -115,9 +119,10 @@ public boolean isEmpty()

/**
* Finds an slot not already claimed, starting from a given slot.
*
* @return First unused slot after fromSlot
*/
int findUnusedSlot( int fromSlot )
private int findUnusedSlot( int fromSlot )
{
while ( true )
{
Expand All @@ -129,4 +134,41 @@ int findUnusedSlot( int fromSlot )
}
}

LongArrayHashTable doubleCapacity()
{
LongArrayHashTable newTable = new LongArrayHashTable( capacity * 2, width );
newTable.numberOfEntries = numberOfEntries;

for ( int fromOffset = 0; fromOffset < capacity * width; fromOffset = fromOffset + width )
{
if ( keys[fromOffset] != NOT_IN_USE )
{
int toSlot = LongArrayHash.hashCode( keys, fromOffset, width ) & newTable.tableMask;
toSlot = newTable.findUnusedSlot( toSlot );
System.arraycopy( keys, fromOffset, newTable.keys, toSlot * width, width );
}
}

return newTable;
}

Pair<LongArrayHashTable,Object[]> doubleCapacity( Object[] srcValues )
{
LongArrayHashTable dstTable = new LongArrayHashTable( capacity * 2, width );
Object[] dstValues = new Object[capacity * 2];
long[] srcKeys = keys;
dstTable.numberOfEntries = numberOfEntries;
for ( int fromSlot = 0; fromSlot < capacity; fromSlot = fromSlot + 1 )
{
int fromOffset = fromSlot * width;
if ( srcKeys[fromOffset] != NOT_IN_USE )
{
int toSlot = LongArrayHash.hashCode( srcKeys, fromOffset, width ) & dstTable.tableMask;
toSlot = dstTable.findUnusedSlot( toSlot );
System.arraycopy( srcKeys, fromOffset, dstTable.keys, toSlot * width, width );
dstValues[toSlot] = srcValues[fromSlot];
}
}
return Pair.of( dstTable, dstValues );
}
}
Expand Up @@ -42,7 +42,7 @@ class LongArrayHashMapTest extends FunSuite with Matchers {
resultAsSet(map) should equal(Set.empty)
}

test("fill and resize") {
test("fill and doubleCapacity") {
val map = new LongArrayHashMap[String](8, 3)
map.getOrCreateAndAdd(Array(0L, 8L, 1L), () => "hello")
map.getOrCreateAndAdd(Array(0L, 7L, 2L), () => "is")
Expand Down
Expand Up @@ -41,7 +41,7 @@ class LongArrayHashMultiMapTest extends FunSuite with Matchers {
map.isEmpty should equal(true)
}

test("fill and resize") {
test("fill and doubleCapacity") {
val map = new LongArrayHashMultiMap[String](8, 3)
map.add(Array(0L, 8L, 1L), "hello")
map.add(Array(0L, 7L, 2L), "is")
Expand Down

0 comments on commit e126e5d

Please sign in to comment.