Package org.jrdf.graph.global

Source Code of org.jrdf.graph.global.MoleculeGraphImpl

/*
* $Header$
* $Revision: 982 $
* $Date: 2006-12-08 18:42:51 +1000 (Fri, 08 Dec 2006) $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003-2009 The JRDF Project.  All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution, if
*    any, must include the following acknowlegement:
*       "This product includes software developed by the
*        the JRDF Project (http://jrdf.sf.net/)."
*    Alternately, this acknowlegement may appear in the software itself,
*    if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The JRDF Project" and "JRDF" must not be used to endorse
*    or promote products derived from this software without prior written
*    permission. For written permission, please contact
*    newmana@users.sourceforge.net.
*
* 5. Products derived from this software may not be called "JRDF"
*    nor may "JRDF" appear in their names without prior written
*    permission of the JRDF Project.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the JRDF Project.  For more
* information on JRDF, please see <http://jrdf.sourceforge.net/>.
*
*/

package org.jrdf.graph.global;

import org.jrdf.graph.Graph;
import org.jrdf.graph.GraphElementFactory;
import org.jrdf.graph.GraphException;
import org.jrdf.graph.Node;
import org.jrdf.graph.ObjectNode;
import org.jrdf.graph.PredicateNode;
import org.jrdf.graph.Resource;
import org.jrdf.graph.SubjectNode;
import org.jrdf.graph.Triple;
import org.jrdf.graph.TripleComparator;
import org.jrdf.graph.TripleFactory;
import org.jrdf.graph.TripleImpl;
import org.jrdf.graph.global.index.AddMoleculeToIndex;
import org.jrdf.graph.global.index.ReadableIndex;
import org.jrdf.graph.global.index.WritableIndex;
import org.jrdf.graph.global.molecule.ClosableMoleculeIterator;
import org.jrdf.graph.global.molecule.Molecule;
import org.jrdf.graph.global.molecule.MoleculeComparator;
import org.jrdf.graph.global.molecule.MoleculeHandler;
import org.jrdf.graph.global.molecule.MoleculeToText;
import org.jrdf.graph.global.molecule.MoleculeTraverser;
import org.jrdf.graph.global.molecule.mem.MoleculeHeadTripleComparatorImpl;
import org.jrdf.graph.global.molecule.mem.MoleculeTraverserImpl;
import org.jrdf.graph.local.TripleComparatorFactoryImpl;
import org.jrdf.graph.local.index.nodepool.NodePool;
import org.jrdf.query.relation.type.NodeType;
import org.jrdf.query.relation.type.ValueNodeType;
import org.jrdf.util.ClosableIterable;
import org.jrdf.util.ClosableIterator;
import org.jrdf.util.LongIndexToMoleculeIterator;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class MoleculeGraphImpl implements MoleculeGraph {
    private static final int QUIN_SIZE = 5;
    private static final int QUAD_SIZE = 4;
    private final WritableIndex<Long> writableIndex;
    private final ReadableIndex<Long> readableIndex;
    private final MoleculeLocalizer localizer;
    private final Graph graph;
    private TripleComparator comparator;
    private MoleculeComparator moleculeComparator;
    private MoleculeGraphHandler handler;

    public MoleculeGraphImpl(WritableIndex<Long> newWriteIndex, ReadableIndex<Long> newReadIndex,
        MoleculeLocalizer newLocalizer, Graph newGraph, NodePool nodePool) {
        this.writableIndex = newWriteIndex;
        this.readableIndex = newReadIndex;
        this.localizer = newLocalizer;
        this.graph = newGraph;
        this.comparator = new TripleComparatorFactoryImpl().newComparator();
        this.moleculeComparator = new MoleculeHeadTripleComparatorImpl(comparator);
        this.handler = new MoleculeGraphHandlerImpl(nodePool, readableIndex, moleculeComparator);
    }

    public void add(Molecule molecule) {
        MoleculeTraverser traverser = new MoleculeTraverserImpl();
        traverser.traverse(molecule, new AddMoleculeToIndex(writableIndex, localizer));
    }

    public void delete(Molecule molecule) throws GraphException {
        final Triple headTriple = molecule.getHeadTriple();
        final Long headTripleMid = findMoleculeID(headTriple);
        Set<Long> mids = new HashSet<Long>();
        mids.add(headTripleMid);
        Set<Long[]> indicesToRemove = new HashSet<Long[]>();
        indicesToRemove = deleteChildMolecules(mids, indicesToRemove);
        getIndicesToRemove(headTripleMid, indicesToRemove);
        //indicesToRemove = getIndicesToRemove(headTripleMid, indicesToRemove);
        for (Long[] index : indicesToRemove) {
            writableIndex.remove(index);
        }
        indicesToRemove.clear();
    }

    private Set<Long[]> getIndicesToRemove(Long headTripleMid, Set<Long[]> indicesToRemove) {
        ClosableIterator<Long[]> iterator = readableIndex.findTriplesForMid(1L, headTripleMid);
        while (iterator.hasNext()) {
            Long[] spo = iterator.next();
            Long[] quin = new Long[QUIN_SIZE];
            System.arraycopy(spo, 0, quin, 0, 3);
            quin[3] = headTripleMid;
            quin[4] = 1L;
            indicesToRemove.add(quin);
        }
        iterator.close();
        return indicesToRemove;
    }

    private Long findMoleculeID(Triple headTriple) throws GraphException {
        final Long[] longsForTriple = localizer.localizeTriple(headTriple);
        return readableIndex.findHeadTripleMid(1L, longsForTriple);
    }

    private Set<Long[]> deleteChildMolecules(Set<Long> mids, Set<Long[]> toRemove) throws GraphException {
        Set<Long> newMids = new HashSet<Long>();
        for (Long pid : mids) {
            final ClosableIterator<Long[]> mspos = readableIndex.findTriplesForPid(pid);
            while (mspos.hasNext()) {
                Long[] mspo = mspos.next();
                newMids.add(mspo[0]);
                Long[] quin = new Long[QUIN_SIZE];
                System.arraycopy(mspo, 0, quin, 0, QUAD_SIZE);
                quin[QUAD_SIZE] = pid;
                //writableIndex.remove(quin);
                toRemove.add(quin);
            }
            mspos.close();
        }
        if (!newMids.isEmpty()) {
            deleteChildMolecules(newMids, toRemove);
            newMids.clear();
        }
        return toRemove;
    }

    public Molecule findTopLevelMolecule(Triple triple) throws GraphException {
        final Long[] localizedTriple = localizer.localizeTriple(triple);
        final ClosableIterator<Long[]> iterator = readableIndex.getMidPidPairs(localizedTriple);
        Long mid = 1L;
        if (iterator.hasNext()) {
            final Long[] pair = iterator.next();
            mid = pair[0];
        }
        iterator.close();
        mid = readableIndex.findTopMoleculeID(mid);
        return handler.createMolecule(1L, mid);
    }

    public Molecule findEnclosingMolecule(Triple triple) throws GraphException {
        Long[] localizedTriple = localizer.localizeTriple(triple);
        Long mid = readableIndex.findMid(localizedTriple);
        Long pid = readableIndex.findEnclosingMoleculeId(mid);
        return handler.createMolecule(pid, mid);
    }

    public ClosableIterator<Molecule> findMolecules(SubjectNode subject, PredicateNode predicate, ObjectNode object)
        throws GraphException {
        Triple triple = new TripleImpl(subject, predicate, object);
        return findMolecules(triple);
    }

    public ClosableIterator<Molecule> findMolecules(Triple rootTriple) throws GraphException {
        Long[] localizedTriple = localizer.localizeTriple(rootTriple);
        ClosableIterator<Long> midIterator = readableIndex.findMoleculeIDs(localizedTriple);
        return new ClosableMoleculeIterator(midIterator, handler);
    }

    // TODO Add more stuff here to handle molecule indexes
    public boolean contains(Triple triple) throws GraphException {
        return graph.contains(triple);
    }

    public boolean contains(SubjectNode subject, PredicateNode predicate, ObjectNode object) throws GraphException {
        return graph.contains(subject, predicate, object);
    }

    public ClosableIterable<Triple> find(Triple triple) throws GraphException {
        return graph.find(triple);
    }

    public ClosableIterable<Triple> find(SubjectNode subject, PredicateNode predicate, ObjectNode object)
        throws GraphException {
        return graph.find(subject, predicate, object);
    }

    public ClosableIterator<Triple> findUnsorted(SubjectNode subject, PredicateNode predicate, ObjectNode object) {
        return graph.findUnsorted(subject, predicate, object);
    }

    public ClosableIterable<? extends Node> findNodes(NodeType type) {
        return graph.findNodes(type);
    }

    public ClosableIterable<PredicateNode> findPredicates(Resource resource) throws GraphException {
        return graph.findPredicates(resource);
    }

    public ClosableIterable<Resource> findResources(ValueNodeType type) {
        return graph.findResources(type);
    }

    public void add(SubjectNode subject, PredicateNode predicate, ObjectNode object) throws GraphException {
        graph.add(subject, predicate, object);
    }

    public void add(Triple triple) throws GraphException {
        graph.add(triple);
    }

    public void add(Iterator<Triple> triples) throws GraphException {
        graph.add(triples);
    }

    public void add(Triple... triples) throws GraphException {
        graph.add(triples);
    }

    public void clear() {
        writableIndex.clear();
        graph.clear();
    }

    public void close() {
        writableIndex.close();
        graph.close();
    }

    public void remove(SubjectNode subject, PredicateNode predicate, ObjectNode object) throws GraphException {
        graph.remove(subject, predicate, object);
    }

    public void remove(Triple triple) throws GraphException {
        graph.remove(triple);
    }

    public void remove(Iterator<Triple> triples) throws GraphException {
        graph.remove(triples);
    }

    public void remove(Triple... triples) throws GraphException {
        graph.remove(triples);
    }

    public GraphElementFactory getElementFactory() {
        return graph.getElementFactory();
    }

    public TripleFactory getTripleFactory() {
        return graph.getTripleFactory();
    }

    public long getNumberOfTriples() throws GraphException {
        return graph.getNumberOfTriples();
    }

    public boolean isEmpty() throws GraphException {
        return graph.isEmpty();
    }

    public ClosableIterator<Molecule> iterator() throws GraphException {
        return new LongIndexToMoleculeIterator(readableIndex.findChildIds(1L), handler);
    }

    public long getNumberOfMolecules() {
        final ClosableIterator<Long> iterator = readableIndex.findChildIds(1L);
        try {
            long size = 0;
            while (iterator.hasNext()) {
                iterator.next();
                size++;
            }
            return size;
        } finally {
            iterator.close();
        }
    }

    public Molecule addRootTriple(Molecule molecule, Triple rootTriple) throws GraphException {
        Triple headTriple = molecule.getHeadTriple();
        Long[] tripleAsLongs = localizer.localizeTriple(headTriple);
        ClosableIterator<Long> iterator = readableIndex.findMoleculeIDs(tripleAsLongs);
        try {
            while (iterator.hasNext()) {
                final Long mid = iterator.next();
                if (readableIndex.isSubmoleculeOfParentID(1L, mid)) {
                    Molecule m = handler.createMolecule(1L, mid);
                    if (m != null && moleculeComparator.compare(molecule, m) == 0) {
                        AddMoleculeToIndex amti = new AddMoleculeToIndex(writableIndex, localizer);
                        amti.handleTriple(rootTriple);
                        return molecule.add(rootTriple);
                    }
                }
            }
        } finally {
            iterator.close();
        }
        throw new GraphException("Cannot add new triple to molecule");
    }

    // TODO recursively remove submolecules
    public Molecule removeRootTriple(Molecule molecule, Triple rootTriple) throws GraphException {
        Long[] tripleAsLongs = localizer.localizeTriple(rootTriple);
        ClosableIterator<Long> iterator = readableIndex.findMoleculeIDs(tripleAsLongs);
        try {
            while (iterator.hasNext()) {
                Long aLong = iterator.next();
                if (readableIndex.isSubmoleculeOfParentID(1L, aLong)) {
                    Molecule m = handler.createMolecule(1L, aLong);
                    if (m != null && moleculeComparator.compare(molecule, m) == 0) {
                        return removeSubMolecules(molecule, rootTriple, tripleAsLongs, aLong);
                    }
                }
            }
        } finally {
            iterator.close();
        }
        throw new GraphException("Cannot remove triple from molecule");
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        MoleculeTraverser traverser = new MoleculeTraverserImpl();
        try {
            ClosableIterator<Molecule> iterator = iterator();
            try {
                MoleculeHandler tmpHandler = new MoleculeToText(builder, localizer.getLocalizer());
                while (iterator.hasNext()) {
                    Molecule molecule = iterator.next();
                    traverser.traverse(molecule, tmpHandler);
                }
                return builder.toString();
            } finally {
                iterator.close();
            }
        } catch (GraphException e) {
            throw new RuntimeException("Cannot return string representation", e);
        }
    }

    // TODO finish implementation
    private Molecule removeSubMolecules(Molecule molecule, Triple rootTriple,
        Long[] tripleAsLongs, Long aLong) throws GraphException {
        removeFromIndex(tripleAsLongs, aLong);
        molecule.remove(rootTriple);
        return molecule;
    }

    private void removeFromIndex(Long[] tripleAsLongs, Long mid) throws GraphException {
        ClosableIterator<Long> iterator = readableIndex.findMoleculeIDs(tripleAsLongs);
        while (iterator.hasNext()) {
            Long subMID = iterator.next();
            if (readableIndex.isSubmoleculeOfParentID(mid, subMID)) {
                Long[] quin = new Long[QUIN_SIZE];
                System.arraycopy(tripleAsLongs, 0, quin, 0, QUIN_SIZE - 2);
                writableIndex.remove(quin);
                ClosableIterator<Long[]> triples = readableIndex.findTriplesForMid(mid, subMID);
                while (triples.hasNext()) {
                    Long[] triple = triples.next();
                    removeFromIndex(triple, subMID);
                }
                triples.close();
            }
        }
        iterator.close();
    }
}
TOP

Related Classes of org.jrdf.graph.global.MoleculeGraphImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.