All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.neo4j.kernel.impl.api.state.PropertyContainerState Maven / Gradle / Ivy

/*
 * Copyright (c) 2002-2015 "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 .
 */
package org.neo4j.kernel.impl.api.state;

import java.util.Iterator;

import org.neo4j.cursor.Cursor;
import org.neo4j.function.Predicate;
import org.neo4j.function.Supplier;
import org.neo4j.graphdb.ResourceIterator;
import org.neo4j.helpers.collection.CombiningIterator;
import org.neo4j.helpers.collection.FilteringIterator;
import org.neo4j.helpers.collection.IteratorUtil;
import org.neo4j.kernel.api.EntityType;
import org.neo4j.kernel.api.cursor.PropertyItem;
import org.neo4j.kernel.api.exceptions.schema.ConstraintValidationKernelException;
import org.neo4j.kernel.api.properties.DefinedProperty;
import org.neo4j.kernel.impl.api.cursor.TxAllPropertyCursor;
import org.neo4j.kernel.impl.api.cursor.TxSinglePropertyCursor;
import org.neo4j.kernel.impl.util.VersionedHashMap;

import static org.neo4j.helpers.collection.IteratorUtil.emptyIterator;

/**
 * Represents the property changes to a {@link NodeState node} or {@link RelationshipState relationship}:
 * 
    *
  • {@linkplain #addedProperties() Added properties},
  • *
  • {@linkplain #removedProperties() removed properties}, and
  • *
  • {@linkplain #changedProperties() changed property values}.
  • *
*/ public interface PropertyContainerState { Iterator addedProperties(); Iterator changedProperties(); Iterator removedProperties(); Iterator addedAndChangedProperties(); Iterator augmentProperties( Iterator iterator ); void accept( Visitor visitor ) throws ConstraintValidationKernelException; Cursor augmentPropertyCursor( Supplier propertyCursor, Cursor cursor ); Cursor augmentSinglePropertyCursor( Supplier propertyCursor, Cursor cursor, int propertyKeyId ); interface Visitor { void visitPropertyChanges( long entityId, Iterator added, Iterator changed, Iterator removed ) throws ConstraintValidationKernelException; } class Mutable implements PropertyContainerState { private final long id; private final EntityType entityType; private static final ResourceIterator NO_PROPERTIES = emptyIterator(); private VersionedHashMap addedProperties; private VersionedHashMap changedProperties; private VersionedHashMap removedProperties; private final Predicate excludePropertiesWeKnowAbout = new Predicate() { @Override public boolean test( DefinedProperty item ) { return (removedProperties == null || !removedProperties.containsKey( item.propertyKeyId() )) && (addedProperties == null || !addedProperties.containsKey( item.propertyKeyId() )) && (changedProperties == null || !changedProperties.containsKey( item.propertyKeyId() )); } }; Mutable( long id, EntityType entityType ) { this.id = id; this.entityType = entityType; } public long getId() { return id; } public void clear() { if ( changedProperties != null ) { changedProperties.clear(); } if ( addedProperties != null ) { addedProperties.clear(); } if ( removedProperties != null ) { removedProperties.clear(); } } public void changeProperty( DefinedProperty property ) { if ( addedProperties != null ) { if ( addedProperties.containsKey( property.propertyKeyId() ) ) { addedProperties.put( property.propertyKeyId(), property ); return; } } if ( changedProperties == null ) { changedProperties = new VersionedHashMap<>(); } changedProperties.put( property.propertyKeyId(), property ); if ( removedProperties != null ) { removedProperties.remove( property.propertyKeyId() ); } } public void addProperty( DefinedProperty property ) { if ( removedProperties != null ) { DefinedProperty removed = removedProperties.remove( property.propertyKeyId() ); if ( removed != null ) { // This indicates the user did remove+add as two discrete steps, which should be translated to // a single change operation. changeProperty( property ); return; } } if ( addedProperties == null ) { addedProperties = new VersionedHashMap<>(); } addedProperties.put( property.propertyKeyId(), property ); } public void removeProperty( DefinedProperty property ) { if ( addedProperties != null ) { if ( addedProperties.remove( property.propertyKeyId() ) != null ) { return; } } if ( removedProperties == null ) { removedProperties = new VersionedHashMap<>(); } removedProperties.put( property.propertyKeyId(), property ); if ( changedProperties != null ) { changedProperties.remove( property.propertyKeyId() ); } } @Override public Iterator addedProperties() { return addedProperties != null ? addedProperties.values().iterator() : NO_PROPERTIES; } @Override public Iterator changedProperties() { return changedProperties != null ? changedProperties.values().iterator() : NO_PROPERTIES; } @Override public Iterator removedProperties() { return removedProperties != null ? removedProperties.keySet().iterator() : IteratorUtil.emptyIterator(); } @Override public Iterator addedAndChangedProperties() { Iterator out = null; if ( addedProperties != null ) { out = addedProperties.values().iterator(); } if ( changedProperties != null ) { if ( out != null ) { out = new CombiningIterator<>( IteratorUtil.iterator( out, changedProperties.values().iterator() ) ); } else { out = changedProperties.values().iterator(); } } return out != null ? out : NO_PROPERTIES; } @Override public Cursor augmentPropertyCursor( Supplier propertyCursorCache, Cursor cursor ) { if ( removedProperties != null || addedProperties != null || changedProperties != null ) { return propertyCursorCache.get().init( cursor, addedProperties, changedProperties, removedProperties ); } else { return cursor; } } @Override public Cursor augmentSinglePropertyCursor( Supplier propertyCursorCache, Cursor cursor, int propertyKeyId ) { if ( removedProperties != null || addedProperties != null || changedProperties != null ) { return propertyCursorCache.get().init( cursor, addedProperties, changedProperties, removedProperties, propertyKeyId ); } else { return cursor; } } @Override public Iterator augmentProperties( Iterator iterator ) { if ( removedProperties != null || addedProperties != null || changedProperties != null ) { iterator = new FilteringIterator<>( iterator, excludePropertiesWeKnowAbout ); if ( addedProperties != null && !addedProperties.isEmpty() ) { iterator = new CombiningIterator<>( IteratorUtil.iterator( iterator, addedProperties.values().iterator() ) ); } if ( changedProperties != null && !changedProperties.isEmpty() ) { iterator = new CombiningIterator<>( IteratorUtil.iterator( iterator, changedProperties.values().iterator() ) ); } } return iterator; } @Override public void accept( Visitor visitor ) throws ConstraintValidationKernelException { if ( addedProperties != null || removedProperties != null || changedProperties != null ) { visitor.visitPropertyChanges( id, addedProperties(), changedProperties(), removedProperties() ); } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy