Package com.thinkaurelius.faunus

Source Code of com.thinkaurelius.faunus.FaunusElement$Comparator

package com.thinkaurelius.faunus;

import com.thinkaurelius.titan.diskstorage.ReadBuffer;
import com.thinkaurelius.titan.diskstorage.StaticBuffer;
import com.thinkaurelius.titan.diskstorage.util.ByteBufferUtil;
import com.thinkaurelius.titan.diskstorage.util.ReadByteBuffer;
import com.thinkaurelius.titan.graphdb.database.serialize.kryo.KryoSerializer;
import com.tinkerpop.blueprints.Element;
import com.tinkerpop.blueprints.util.ElementHelper;
import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.io.WritableComparator;
import org.apache.hadoop.io.WritableUtils;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
*/
public abstract class FaunusElement implements Element, WritableComparable<FaunusElement> {

    static {
        WritableComparator.define(FaunusElement.class, new Comparator());
    }

    protected static final KryoSerializer serialize = new KryoSerializer();

    protected static final Map<String, String> TYPE_MAP = new HashMap<String, String>() {
        @Override
        public final String get(final Object object) {
            final String label = (String) object;
            final String existing = super.get(label);
            if (null == existing) {
                super.put(label, label);
                return label;
            } else {
                return existing;
            }
        }
    };

    protected long id;
    protected Map<String, Object> properties = null;
    protected List<List<MicroElement>> paths = null;
    private MicroElement microVersion = null;
    protected boolean pathEnabled = false;
    protected long pathCounter = 0;


    public FaunusElement(final long id) {
        this.id = id;
    }

    protected FaunusElement reuse(final long id) {
        this.id = id;
        this.properties = null;
        this.clearPaths();
        return this;
    }

    @Override
    public void remove() throws UnsupportedOperationException {
        //TODO: should this be supported?
        throw new UnsupportedOperationException();
    }

    public void enablePath(final boolean enablePath) {
        this.pathEnabled = enablePath;
        if (this.pathEnabled) {
            if (null == this.microVersion)
                this.microVersion = (this instanceof FaunusVertex) ? new FaunusVertex.MicroVertex(this.id) : new FaunusEdge.MicroEdge(this.id);
            if (null == this.paths)
                this.paths = new ArrayList<List<MicroElement>>();
        }
        // TODO: else make pathCounter = paths.size()?
    }

    public void addPath(final List<MicroElement> path, final boolean append) throws IllegalStateException {
        if (this.pathEnabled) {
            if (append) path.add(this.microVersion);
            this.paths.add(path);
        } else {
            throw new IllegalStateException("Path calculations are not enabled");
        }
    }

    public void addPaths(final List<List<MicroElement>> paths, final boolean append) throws IllegalStateException {
        if (this.pathEnabled) {
            if (append) {
                for (final List<MicroElement> path : paths) {
                    this.addPath(path, append);
                }
            } else
                this.paths.addAll(paths);
        } else {
            throw new IllegalStateException("Path calculations are not enabled");
        }
    }

    public List<List<MicroElement>> getPaths() throws IllegalStateException {
        if (this.pathEnabled)
            return this.paths;
        else
            throw new IllegalStateException("Path calculations are not enabled");
    }

    public void getPaths(final FaunusElement element, final boolean append) {
        if (this.pathEnabled) {
            this.addPaths(element.getPaths(), append);
        } else {
            this.pathCounter = this.pathCounter + element.pathCount();
        }
    }

    public long incrPath(final long amount) throws IllegalStateException {
        if (this.pathEnabled)
            throw new IllegalStateException("Path calculations are enabled -- use addPath()");
        else
            this.pathCounter = this.pathCounter + amount;
        return this.pathCounter;
    }

    public boolean hasPaths() {
        if (this.pathEnabled)
            return !this.paths.isEmpty();
        else
            return this.pathCounter > 0;
    }

    public void clearPaths() {
        if (this.pathEnabled) {
            this.paths = new ArrayList<List<MicroElement>>();
            this.microVersion = (this instanceof FaunusVertex) ? new FaunusVertex.MicroVertex(this.id) : new FaunusEdge.MicroEdge(this.id);
        } else
            this.pathCounter = 0;
    }

    public long pathCount() {
        if (this.pathEnabled)
            return this.paths.size();
        else
            return this.pathCounter;
    }

    public void startPath() {
        if (this.pathEnabled) {
            this.clearPaths();
            final List<MicroElement> startPath = new ArrayList<MicroElement>();
            startPath.add(this.microVersion);
            this.paths.add(startPath);
        } else {
            this.pathCounter = 1;
        }
    }

    public void setProperty(final String key, final Object value) {
        ElementHelper.validateProperty(this, key, value);
        if (key.equals(Tokens._COUNT))
            throw new IllegalArgumentException("_count is a reserved property");

        if (null == this.properties)
            this.properties = new HashMap<String, Object>();
        this.properties.put(TYPE_MAP.get(key), value);
    }

    public <T> T removeProperty(final String key) {
        return null == this.properties ? null : (T) this.properties.remove(key);
    }

    public <T> T getProperty(final String key) {
        if (key.equals(Tokens._COUNT))
            return (T) Long.valueOf(this.pathCount());
        return null == this.properties ? null : (T) this.properties.get(key);
    }

    public Set<String> getPropertyKeys() {
        return null == this.properties ? (Set) Collections.emptySet() : this.properties.keySet();
    }

    public Map<String, Object> getProperties() {
        return null == this.properties ? this.properties = new HashMap<String, Object>() : this.properties;
    }

    public Object getId() {
        return this.id;
    }

    public long getIdAsLong() {
        return this.id;
    }

    public void readFields(final DataInput in) throws IOException {
        this.id = WritableUtils.readVLong(in);
        this.pathEnabled = in.readBoolean();
        if (this.pathEnabled) {
            this.paths = ElementPaths.readFields(in);
            this.microVersion = (this instanceof FaunusVertex) ? new FaunusVertex.MicroVertex(this.id) : new FaunusEdge.MicroEdge(this.id);
        } else
            this.pathCounter = WritableUtils.readVLong(in);
        this.properties = ElementProperties.readFields(in);
    }

    public void write(final DataOutput out) throws IOException {
        WritableUtils.writeVLong(out, this.id);
        out.writeBoolean(this.pathEnabled);
        if (this.pathEnabled)
            ElementPaths.write(this.paths, out);
        else
            WritableUtils.writeVLong(out, this.pathCounter);
        ElementProperties.write(this.properties, out);
    }

    @Override
    public boolean equals(final Object other) {
        return this.getClass().equals(other.getClass()) && this.id == ((FaunusElement) other).getIdAsLong();
    }

    @Override
    public int hashCode() {
        return ((Long) this.id).hashCode();
    }

    public int compareTo(final FaunusElement other) {
        return new Long(this.id).compareTo((Long) other.getId());
    }

    public static class ElementProperties {

        public static void write(final Map<String, Object> properties, final DataOutput out) throws IOException {
            if (null == properties || properties.size() == 0)
                WritableUtils.writeVInt(out, 0);
            else {
                WritableUtils.writeVInt(out, properties.size());
                final com.thinkaurelius.titan.graphdb.database.serialize.DataOutput o = serialize.getDataOutput(128, true);
                for (final Map.Entry<String, Object> entry : properties.entrySet()) {
                    o.writeObject(entry.getKey(), String.class);
                    o.writeClassAndObject(entry.getValue());
                }
                final StaticBuffer buffer = o.getStaticBuffer();
                WritableUtils.writeVInt(out, buffer.length());
                out.write(ByteBufferUtil.getArray(buffer.asByteBuffer()));
            }
        }

        public static Map<String, Object> readFields(final DataInput in) throws IOException {
            final int numberOfProperties = WritableUtils.readVInt(in);
            if (numberOfProperties == 0)
                return null;
            else {
                final Map<String, Object> properties = new HashMap<String, Object>();
                byte[] bytes = new byte[WritableUtils.readVInt(in)];
                in.readFully(bytes);
                final ReadBuffer buffer = new ReadByteBuffer(bytes);
                for (int i = 0; i < numberOfProperties; i++) {
                    final String key = serialize.readObject(buffer, String.class);
                    final Object valueObject = serialize.readClassAndObject(buffer);
                    properties.put(TYPE_MAP.get(key), valueObject);
                }
                return properties;
            }
        }
    }

    public static class ElementPaths {

        public static void write(final List<List<MicroElement>> paths, final DataOutput out) throws IOException {
            if (null == paths) {
                WritableUtils.writeVInt(out, 0);
            } else {
                WritableUtils.writeVInt(out, paths.size());
                for (final List<MicroElement> path : paths) {
                    WritableUtils.writeVInt(out, path.size());
                    for (MicroElement element : path) {
                        if (element instanceof FaunusVertex.MicroVertex)
                            out.writeChar('v');
                        else
                            out.writeChar('e');
                        WritableUtils.writeVLong(out, element.getId());
                    }
                }
            }
        }

        public static List<List<MicroElement>> readFields(final DataInput in) throws IOException {
            int pathsSize = WritableUtils.readVInt(in);
            if (pathsSize == 0)
                return new ArrayList<List<MicroElement>>();
            else {
                final List<List<MicroElement>> paths = new ArrayList<List<MicroElement>>(pathsSize);
                for (int i = 0; i < pathsSize; i++) {
                    int pathSize = WritableUtils.readVInt(in);
                    final List<MicroElement> path = new ArrayList<MicroElement>(pathSize);
                    for (int j = 0; j < pathSize; j++) {
                        char type = in.readChar();
                        if (type == 'v')
                            path.add(new FaunusVertex.MicroVertex(WritableUtils.readVLong(in)));
                        else
                            path.add(new FaunusEdge.MicroEdge(WritableUtils.readVLong(in)));
                    }
                    paths.add(path);
                }
                return paths;
            }
        }

    }

    public static class Comparator extends WritableComparator {
        public Comparator() {
            super(FaunusElement.class);
        }

        @Override
        public int compare(final byte[] element1, final int start1, final int length1, final byte[] element2, final int start2, final int length2) {
            try {
                return Long.valueOf(readVLong(element1, start1)).compareTo(readVLong(element2, start2));
            } catch (IOException e) {
                return -1;
            }
        }

        @Override
        public int compare(final WritableComparable a, final WritableComparable b) {
            if (a instanceof FaunusElement && b instanceof FaunusElement)
                return ((Long) (((FaunusElement) a).getIdAsLong())).compareTo(((FaunusElement) b).getIdAsLong());
            else
                return super.compare(a, b);
        }
    }

    public static abstract class MicroElement {

        protected final long id;

        public MicroElement(final long id) {
            this.id = id;
        }

        public long getId() {
            return this.id;
        }

        public int hashCode() {
            return Long.valueOf(this.id).hashCode();
        }

        public boolean equals(final Object object) {
            return (object.getClass().equals(this.getClass()) && this.id == ((MicroElement) object).getId());
        }
    }
}
TOP

Related Classes of com.thinkaurelius.faunus.FaunusElement$Comparator

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.