Skip to content

Commit

Permalink
Minor GeometryType/GeometryArrayType clarifications
Browse files Browse the repository at this point in the history
  • Loading branch information
tinwelint committed Oct 1, 2018
1 parent f26e3cb commit 0975bb0
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 10 deletions.
Expand Up @@ -24,6 +24,7 @@
import org.neo4j.graphdb.spatial.Point; import org.neo4j.graphdb.spatial.Point;
import org.neo4j.io.pagecache.PageCursor; import org.neo4j.io.pagecache.PageCursor;
import org.neo4j.values.storable.CoordinateReferenceSystem; import org.neo4j.values.storable.CoordinateReferenceSystem;
import org.neo4j.values.storable.PointArray;
import org.neo4j.values.storable.PointValue; import org.neo4j.values.storable.PointValue;
import org.neo4j.values.storable.Value; import org.neo4j.values.storable.Value;
import org.neo4j.values.storable.ValueGroup; import org.neo4j.values.storable.ValueGroup;
Expand All @@ -34,14 +35,23 @@
import static org.neo4j.collection.PrimitiveLongCollections.EMPTY_LONG_ARRAY; import static org.neo4j.collection.PrimitiveLongCollections.EMPTY_LONG_ARRAY;
import static org.neo4j.kernel.impl.index.schema.GeometryType.assertHasCoordinates; import static org.neo4j.kernel.impl.index.schema.GeometryType.assertHasCoordinates;
import static org.neo4j.kernel.impl.index.schema.GeometryType.dimensions; import static org.neo4j.kernel.impl.index.schema.GeometryType.dimensions;
import static org.neo4j.kernel.impl.index.schema.GeometryType.put;
import static org.neo4j.kernel.impl.index.schema.GeometryType.putCrs; import static org.neo4j.kernel.impl.index.schema.GeometryType.putCrs;
import static org.neo4j.kernel.impl.index.schema.GeometryType.putPoint;
import static org.neo4j.kernel.impl.index.schema.GeometryType.readCrs; import static org.neo4j.kernel.impl.index.schema.GeometryType.readCrs;


/**
* Handles {@link PointValue[]}.
*
* Note about lazy initialization of {@link GenericKeyState} data structures: a point type is special in that it contains a {@link CoordinateReferenceSystem},
* which dictates how much space it will occupy. When serializing a {@link PointArray} into {@link GenericKeyState} (via the logic in this class)
* the {@link CoordinateReferenceSystem} isn't known at initialization, where only the type and array length is known.
* This is why some state is initialize lazily when observing the first point in the array.
*/
class GeometryArrayType extends AbstractArrayType<PointValue> class GeometryArrayType extends AbstractArrayType<PointValue>
{ {
// Affected key state: // Affected key state:
// long0Array (rawValueBits) // long0Array (rawValueBits)
// long1Array (coordinates)
// long1 (coordinate reference system tableId) // long1 (coordinate reference system tableId)
// long2 (coordinate reference system code) // long2 (coordinate reference system code)


Expand Down Expand Up @@ -81,8 +91,7 @@ void initializeArray( GenericKeyState key, int length, ValueWriter.ArrayType arr
key.long0Array = ensureBigEnough( key.long0Array, length ); key.long0Array = ensureBigEnough( key.long0Array, length );


// Since this method is called when serializing a PointValue into the key state, the CRS and number of dimensions // Since this method is called when serializing a PointValue into the key state, the CRS and number of dimensions
// are unknown at this point. Instead key.long1Array will be initialized lazily upon observing the first array item, // are unknown at this point. Read more about why lazy initialization is required in the class-level javadoc.
// because that's when we first will know that information.
if ( length == 0 && key.long1Array == null ) if ( length == 0 && key.long1Array == null )
{ {
// There's this special case where we're initializing an empty geometry array and so the long1Array // There's this special case where we're initializing an empty geometry array and so the long1Array
Expand Down Expand Up @@ -110,7 +119,7 @@ void putValue( PageCursor cursor, GenericKeyState state )
{ {
putCrs( cursor, state.long1, state.long2, state.long3 ); putCrs( cursor, state.long1, state.long2, state.long3 );
int dimensions = dimensions( state ); int dimensions = dimensions( state );
putArray( cursor, state, ( c, k, i ) -> put( c, state.long0Array[i], state.long3, state.long1Array, i * dimensions ) ); putArray( cursor, state, ( c, k, i ) -> putPoint( c, k.long0Array[i], k.long3, k.long1Array, i * dimensions ) );
} }


@Override @Override
Expand All @@ -133,8 +142,7 @@ private static boolean readGeometryArrayItem( PageCursor cursor, GenericKeyState
int dimensions = dimensions( into ); int dimensions = dimensions( into );
if ( into.currentArrayOffset == 0 ) if ( into.currentArrayOffset == 0 )
{ {
// Initialize the coordinates array lazily because we don't know the dimension count // Read more about why lazy initialization is required in the class-level javadoc.
// when initializeArray is called, only afterwards when the header have been read.
into.long1Array = ensureBigEnough( into.long1Array, dimensions * into.arrayLength ); into.long1Array = ensureBigEnough( into.long1Array, dimensions * into.arrayLength );
} }
for ( int i = 0, offset = into.currentArrayOffset * dimensions; i < dimensions; i++ ) for ( int i = 0, offset = into.currentArrayOffset * dimensions; i < dimensions; i++ )
Expand All @@ -150,6 +158,7 @@ void write( GenericKeyState state, int offset, long derivedSpaceFillingCurveValu
state.long0Array[offset] = derivedSpaceFillingCurveValue; state.long0Array[offset] = derivedSpaceFillingCurveValue;
if ( offset == 0 ) if ( offset == 0 )
{ {
// Read more about why lazy initialization is required in the class-level javadoc.
int dimensions = coordinates.length; int dimensions = coordinates.length;
state.long1Array = ensureBigEnough( state.long1Array, dimensions * state.arrayLength ); state.long1Array = ensureBigEnough( state.long1Array, dimensions * state.arrayLength );
state.long3 = dimensions; state.long3 = dimensions;
Expand Down
Expand Up @@ -108,13 +108,13 @@ int compareValue( GenericKeyState left, GenericKeyState right )
void putValue( PageCursor cursor, GenericKeyState state ) void putValue( PageCursor cursor, GenericKeyState state )
{ {
putCrs( cursor, state.long1, state.long2, state.long3 ); putCrs( cursor, state.long1, state.long2, state.long3 );
put( cursor, state.long0, state.long3, state.long1Array, 0 ); putPoint( cursor, state.long0, state.long3, state.long1Array, 0 );
} }


@Override @Override
boolean readValue( PageCursor cursor, int size, GenericKeyState into ) boolean readValue( PageCursor cursor, int size, GenericKeyState into )
{ {
return readCrs( cursor, into ) && read( cursor, into ); return readCrs( cursor, into ) && readPoint( cursor, into );
} }


@Override @Override
Expand Down Expand Up @@ -164,7 +164,7 @@ private static void assertValueWithin( long value, int maskAllowed, String name
} }
} }


static void put( PageCursor cursor, long long0, long long3, long[] long1Array, int long1ArrayOffset ) static void putPoint( PageCursor cursor, long long0, long long3, long[] long1Array, int long1ArrayOffset )
{ {
assertHasCoordinates( long3, long1Array ); assertHasCoordinates( long3, long1Array );
cursor.putLong( long0 ); cursor.putLong( long0 );
Expand Down Expand Up @@ -207,7 +207,7 @@ static boolean readCrs( PageCursor cursor, GenericKeyState into )
return true; return true;
} }


static boolean read( PageCursor cursor, GenericKeyState into ) static boolean readPoint( PageCursor cursor, GenericKeyState into )
{ {
into.long0 = cursor.getLong(); into.long0 = cursor.getLong();
// into.long3 have just been read by readCrs, before this method is called // into.long3 have just been read by readCrs, before this method is called
Expand Down

0 comments on commit 0975bb0

Please sign in to comment.