Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for local datetime to temporal index
- Loading branch information
1 parent
8bc6827
commit 9c16c6f
Showing
9 changed files
with
339 additions
and
11 deletions.
There are no files selected for viewing
167 changes: 167 additions & 0 deletions
167
community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/LocalDateTimeLayout.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,167 @@ | |||
/* | |||
* 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 org.neo4j.index.internal.gbptree.Layout; | |||
import org.neo4j.io.pagecache.PageCursor; | |||
import org.neo4j.kernel.api.schema.index.IndexDescriptor; | |||
|
|||
/** | |||
* {@link Layout} for local date times. | |||
*/ | |||
abstract class LocalDateTimeLayout extends Layout.Adapter<LocalDateTimeSchemaKey,NativeSchemaValue> | |||
{ | |||
public static Layout<LocalDateTimeSchemaKey,NativeSchemaValue> of( IndexDescriptor descriptor ) | |||
{ | |||
return descriptor.type() == IndexDescriptor.Type.UNIQUE ? LocalDateTimeLayout.UNIQUE : LocalDateTimeLayout.NON_UNIQUE; | |||
} | |||
|
|||
private static final long UNIQUE_LAYOUT_IDENTIFIER = Layout.namedIdentifier( "UTld", NativeSchemaValue.SIZE ); | |||
public static LocalDateTimeLayout UNIQUE = new LocalDateTimeLayout() | |||
{ | |||
@Override | |||
public long identifier() | |||
{ | |||
return UNIQUE_LAYOUT_IDENTIFIER; | |||
} | |||
|
|||
@Override | |||
public int majorVersion() | |||
{ | |||
return 0; | |||
} | |||
|
|||
@Override | |||
public int minorVersion() | |||
{ | |||
return 1; | |||
} | |||
|
|||
@Override | |||
public int compare( LocalDateTimeSchemaKey o1, LocalDateTimeSchemaKey o2 ) | |||
{ | |||
int comparison = o1.compareValueTo( o2 ); | |||
if ( comparison == 0 ) | |||
{ | |||
// This is a special case where we need also compare entityId to support inclusive/exclusive | |||
if ( o1.getCompareId() || o2.getCompareId() ) | |||
{ | |||
return Long.compare( o1.getEntityId(), o2.getEntityId() ); | |||
} | |||
} | |||
return comparison; | |||
} | |||
}; | |||
|
|||
private static final long NON_UNIQUE_LAYOUT_IDENTIFIER = Layout.namedIdentifier( "NTld", NativeSchemaValue.SIZE ); | |||
public static LocalDateTimeLayout NON_UNIQUE = new LocalDateTimeLayout() | |||
{ | |||
@Override | |||
public long identifier() | |||
{ | |||
return NON_UNIQUE_LAYOUT_IDENTIFIER; | |||
} | |||
|
|||
@Override | |||
public int majorVersion() | |||
{ | |||
return 0; | |||
} | |||
|
|||
@Override | |||
public int minorVersion() | |||
{ | |||
return 1; | |||
} | |||
|
|||
@Override | |||
public int compare( LocalDateTimeSchemaKey o1, LocalDateTimeSchemaKey o2 ) | |||
{ | |||
int comparison = o1.compareValueTo( o2 ); | |||
return comparison != 0 ? comparison : Long.compare( o1.getEntityId(), o2.getEntityId() ); | |||
} | |||
}; | |||
|
|||
@Override | |||
public LocalDateTimeSchemaKey newKey() | |||
{ | |||
return new LocalDateTimeSchemaKey(); | |||
} | |||
|
|||
@Override | |||
public LocalDateTimeSchemaKey copyKey( LocalDateTimeSchemaKey key, LocalDateTimeSchemaKey into ) | |||
{ | |||
into.epochSecond = key.epochSecond; | |||
into.nanoOfSecond = key.nanoOfSecond; | |||
into.setEntityId( key.getEntityId() ); | |||
into.setCompareId( key.getCompareId() ); | |||
return into; | |||
} | |||
|
|||
@Override | |||
public NativeSchemaValue newValue() | |||
{ | |||
return NativeSchemaValue.INSTANCE; | |||
} | |||
|
|||
@Override | |||
public int keySize( LocalDateTimeSchemaKey key ) | |||
{ | |||
return LocalDateTimeSchemaKey.SIZE; | |||
} | |||
|
|||
@Override | |||
public int valueSize( NativeSchemaValue value ) | |||
{ | |||
return NativeSchemaValue.SIZE; | |||
} | |||
|
|||
@Override | |||
public void writeKey( PageCursor cursor, LocalDateTimeSchemaKey key ) | |||
{ | |||
cursor.putLong( key.epochSecond ); | |||
cursor.putInt( key.nanoOfSecond ); | |||
cursor.putLong( key.getEntityId() ); | |||
} | |||
|
|||
@Override | |||
public void writeValue( PageCursor cursor, NativeSchemaValue value ) | |||
{ | |||
} | |||
|
|||
@Override | |||
public void readKey( PageCursor cursor, LocalDateTimeSchemaKey into, int keySize ) | |||
{ | |||
into.epochSecond = cursor.getLong(); | |||
into.nanoOfSecond = cursor.getInt(); | |||
into.setEntityId( cursor.getLong() ); | |||
} | |||
|
|||
@Override | |||
public void readValue( PageCursor cursor, NativeSchemaValue into, int valueSize ) | |||
{ | |||
} | |||
|
|||
@Override | |||
public boolean fixedSize() | |||
{ | |||
return true; | |||
} | |||
} |
151 changes: 151 additions & 0 deletions
151
...unity/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/LocalDateTimeSchemaKey.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,151 @@ | |||
/* | |||
* 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 org.neo4j.values.storable.LocalDateTimeValue; | |||
import org.neo4j.values.storable.Value; | |||
import org.neo4j.values.storable.ValueWriter; | |||
|
|||
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 LocalDateTimeValue}. | |||
*/ | |||
class LocalDateTimeSchemaKey extends ValueWriter.Adapter<RuntimeException> implements NativeSchemaKey | |||
{ | |||
static final int SIZE = | |||
Long.BYTES + /* epochSecond */ | |||
Integer.BYTES + /* nanoOfSecond */ | |||
Long.BYTES; /* entityId */ | |||
|
|||
private long entityId; | |||
private boolean compareId; | |||
|
|||
int nanoOfSecond; | |||
long epochSecond; | |||
|
|||
public void setCompareId( boolean compareId ) | |||
{ | |||
this.compareId = compareId; | |||
} | |||
|
|||
public boolean getCompareId() | |||
{ | |||
return compareId; | |||
} | |||
|
|||
@Override | |||
public long getEntityId() | |||
{ | |||
return entityId; | |||
} | |||
|
|||
@Override | |||
public void setEntityId( long entityId ) | |||
{ | |||
this.entityId = entityId; | |||
} | |||
|
|||
@Override | |||
public void from( long entityId, Value... values ) | |||
{ | |||
this.entityId = entityId; | |||
compareId = false; | |||
assertValidValue( values ).writeTo( this ); | |||
} | |||
|
|||
private LocalDateTimeValue assertValidValue( Value... values ) | |||
{ | |||
if ( values.length > 1 ) | |||
{ | |||
throw new IllegalArgumentException( "Tried to create composite key with non-composite schema key layout" ); | |||
} | |||
if ( values.length < 1 ) | |||
{ | |||
throw new IllegalArgumentException( "Tried to create key without value" ); | |||
} | |||
if ( !(values[0] instanceof LocalDateTimeValue) ) | |||
{ | |||
throw new IllegalArgumentException( | |||
"Key layout does only support LocalDateTimeValue, tried to create key from " + values[0] ); | |||
} | |||
return (LocalDateTimeValue) values[0]; | |||
} | |||
|
|||
@Override | |||
public String propertiesAsString() | |||
{ | |||
return asValue().toString(); | |||
} | |||
|
|||
@Override | |||
public Value asValue() | |||
{ | |||
return LocalDateTimeValue.localDateTime( epochSecond, nanoOfSecond ); | |||
} | |||
|
|||
@Override | |||
public void initAsLowest() | |||
{ | |||
epochSecond = Long.MIN_VALUE; | |||
nanoOfSecond = Integer.MIN_VALUE; | |||
entityId = Long.MIN_VALUE; | |||
compareId = true; | |||
} | |||
|
|||
@Override | |||
public void initAsHighest() | |||
{ | |||
epochSecond = Long.MAX_VALUE; | |||
nanoOfSecond = Integer.MAX_VALUE; | |||
entityId = Long.MAX_VALUE; | |||
compareId = true; | |||
} | |||
|
|||
/** | |||
* Compares the value of this key to that of another key. | |||
* This method is expected to be called in scenarios where inconsistent reads may happen (and later retried). | |||
* | |||
* @param other the {@link LocalDateTimeSchemaKey} to compare to. | |||
* @return comparison against the {@code other} {@link LocalDateTimeSchemaKey}. | |||
*/ | |||
int compareValueTo( LocalDateTimeSchemaKey other ) | |||
{ | |||
int compare = Long.compare( epochSecond, other.epochSecond ); | |||
if ( compare == 0 ) | |||
{ | |||
compare = Integer.compare( nanoOfSecond, other.nanoOfSecond ); | |||
} | |||
return compare; | |||
} | |||
|
|||
@Override | |||
public String toString() | |||
{ | |||
return format( "value=%s,entityId=%d,nanoOfDay=%s", asValue(), entityId, nanoOfSecond ); | |||
} | |||
|
|||
@Override | |||
public void writeLocalDateTime( long epochSecond, int nano ) | |||
{ | |||
this.nanoOfSecond = nano; | |||
this.epochSecond = epochSecond; | |||
} | |||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.