Package com.tinkerpop.blueprints.impls.orient

Source Code of com.tinkerpop.blueprints.impls.orient.OrientIndex

package com.tinkerpop.blueprints.impls.orient;

import java.util.Collection;
import java.util.Collections;
import java.util.List;

import com.orientechnologies.common.collection.OCompositeKey;
import com.orientechnologies.orient.core.db.record.OIdentifiable;
import com.orientechnologies.orient.core.index.OIndex;
import com.orientechnologies.orient.core.index.OIndexTxAwareMultiValue;
import com.orientechnologies.orient.core.index.OIndexTxAwareOneValue;
import com.orientechnologies.orient.core.index.OSimpleKeyIndexDefinition;
import com.orientechnologies.orient.core.metadata.schema.OClass;
import com.orientechnologies.orient.core.metadata.schema.OType;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.tinkerpop.blueprints.CloseableIterable;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Element;
import com.tinkerpop.blueprints.Index;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.util.StringFactory;
import com.tinkerpop.blueprints.util.WrappingCloseableIterable;

/**
* @author Luca Garulli (http://www.orientechnologies.com)
*/
@SuppressWarnings("unchecked")
public class OrientIndex<T extends OrientElement> implements Index<T> {
    protected static final String VERTEX = "Vertex";
    protected static final String EDGE = "Edge";
    protected static final String CONFIG_CLASSNAME = "blueprintsIndexClass";
    public static final String CONFIG_RECORD_MAP_NAME = "record_map_name";

    protected static final String SEPARATOR = "!=!";

    protected OrientBaseGraph graph;
    protected OIndex<?> underlying;
    protected OIndex<?> recordKeyValueIndex;

    protected Class<? extends Element> indexClass;

    protected OrientIndex(final OrientBaseGraph graph, final String indexName, final Class<? extends Element> indexClass,
                          final OType iType) {
        this.graph = graph;
        this.indexClass = indexClass;
        create(indexName, this.indexClass, iType);
    }

    protected OrientIndex(final OrientBaseGraph orientGraph, final OIndex<?> rawIndex) {
        this.graph = orientGraph;
        this.underlying = rawIndex instanceof OIndexTxAwareMultiValue ? rawIndex : new OIndexTxAwareMultiValue(
                orientGraph.getRawGraph(), (OIndex<Collection<OIdentifiable>>) rawIndex);
        load(rawIndex.getMetadata());
    }

    public String getIndexName() {
        return underlying.getName();
    }

    public Class<T> getIndexClass() {
        return (Class<T>) this.indexClass;
    }

    public void put(final String key, final Object value, final T element) {
        final String keyTemp = key + SEPARATOR + value;

        final ODocument doc = element.getRecord();
        if (!doc.getIdentity().isValid())
            doc.save();

        graph.autoStartTransaction();
        underlying.put(keyTemp, doc);
        recordKeyValueIndex.put(new OCompositeKey(element.getIdentity(), keyTemp), element.getIdentity());
    }

    @SuppressWarnings("rawtypes")
    public CloseableIterable<T> get(final String key, final Object iValue) {
        final String keyTemp = key + SEPARATOR + iValue;
        Collection<OIdentifiable> records = (Collection<OIdentifiable>) underlying.get(keyTemp);

        if (records == null || records.isEmpty())
            return new WrappingCloseableIterable(Collections.emptySet());

        return new OrientElementIterable<T>(graph, records);
    }

    public CloseableIterable<T> query(final String key, final Object query) throws UnsupportedOperationException {
        throw new UnsupportedOperationException();
    }

    public long count(final String key, final Object value) {
        final String keyTemp = key + SEPARATOR + value;
        final Collection<OIdentifiable> records = (Collection<OIdentifiable>) underlying.get(keyTemp);
        return records.size();
    }

    public void remove(final String key, final Object value, final T element) {
        final String keyTemp = key + SEPARATOR + value;
        graph.autoStartTransaction();
        try {
            underlying.remove(keyTemp, element.getRecord());
            recordKeyValueIndex.remove(new OCompositeKey(element.getIdentity(), keyTemp), element.getIdentity());
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    public String toString() {
        return StringFactory.indexString(this);
    }

    protected void removeElement(final T element) {
        graph.autoStartTransaction();
        Collection<ODocument> entries = recordKeyValueIndex.getEntriesBetween(new OCompositeKey(element.getIdentity()),
                new OCompositeKey(element.getIdentity()));
        for (ODocument entry : entries) {
            OCompositeKey key = entry.field("key");
            List<Object> keys = key.getKeys();
            underlying.remove(keys.get(1).toString(), element.getIdentity());
            recordKeyValueIndex.remove(key, element.getIdentity());
        }
    }

    public OIndex<?> getUnderlying() {
        return underlying;
    }

    private void create(final String indexName, final Class<? extends Element> indexClass, OType iKeyType) {
        this.indexClass = indexClass;

        if (iKeyType == null)
            iKeyType = OType.STRING;

        this.recordKeyValueIndex = new OIndexTxAwareOneValue(graph.getRawGraph(), (OIndex<OIdentifiable>) graph
                .getRawGraph()
                .getMetadata()
                .getIndexManager()
                .createIndex("__@recordmap@___" + indexName, OClass.INDEX_TYPE.DICTIONARY.toString(),
                        new OSimpleKeyIndexDefinition(OType.LINK, OType.STRING), null, null, null));

        final String className;
        if (Vertex.class.isAssignableFrom(indexClass))
            className = VERTEX;
        else if (Edge.class.isAssignableFrom(indexClass))
            className = EDGE;
        else
            className = indexClass.getName();

        final ODocument metadata = new ODocument();
        metadata.field(CONFIG_CLASSNAME, className);
        metadata.field(CONFIG_RECORD_MAP_NAME, recordKeyValueIndex.getName());

        // CREATE THE MAP
        this.underlying = new OIndexTxAwareMultiValue(graph.getRawGraph(), (OIndex<Collection<OIdentifiable>>) graph.getRawGraph()
                .getMetadata().getIndexManager()
                .createIndex(indexName, OClass.INDEX_TYPE.NOTUNIQUE.toString(), new OSimpleKeyIndexDefinition(iKeyType), null, null
                        , metadata));


    }

    private void load(final ODocument metadata) {
        // LOAD TREEMAP
        final String indexClassName = metadata.field(CONFIG_CLASSNAME);
        final String recordKeyValueMap = metadata.field(CONFIG_RECORD_MAP_NAME);

        if (VERTEX.equals(indexClassName))
            this.indexClass = OrientVertex.class;
        else if (EDGE.equals(indexClassName))
            this.indexClass = OrientEdge.class;
        else
            try {
                this.indexClass = (Class<T>) Class.forName(indexClassName);
            } catch (ClassNotFoundException e) {
                throw new IllegalArgumentException("Index class '" + indexClassName
                        + "' is not registered. Supported ones: Vertex, Edge and custom class that extends them");
            }

        recordKeyValueIndex = new OIndexTxAwareOneValue(graph.getRawGraph(), (OIndex<OIdentifiable>) graph.getRawGraph().getMetadata()
                .getIndexManager().getIndex(recordKeyValueMap));
    }

    public void close() {
        if (underlying != null) {
            underlying.flush();
            underlying = null;
        }
        graph = null;
    }

}
TOP

Related Classes of com.tinkerpop.blueprints.impls.orient.OrientIndex

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.