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

org.neo4j.consistency.repair.RelationshipChainExplorer Maven / Gradle / Ivy

There is a newer version: 5.26.0
Show newest version
/*
 * Copyright (c) 2002-2020 "Neo4j,"
 * Neo4j Sweden AB [http://neo4j.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.consistency.repair;

import org.neo4j.kernel.impl.store.RecordStore;
import org.neo4j.kernel.impl.store.record.RelationshipRecord;

import static org.neo4j.consistency.repair.RelationshipChainDirection.NEXT;
import static org.neo4j.consistency.repair.RelationshipChainDirection.PREV;
import static org.neo4j.kernel.impl.store.record.RecordLoad.FORCE;
import static org.neo4j.kernel.impl.store.record.RecordLoad.NORMAL;

public class RelationshipChainExplorer
{
    private final RecordStore recordStore;

    public RelationshipChainExplorer( RecordStore recordStore )
    {
        this.recordStore = recordStore;
    }

    public RecordSet exploreRelationshipRecordChainsToDepthTwo( RelationshipRecord record )
    {
        RecordSet records = new RecordSet<>();
        for ( RelationshipNodeField nodeField : RelationshipNodeField.values() )
        {
            long nodeId = nodeField.get( record );
            records.addAll( expandChains( expandChainInBothDirections( record, nodeId ), nodeId ) );
        }
        return records;
    }

    private RecordSet expandChains( RecordSet records, long otherNodeId )
    {
        RecordSet chains = new RecordSet<>();
        for ( RelationshipRecord record : records )
        {
            chains.addAll( expandChainInBothDirections( record,
                    record.getFirstNode() == otherNodeId ? record.getSecondNode() : record.getFirstNode() ) );
        }
        return chains;
    }

    private RecordSet expandChainInBothDirections( RelationshipRecord record, long nodeId )
    {
        return expandChain( record, nodeId, PREV ).union( expandChain( record, nodeId, NEXT ) );
    }

    protected RecordSet followChainFromNode( long nodeId, long relationshipId )
    {
        return expandChain( recordStore.getRecord( relationshipId, recordStore.newRecord(), NORMAL ), nodeId, NEXT );
    }

    private RecordSet expandChain( RelationshipRecord record, long nodeId,
                                                       RelationshipChainDirection direction )
    {
        RecordSet chain = new RecordSet<>();
        chain.add( record );
        RelationshipRecord currentRecord = record;
        long nextRelId = direction.fieldFor( nodeId, currentRecord ).relOf( currentRecord );
        while ( currentRecord.inUse() && !direction.fieldFor( nodeId, currentRecord ).endOfChain( currentRecord ) )
        {
            currentRecord = recordStore.getRecord( nextRelId, recordStore.newRecord(), FORCE );
            chain.add( currentRecord );
            nextRelId = direction.fieldFor( nodeId, currentRecord ).relOf( currentRecord );
        }
        return chain;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy