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

com.graphaware.relcount.full.counter.FullFallingBackRelationshipCounter Maven / Gradle / Ivy

/*
 * Copyright (c) 2013 GraphAware
 *
 * This file is part of GraphAware.
 *
 * GraphAware 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 com.graphaware.relcount.full.counter;

import com.graphaware.framework.config.DefaultFrameworkConfiguration;
import com.graphaware.framework.config.FrameworkConfiguration;
import com.graphaware.propertycontainer.dto.string.property.CopyMakingSerializableProperties;
import com.graphaware.relcount.common.counter.UnableToCountException;
import com.graphaware.relcount.full.internal.dto.relationship.LiteralRelationshipDescription;
import com.graphaware.relcount.full.internal.dto.relationship.WildcardRelationshipDescription;
import com.graphaware.relcount.full.module.FullRelationshipCountModule;
import com.graphaware.relcount.full.strategy.RelationshipCountStrategies;
import com.graphaware.relcount.full.strategy.RelationshipCountStrategiesImpl;
import org.apache.log4j.Logger;
import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.RelationshipType;

/**
 * {@link FullRelationshipCounter} that counts matching relationships by first trying to look them up in cached
 * {@link org.neo4j.graphdb.Node}'s properties, falling back to naive approach of iterating through all {@link Node}'s
 * {@link org.neo4j.graphdb.Relationship}s.
 * 

* This is a full relationship counter, meaning that it inspects relationship types, directions, and properties. *

* It should be used in conjunction with {@link com.graphaware.relcount.full.module.FullRelationshipCountModule} * registered with {@link com.graphaware.framework.GraphAwareFramework}. The easiest and recommended way to create * and instance of this counter is through the corresponding {@link com.graphaware.relcount.full.module.FullRelationshipCountModule#fallingBackCounter(org.neo4j.graphdb.RelationshipType, org.neo4j.graphdb.Direction)}. *

* This counter always returns a count, never throws {@link com.graphaware.relcount.common.counter.UnableToCountException}. *

* About fallback: Fallback to naive approach only happens if it is detected that compaction has taken place * (see {@link com.graphaware.relcount.full.internal.cache.FullRelationshipCountCache}) and the needed granularity has * been compacted out. There is a performance penalty to this fallback. * To avoid it, make sure the compaction threshold is set correctly. No fallback happens when a {@link com.graphaware.tx.event.improved.strategy.RelationshipInclusionStrategy} has been used that explicitly excludes * the relationships being counted (0 is returned). If you prefer an exception to fallback, use {@link FullCachedRelationshipCounter}. */ public class FullFallingBackRelationshipCounter extends BaseFullRelationshipCounter implements FullRelationshipCounter { private static final Logger LOG = Logger.getLogger(FullFallingBackRelationshipCounter.class); private final String id; private final RelationshipCountStrategies strategies; private final FrameworkConfiguration config; /** * Construct a new relationship counter with default settings. Use this constructor when * {@link com.graphaware.framework.GraphAwareFramework} is used with default configuration, only a single * instance of {@link com.graphaware.relcount.full.module.FullRelationshipCountModule} is registered, and * no custom {@link RelationshipCountStrategies} are in use. If unsure, it is always easy and correct to instantiate * this counter through {@link com.graphaware.relcount.full.module.FullRelationshipCountModule#fallingBackCounter(org.neo4j.graphdb.RelationshipType, org.neo4j.graphdb.Direction)}. * * @param type type of the relationships to count. * @param direction direction of the relationships to count. */ public FullFallingBackRelationshipCounter(RelationshipType type, Direction direction) { this(type, direction, FullRelationshipCountModule.FULL_RELCOUNT_DEFAULT_ID, RelationshipCountStrategiesImpl.defaultStrategies(), DefaultFrameworkConfiguration.getInstance()); } /** * Construct a new relationship counter with granular settings. It is always easier and recommended to use * {@link com.graphaware.relcount.full.module.FullRelationshipCountModule#fallingBackCounter(org.neo4j.graphdb.RelationshipType, org.neo4j.graphdb.Direction)} * instead. * * @param type type of the relationships to count. * @param direction direction of the relationships to count. * @param id of the {@link com.graphaware.relcount.full.module.FullRelationshipCountModule} used to cache relationship counts. * @param strategies for counting relationships, provided to the {@link com.graphaware.relcount.full.module.FullRelationshipCountModule}. * @param config used with the {@link com.graphaware.framework.GraphAwareFramework}. */ public FullFallingBackRelationshipCounter(RelationshipType type, Direction direction, String id, RelationshipCountStrategies strategies, FrameworkConfiguration config) { super(type, direction); this.id = id; this.strategies = strategies; this.config = config; } /** * {@inheritDoc} */ @Override public int count(Node node) { try { return new FullCachedRelationshipCounter(getType(), getDirection(), getProperties(), id, config).count(node); } catch (UnableToCountException e) { LOG.warn("Unable to count relationships with description: " + new WildcardRelationshipDescription(this).toString() + " for node " + node.toString() + ". Falling back to naive approach"); return new FullNaiveRelationshipCounter(getType(), getDirection(), getProperties(), strategies).count(node); } } /** * {@inheritDoc} */ @Override public int countLiterally(Node node) { try { return new FullCachedRelationshipCounter(getType(), getDirection(), getProperties(), id, config).countLiterally(node); } catch (UnableToCountException e) { LOG.warn("Unable to count relationships with description: " + new LiteralRelationshipDescription(this).toString() + " for node " + node.toString() + ". Falling back to naive approach"); return new FullNaiveRelationshipCounter(getType(), getDirection(), getProperties(), strategies).countLiterally(node); } } /** * {@inheritDoc} */ @Override public FullRelationshipCounter with(String key, Object value) { return new FullFallingBackRelationshipCounter(getType(), getDirection(), getProperties().with(key, value), id, strategies, config); } /** * Construct a counter. * * @param type type. * @param direction direction. * @param properties props. * @param strategies strategies, of which only {@link com.graphaware.relcount.full.strategy.RelationshipPropertiesExtractionStrategy} */ protected FullFallingBackRelationshipCounter(RelationshipType type, Direction direction, CopyMakingSerializableProperties properties, String id, RelationshipCountStrategies strategies, FrameworkConfiguration config) { super(type, direction, properties); this.id = id; this.strategies = strategies; this.config = config; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy