public static Locks createLockManager( LocksFactory locksFactory, Config config, Clock clock ) { return locksFactory.newInstance( config, clock, ResourceTypes.values() ); }
private static IntObjectProcedure<LongObjectMap<LockResource>> collectActiveLocks( List<ActiveLock> locks, ActiveLock.Factory activeLock ) { return ( typeId, exclusive ) -> { ResourceType resourceType = ResourceTypes.fromId( typeId ); exclusive.forEachKeyValue( ( resourceId, lock ) -> { locks.add( activeLock.create( resourceType, resourceId ) ); } ); }; }
@Test public void shouldProduceBackwardsCompatibleId() { long id = ResourceTypes.indexEntryResourceId( labelId, exact( propertyId, value ) ); assertThat( id, equalTo( 155667838465249649L ) ); }
/** * This is the schema index entry hashing method used since 2.2.0 and onwards. * <p> * Use the {@link ResourceTypes#useStrongHashing} feature toggle to use a stronger hash function, which will become * the default in a future release. <strong>Note</strong> that changing this hash function is effectively a * clustering protocol change in HA setups. Causal cluster setups are unaffected because followers do not take any * locks on the cluster leader. */ public static long indexEntryResourceId( long labelId, IndexQuery.ExactPredicate... predicates ) { if ( !useStrongHashing ) { // Default return indexEntryResourceId_2_2_0( labelId, predicates ); } else { // Opt-in return indexEntryResourceId_4_x( labelId, predicates ); } }
private static long indexEntryResourceId_2_2_0( long labelId, IndexQuery.ExactPredicate[] predicates, int i ) { int propertyKeyId = predicates[i].propertyKeyId(); Value value = predicates[i].value(); // Note: // It is important that single-property indexes only hash with this particular call; no additional hashing! long hash = indexEntryResourceId_2_2_0( labelId, propertyKeyId, stringOf( value ) ); i++; if ( i < predicates.length ) { hash = hash( hash + indexEntryResourceId_2_2_0( labelId, predicates, i ) ); } return hash; }
@Override public Value graphRemoveProperty( int propertyKey ) { ktx.statementLocks().optimistic() .acquireExclusive( ktx.lockTracer(), ResourceTypes.GRAPH_PROPS, ResourceTypes.graphPropertyResource() ); ktx.assertOpen(); Value existingValue = readGraphProperty( propertyKey ); if ( existingValue != Values.NO_VALUE ) { ktx.txState().graphDoRemoveProperty( propertyKey ); } return existingValue; }
static long indexEntryResourceId_2_2_0( long labelId, IndexQuery.ExactPredicate[] predicates ) { return indexEntryResourceId_2_2_0( labelId, predicates, 0 ); }
ktx.locks().acquireExclusiveExplicitIndexLock( explicitIndexResourceId( name, key ) ); ktx.locks().releaseExclusiveExplicitIndexLock( explicitIndexResourceId( name, key ) ); return existing;
private static long indexEntryResourceId_2_2_0( long labelId, IndexQuery.ExactPredicate[] predicates, int i ) { int propertyKeyId = predicates[i].propertyKeyId(); Value value = predicates[i].value(); // Note: // It is important that single-property indexes only hash with this particular call; no additional hashing! long hash = indexEntryResourceId_2_2_0( labelId, propertyKeyId, stringOf( value ) ); i++; if ( i < predicates.length ) { hash = hash( hash + indexEntryResourceId_2_2_0( labelId, predicates, i ) ); } return hash; }
/** * This is the schema index entry hashing method used since 2.2.0 and onwards. * <p> * Use the {@link ResourceTypes#useStrongHashing} feature toggle to use a stronger hash function, which will become * the default in a future release. <strong>Note</strong> that changing this hash function is effectively a * clustering protocol change in HA setups. Causal cluster setups are unaffected because followers do not take any * locks on the cluster leader. */ public static long indexEntryResourceId( long labelId, IndexQuery.ExactPredicate... predicates ) { if ( !useStrongHashing ) { // Default return indexEntryResourceId_2_2_0( labelId, predicates ); } else { // Opt-in return indexEntryResourceId_4_x( labelId, predicates ); } }
@Override public Value graphSetProperty( int propertyKey, Value value ) { ktx.statementLocks().optimistic() .acquireExclusive( ktx.lockTracer(), ResourceTypes.GRAPH_PROPS, ResourceTypes.graphPropertyResource() ); ktx.assertOpen(); Value existingValue = readGraphProperty( propertyKey ); if ( !existingValue.equals( value ) ) { ktx.txState().graphDoReplaceProperty( propertyKey, existingValue, value ); } return existingValue; }
static long indexEntryResourceId_2_2_0( long labelId, IndexQuery.ExactPredicate[] predicates ) { return indexEntryResourceId_2_2_0( labelId, predicates, 0 ); }
ktx.locks().acquireExclusiveExplicitIndexLock( explicitIndexResourceId( name, key ) ); ktx.locks().releaseExclusiveExplicitIndexLock( explicitIndexResourceId( name, key ) ); return existing;
@Test void createLocksForAllResourceTypes() { LocksFactory lockFactory = mock( LocksFactory.class ); Config config = Config.defaults(); Clock clock = Clocks.systemClock(); createLockManager( lockFactory, config, clock ); verify( lockFactory ).newInstance( eq( config ), eq( clock ), eq( ResourceTypes.values() ) ); }
@Test public void shouldDifferentiateBetweenIndexes() { ExactPredicate pred1 = exact( 1, "value" ); ExactPredicate pred2 = exact( 1, "value2" ); ExactPredicate pred3 = exact( 2, "value" ); ExactPredicate pred4 = exact( 2, "value2" ); List<Long> ids = Arrays.asList( ResourceTypes.indexEntryResourceId( 1, array( pred1 ) ), ResourceTypes.indexEntryResourceId( 1, array( pred2 ) ), ResourceTypes.indexEntryResourceId( 1, array( pred3 ) ), ResourceTypes.indexEntryResourceId( 1, array( pred4 ) ), ResourceTypes.indexEntryResourceId( 2, array( pred1 ) ), ResourceTypes.indexEntryResourceId( 1, array( pred1, pred2 ) ), ResourceTypes.indexEntryResourceId( 1, array( pred1, pred2, pred3 ) ), ResourceTypes.indexEntryResourceId( 2, array( pred1, pred2, pred3, pred4 ) ) ); Set<Long> uniqueIds = Iterables.asSet( ids ); assertThat( ids.size(), equalTo( uniqueIds.size() ) ); }
private static IntObjectProcedure<LongObjectMap<LockResource>> collectActiveLocks( List<ActiveLock> locks, ActiveLock.Factory activeLock ) { return ( typeId, exclusive ) -> { ResourceType resourceType = ResourceTypes.fromId( typeId ); exclusive.forEachKeyValue( ( resourceId, lock ) -> { locks.add( activeLock.create( resourceType, resourceId ) ); } ); }; }
@Override public Value graphRemoveProperty( int propertyKey ) { ktx.statementLocks().optimistic() .acquireExclusive( ktx.lockTracer(), ResourceTypes.GRAPH_PROPS, ResourceTypes.graphPropertyResource() ); ktx.assertOpen(); Value existingValue = readGraphProperty( propertyKey ); if ( existingValue != Values.NO_VALUE ) { ktx.txState().graphDoRemoveProperty( propertyKey ); } return existingValue; }
@Test void createDifferentCommunityLockManagers() { CommunityLocksFactory factory = new CommunityLocksFactory(); Locks locks1 = factory.newInstance( Config.defaults(), Clocks.systemClock(), ResourceTypes.values() ); Locks locks2 = factory.newInstance( Config.defaults(), Clocks.systemClock(), ResourceTypes.values() ); assertNotSame( locks1, locks2 ); assertThat( locks1, instanceOf( CommunityLockManger.class ) ); assertThat( locks2, instanceOf( CommunityLockManger.class ) ); } }