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


private void resize() private void resize()
{ {
Pair<LongArrayHashTable,Object[]> resized = LongArrayHash.doubleInSize( table, values ); Pair<LongArrayHashTable,Object[]> resized = table.doubleCapacity( values );
table = resized.first(); table = resized.first();
values = resized.other(); values = resized.other();
} }
Expand Down
Expand Up @@ -22,7 +22,6 @@
import org.opencypher.v9_0.util.InternalException; 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.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.SLOT_EMPTY;
import static org.neo4j.cypher.internal.runtime.LongArrayHash.VALUE_FOUND; 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() ) if ( table.timeToResize() )
{ {
// We know we need to add the value to the set, but there is no space left // 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 // Need to restart linear probe after resizing
slotNr = slotFor( value ); slotNr = slotFor( value );
} }
Expand Down Expand Up @@ -117,26 +116,6 @@ public boolean contains( long[] value )
return result == VALUE_FOUND; 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 ) private int slotFor( long[] value )
{ {
return LongArrayHash.hashCode( value, 0, width ) & table.tableMask; return LongArrayHash.hashCode( value, 0, width ) & table.tableMask;
Expand Down
Expand Up @@ -19,6 +19,8 @@
*/ */
package org.neo4j.cypher.internal.runtime; 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.CONTINUE_PROBING;
import static org.neo4j.cypher.internal.runtime.LongArrayHash.NOT_IN_USE; 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.SLOT_EMPTY;
Expand All @@ -32,7 +34,7 @@ class LongArrayHashTable
public final long[] keys; public final long[] keys;
public final int width; public final int width;
public final int capacity; public final int capacity;
int numberOfEntries; private int numberOfEntries;
private int resizeLimit; private int resizeLimit;


private static final double LOAD_FACTOR = 0.75; 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 * 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. * 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. * @return true if the number of keys in the hash table has reached capacity.
*/ */
boolean timeToResize() boolean timeToResize()
Expand Down Expand Up @@ -91,6 +94,7 @@ int checkSlot( int slot, long[] key )


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


/** /**
* Finds an slot not already claimed, starting from a given slot. * Finds an slot not already claimed, starting from a given slot.
*
* @return First unused slot after fromSlot * @return First unused slot after fromSlot
*/ */
int findUnusedSlot( int fromSlot ) private int findUnusedSlot( int fromSlot )
{ {
while ( true ) 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) resultAsSet(map) should equal(Set.empty)
} }


test("fill and resize") { test("fill and doubleCapacity") {
val map = new LongArrayHashMap[String](8, 3) val map = new LongArrayHashMap[String](8, 3)
map.getOrCreateAndAdd(Array(0L, 8L, 1L), () => "hello") map.getOrCreateAndAdd(Array(0L, 8L, 1L), () => "hello")
map.getOrCreateAndAdd(Array(0L, 7L, 2L), () => "is") 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) map.isEmpty should equal(true)
} }


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

0 comments on commit e126e5d

Please sign in to comment.