Skip to content

Commit

Permalink
Add zoned time layout
Browse files Browse the repository at this point in the history
  • Loading branch information
fickludd committed Mar 9, 2018
1 parent 4294a62 commit 16fde87
Show file tree
Hide file tree
Showing 9 changed files with 211 additions and 6 deletions.
Expand Up @@ -254,7 +254,7 @@ public PartAccessor<?> newLocalTime() throws IOException
@Override @Override
public PartAccessor<?> newZonedTime() throws IOException public PartAccessor<?> newZonedTime() throws IOException
{ {
throw new UnsupportedOperationException( "no comprende" ); return createPartAccessor( temporalIndexFiles.zonedTime() );
} }


@Override @Override
Expand Down
Expand Up @@ -36,7 +36,7 @@ class TemporalIndexFiles
private FileLayout<LocalDateTimeSchemaKey> localDateTime; private FileLayout<LocalDateTimeSchemaKey> localDateTime;
private FileLayout<ZonedDateTimeSchemaKey> zonedDateTime; private FileLayout<ZonedDateTimeSchemaKey> zonedDateTime;
private FileLayout<LocalTimeSchemaKey> localTime; private FileLayout<LocalTimeSchemaKey> localTime;
private FileLayout zonedTime; private FileLayout<ZonedTimeSchemaKey> zonedTime;
private FileLayout duration; private FileLayout duration;


TemporalIndexFiles( IndexDirectoryStructure directoryStructure, long indexId, IndexDescriptor descriptor, FileSystemAbstraction fs ) TemporalIndexFiles( IndexDirectoryStructure directoryStructure, long indexId, IndexDescriptor descriptor, FileSystemAbstraction fs )
Expand All @@ -45,6 +45,7 @@ class TemporalIndexFiles
File indexDirectory = directoryStructure.directoryForIndex( indexId ); File indexDirectory = directoryStructure.directoryForIndex( indexId );
this.date = new FileLayout<>( new File( indexDirectory, "date" ), DateLayout.of( descriptor ), ValueGroup.DATE ); this.date = new FileLayout<>( new File( indexDirectory, "date" ), DateLayout.of( descriptor ), ValueGroup.DATE );
this.localTime = new FileLayout<>( new File( indexDirectory, "localTime" ), LocalTimeLayout.of( descriptor ), ValueGroup.LOCAL_TIME ); this.localTime = new FileLayout<>( new File( indexDirectory, "localTime" ), LocalTimeLayout.of( descriptor ), ValueGroup.LOCAL_TIME );
this.zonedTime = new FileLayout<>( new File( indexDirectory, "zonedTime" ), ZonedTimeLayout.of( descriptor ), ValueGroup.ZONED_TIME );
this.localDateTime = new FileLayout<>( new File( indexDirectory, "localDateTime" ), LocalDateTimeLayout.of( descriptor ), ValueGroup.LOCAL_DATE_TIME ); this.localDateTime = new FileLayout<>( new File( indexDirectory, "localDateTime" ), LocalDateTimeLayout.of( descriptor ), ValueGroup.LOCAL_DATE_TIME );
this.zonedDateTime = new FileLayout<>( new File( indexDirectory, "zonedDateTime" ), ZonedDateTimeLayout.of( descriptor ), ValueGroup.ZONED_DATE_TIME ); this.zonedDateTime = new FileLayout<>( new File( indexDirectory, "zonedDateTime" ), ZonedDateTimeLayout.of( descriptor ), ValueGroup.ZONED_DATE_TIME );
} }
Expand Down Expand Up @@ -79,6 +80,11 @@ FileLayout<LocalTimeSchemaKey> localTime()
return localTime; return localTime;
} }


FileLayout<ZonedTimeSchemaKey> zonedTime()
{
return zonedTime;
}

FileLayout<LocalDateTimeSchemaKey> localDateTime() FileLayout<LocalDateTimeSchemaKey> localDateTime()
{ {
return localDateTime; return localDateTime;
Expand Down
Expand Up @@ -116,7 +116,7 @@ public IndexUpdater newLocalTime() throws IOException
@Override @Override
public IndexUpdater newZonedTime() throws IOException public IndexUpdater newZonedTime() throws IOException
{ {
throw new UnsupportedOperationException( "too tired to write" ); return populator.zonedTime().newPopulatingUpdater( propertyAccessor );
} }


@Override @Override
Expand Down
Expand Up @@ -268,7 +268,7 @@ public PartPopulator<?> newLocalTime() throws IOException
@Override @Override
public PartPopulator<?> newZonedTime() throws IOException public PartPopulator<?> newZonedTime() throws IOException
{ {
throw new UnsupportedOperationException( "not implementedur still" ); return create( temporalIndexFiles.zonedTime() );
} }


@Override @Override
Expand Down
Expand Up @@ -163,7 +163,7 @@ public TemporalIndexPartReader<?> newLocalTime()
@Override @Override
public TemporalIndexPartReader<?> newZonedTime() public TemporalIndexPartReader<?> newZonedTime()
{ {
throw new UnsupportedOperationException( "Illiterate" ); return accessor.selectOrElse( ValueGroup.ZONED_TIME, TemporalIndexAccessor.PartAccessor::newReader, null );
} }


@Override @Override
Expand Down
Expand Up @@ -109,7 +109,7 @@ public NativeSchemaIndexUpdater<?, NativeSchemaValue> newLocalTime() throws IOEx
@Override @Override
public NativeSchemaIndexUpdater<?, NativeSchemaValue> newZonedTime() throws IOException public NativeSchemaIndexUpdater<?, NativeSchemaValue> newZonedTime() throws IOException
{ {
throw new UnsupportedOperationException( "ma-a-da dayo" ); return accessor.zonedTime().newUpdater( mode );
} }


@Override @Override
Expand Down
@@ -0,0 +1,90 @@
/*
* Copyright (c) 2002-2018 "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.kernel.impl.index.schema;

import java.util.Comparator;

import org.neo4j.index.internal.gbptree.Layout;
import org.neo4j.io.pagecache.PageCursor;
import org.neo4j.kernel.api.schema.index.IndexDescriptor;

/**
* {@link Layout} for absolute times.
*/
class ZonedTimeLayout extends BaseLayout<ZonedTimeSchemaKey>
{
public static Layout<ZonedTimeSchemaKey,NativeSchemaValue> of( IndexDescriptor descriptor )
{
return descriptor.type() == IndexDescriptor.Type.UNIQUE ? ZonedTimeLayout.UNIQUE : ZonedTimeLayout.NON_UNIQUE;
}

private static final ZonedTimeLayout UNIQUE = new ZonedTimeLayout( "UTzt", 0, 1, ComparableNativeSchemaKey.UNIQUE() );
private static final ZonedTimeLayout NON_UNIQUE = new ZonedTimeLayout( "NTzt", 0, 1, ComparableNativeSchemaKey.NON_UNIQUE() );

private ZonedTimeLayout(
String layoutName, int majorVersion, int minorVersion, Comparator<ZonedTimeSchemaKey> comparator )
{
super( layoutName, majorVersion, minorVersion, comparator );
}

@Override
public ZonedTimeSchemaKey newKey()
{
return new ZonedTimeSchemaKey();
}

@Override
public ZonedTimeSchemaKey copyKey( ZonedTimeSchemaKey key, ZonedTimeSchemaKey into )
{
into.nanosOfDayUTC = key.nanosOfDayUTC;
into.zoneOffsetSeconds = key.zoneOffsetSeconds;
into.setEntityId( key.getEntityId() );
into.setCompareId( key.getCompareId() );
return into;
}

@Override
public int keySize( ZonedTimeSchemaKey key )
{
return ZonedTimeSchemaKey.SIZE;
}

@Override
public void writeKey( PageCursor cursor, ZonedTimeSchemaKey key )
{
cursor.putLong( key.nanosOfDayUTC );
cursor.putInt( key.zoneOffsetSeconds );
cursor.putLong( key.getEntityId() );
}

@Override
public void readKey( PageCursor cursor, ZonedTimeSchemaKey into, int keySize )
{
into.nanosOfDayUTC = cursor.getLong();
into.zoneOffsetSeconds = cursor.getInt();
into.setEntityId( cursor.getLong() );
}

@Override
public boolean fixedSize()
{
return true;
}
}
@@ -0,0 +1,101 @@
/*
* Copyright (c) 2002-2018 "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.kernel.impl.index.schema;

import java.time.ZoneOffset;

import org.neo4j.values.storable.TimeValue;
import org.neo4j.values.storable.Value;

import static java.lang.String.format;

/**
* Includes value and entity id (to be able to handle non-unique values). A value can be any {@link TimeValue}.
*
* With these keys the TimeValues are sorted by UTC time of day, and then by time zone.
*/
class ZonedTimeSchemaKey extends TemporalSchemaKey implements ComparableNativeSchemaKey<ZonedTimeSchemaKey>
{
static final int SIZE =
Long.BYTES + /* nanosOfDayUTC */
Integer.BYTES + /* zoneOffsetSeconds */
Long.BYTES; /* entityId */

long nanosOfDayUTC;
int zoneOffsetSeconds;

@Override
public Value asValue()
{
return TimeValue.time( nanosOfDayUTC, ZoneOffset.ofTotalSeconds( zoneOffsetSeconds ) );
}

@Override
public void initAsLowest()
{
super.initAsLowest();
nanosOfDayUTC = Long.MIN_VALUE;
zoneOffsetSeconds = Integer.MIN_VALUE;
}

@Override
public void initAsHighest()
{
super.initAsHighest();
nanosOfDayUTC = Long.MAX_VALUE;
zoneOffsetSeconds = Integer.MAX_VALUE;
}

@Override
public int compareValueTo( ZonedTimeSchemaKey other )
{
int compare = Long.compare( nanosOfDayUTC, other.nanosOfDayUTC );
if ( compare == 0 )
{
compare = Integer.compare( zoneOffsetSeconds, other.zoneOffsetSeconds );
}
return compare;
}

@Override
public String toString()
{
return format( "value=%s,entityId=%d,nanosOfDayUTC=%d,zoneOffsetSeconds=%d",
asValue(), entityId, nanosOfDayUTC, zoneOffsetSeconds );
}

@Override
public void writeTime( long nanosOfDayUTC, int offsetSeconds )
{
this.nanosOfDayUTC = nanosOfDayUTC;
this.zoneOffsetSeconds = offsetSeconds;
}

@Override
protected Value assertCorrectType( Value value )
{
if ( !(value instanceof TimeValue) )
{
throw new IllegalArgumentException(
"Key layout does only support TimeValue, tried to create key from " + value );
}
return value;
}
}
Expand Up @@ -25,6 +25,8 @@
import org.junit.runners.Suite; import org.junit.runners.Suite;


import java.io.File; import java.io.File;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
Expand All @@ -41,6 +43,7 @@
import org.neo4j.values.storable.DateValue; import org.neo4j.values.storable.DateValue;
import org.neo4j.values.storable.LocalDateTimeValue; import org.neo4j.values.storable.LocalDateTimeValue;
import org.neo4j.values.storable.LocalTimeValue; import org.neo4j.values.storable.LocalTimeValue;
import org.neo4j.values.storable.TimeValue;
import org.neo4j.values.storable.Value; import org.neo4j.values.storable.Value;
import org.neo4j.values.storable.Values; import org.neo4j.values.storable.Values;


Expand Down Expand Up @@ -97,6 +100,10 @@ public Compatibility( IndexProviderCompatibilityTestSuite testSuite, IndexDescri
Arrays.asList( Arrays.asList(
DateValue.epochDate( 2 ), DateValue.epochDate( 2 ),
LocalTimeValue.localTime( 100000 ), LocalTimeValue.localTime( 100000 ),
TimeValue.time( 43_200_000_000_000L, ZoneOffset.UTC ), // Noon
TimeValue.time( 43_201_000_000_000L, ZoneOffset.UTC ),
TimeValue.time( 43_200_000_000_000L, ZoneId.of( "+01:00" ) ), // Noon in the next time-zone
TimeValue.time( 46_800_000_000_000L, ZoneOffset.UTC ), // Same time UTC as prev time
LocalDateTimeValue.localDateTime( 2018, 3, 1, 13, 50, 42, 1337 ), LocalDateTimeValue.localDateTime( 2018, 3, 1, 13, 50, 42, 1337 ),
DateTimeValue.datetime( 2014, 3, 25, 12, 45, 13, 7474, "UTC" ), DateTimeValue.datetime( 2014, 3, 25, 12, 45, 13, 7474, "UTC" ),
DateTimeValue.datetime( 2014, 3, 25, 12, 45, 13, 7474, "Europe/Stockholm" ), DateTimeValue.datetime( 2014, 3, 25, 12, 45, 13, 7474, "Europe/Stockholm" ),
Expand All @@ -118,6 +125,7 @@ public Compatibility( IndexProviderCompatibilityTestSuite testSuite, IndexDescri
Arrays.asList( Arrays.asList(
DateValue.epochDate( 42 ), DateValue.epochDate( 42 ),
LocalTimeValue.localTime( 2000 ), LocalTimeValue.localTime( 2000 ),
TimeValue.time( 100L, ZoneOffset.UTC ), // Just around midnight
LocalDateTimeValue.localDateTime( 2018, 2, 28, 11, 5, 1, 42 ), LocalDateTimeValue.localDateTime( 2018, 2, 28, 11, 5, 1, 42 ),
DateTimeValue.datetime( 1999, 12, 31, 23, 59, 59, 123456789, "Europe/London" ) ), DateTimeValue.datetime( 1999, 12, 31, 23, 59, 59, 123456789, "Europe/London" ) ),
Arrays.asList( Values.pointValue( CoordinateReferenceSystem.Cartesian, 10, 10 ), Arrays.asList( Values.pointValue( CoordinateReferenceSystem.Cartesian, 10, 10 ),
Expand Down

0 comments on commit 16fde87

Please sign in to comment.