org.sf.xrime.model.vertex.AdjBiSetVertex.java Source code

Java tutorial

Introduction

Here is the source code for org.sf.xrime.model.vertex.AdjBiSetVertex.java

Source

/*
 * Copyright (C) IBM Corp. 2009.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.sf.xrime.model.vertex;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.io.WritableFactories;
import org.apache.hadoop.io.WritableFactory;
import org.sf.xrime.model.edge.AbstractEdge;
import org.sf.xrime.model.edge.AdjVertexEdge;

/**
 * An object of this class represents a vertex and its bi-directional adjacent
 * vertexes. The difference with AdjSetVertex is that this class distinguishes
 * the forward adjacent vertexes and backward adjacent vertexes.
 * 
 * @author xue
 * 
 */
public class AdjBiSetVertex extends Vertex implements Cloneable {
    static {
        // Register the writable factory for this class.
        WritableFactories.setFactory(AdjBiSetVertex.class, new WritableFactory() {
            public Writable newInstance() {
                return new AdjBiSetVertex();
            }
        });
    }

    /**
     * The set for forward adjacent vertexes. All elements should have the same
     * type (AdjVertexEdge or its derivants).
     */
    protected Set<AdjVertexEdge> _forward_vertexes = null;

    /**
     * The set for backward adjacent vertexes. All elements should have the same
     * type (AdjVertexEdge or its derivants).
     */
    protected Set<AdjVertexEdge> _backward_vertexes = null;

    /**
     * Default constructor.
     */
    public AdjBiSetVertex() {
        super();
        _forward_vertexes = new HashSet<AdjVertexEdge>();
        _backward_vertexes = new HashSet<AdjVertexEdge>();
    }

    /**
     * Another constructor.
     * @param id
     */
    public AdjBiSetVertex(String id) {
        super(id);
        _forward_vertexes = new HashSet<AdjVertexEdge>();
        _backward_vertexes = new HashSet<AdjVertexEdge>();
    }

    /**
     * Copy constructor.
     * 
     * @param copy
     */
    public AdjBiSetVertex(AdjBiSetVertex copy) {
        super(copy);
        _forward_vertexes = new HashSet<AdjVertexEdge>();
        for (AdjVertexEdge edge : copy._forward_vertexes) {
            _forward_vertexes.add((AdjVertexEdge) edge.clone());
        }
        _backward_vertexes = new HashSet<AdjVertexEdge>();
        for (AdjVertexEdge edge : copy._backward_vertexes) {
            _backward_vertexes.add((AdjVertexEdge) edge.clone());
        }
    }

    /**
     * Get the set of forward vertexes of this vertex.
     * 
     * @return
     */
    public Set<AdjVertexEdge> getForwardVertexes() {
        return _forward_vertexes;
    }

    /**
     * Get the set of backward vertexes of this vertex.
     * 
     * @return
     */
    public Set<AdjVertexEdge> getBackwardVertexes() {
        return _backward_vertexes;
    }

    /**
     * Add specified vertex to the forward vertexes set.
     * 
     * @param vertex
     */
    public void addForwardVertex(AdjVertexEdge vertex) {
        _forward_vertexes.add(vertex);
    }

    /**
     * Remove specified vertex from the forward vertexes set.
     * 
     * @param vertex
     */
    public void removeForwardVertex(AdjVertexEdge vertex) {
        _forward_vertexes.remove(vertex);
    }

    /**
     * Clear the set of forward vertex set.
     */
    public void clearForwardVertex() {
        _forward_vertexes.clear();
    }

    /**
     * Add specified vertex to the backward vertexes set.
     * 
     * @param vertex
     */
    public void addBackwardVertex(AdjVertexEdge vertex) {
        _backward_vertexes.add(vertex);
    }

    /**
     * Remove specified vertex from the backward vertexes set.
     * 
     * @param vertex
     */
    public void removeBackwardVertex(AdjVertexEdge vertex) {
        _backward_vertexes.remove(vertex);
    }

    /**
     * Clear the set of backward vertex set.
     */
    public void clearBackwardVertex() {
        _backward_vertexes.clear();
    }

    /**
     * Remove loop.
     */
    public void removeLoop() {
        _forward_vertexes.remove(id);
        _backward_vertexes.remove(id);
    }

    @Override
    public Object clone() {
        return new AdjBiSetVertex(this);
    }

    @SuppressWarnings("unchecked")
    @Override
    public void readFields(DataInput in) throws IOException {
        // Call super first.
        super.readFields(in);
        // Clean containers.
        _forward_vertexes.clear();
        _backward_vertexes.clear();
        // Deal with forward vertex set.
        int size = in.readInt();
        if (size > 0) {
            // Determine the type of elements.
            String className = Text.readString(in);
            try {
                Class instanceClass = Class.forName(className);
                for (int ii = 0; ii < size; ii++) {
                    Writable writable = WritableFactories.newInstance(instanceClass, null);
                    writable.readFields(in);
                    if (writable instanceof AdjVertexEdge) {
                        addForwardVertex((AdjVertexEdge) writable);
                    }
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        // Deal with backward vertex set.
        size = in.readInt();
        if (size > 0) {
            // Determine the type of elements.
            String className = Text.readString(in);
            Class instanceClass;
            try {
                instanceClass = Class.forName(className);
                for (int i = 0; i < size; i++) {
                    Writable writable = WritableFactories.newInstance(instanceClass, null);
                    writable.readFields(in);
                    if (writable instanceof AdjVertexEdge) {
                        addBackwardVertex((AdjVertexEdge) writable);
                    }
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void write(DataOutput out) throws IOException {
        // Write the pure vertex id.
        super.write(out);
        // Deal with the forward and backward vertexes sets.
        if (_forward_vertexes == null || _forward_vertexes.size() == 0) {
            out.writeInt(0);
        } else {
            out.writeInt(_forward_vertexes.size());
            Text.writeString(out, _forward_vertexes.toArray()[0].getClass().getName());
            for (AdjVertexEdge edge : _forward_vertexes) {
                edge.write(out);
            }
        }
        if (_backward_vertexes == null || _backward_vertexes.size() == 0) {
            out.writeInt(0);
        } else {
            out.writeInt(_backward_vertexes.size());
            Text.writeString(out, _backward_vertexes.toArray()[0].getClass().getName());
            for (AdjVertexEdge edge : _backward_vertexes) {
                edge.write(out);
            }
        }
    }

    @Override
    public String toString() {
        StringBuffer result_buf = new StringBuffer();
        result_buf.append("<");
        result_buf.append(id);
        result_buf.append(", <");
        for (AdjVertexEdge edge : _forward_vertexes) {
            result_buf.append(((AdjVertexEdge) edge).toString());
            result_buf.append(", ");
        }
        if (_forward_vertexes.size() > 0)
            result_buf.delete(result_buf.length() - 2, result_buf.length());
        result_buf.append(">, <");
        for (AdjVertexEdge edge : _backward_vertexes) {
            result_buf.append(((AdjVertexEdge) edge).toString());
            result_buf.append(", ");
        }
        if (_backward_vertexes.size() > 0)
            result_buf.delete(result_buf.length() - 2, result_buf.length());
        result_buf.append(">>");
        return result_buf.toString();
    }

    @Override
    public void fromString(String encoding) {
        // Clean.
        id = null;
        _forward_vertexes.clear();
        _backward_vertexes.clear();

        // id.
        int pointerA = 0, pointerB = 0;
        pointerB = encoding.indexOf(", <", pointerA);
        id = encoding.substring(pointerA + 1, pointerB);
        pointerA = pointerB + 3;

        // forward and backward opposite vertexes.
        pointerB = encoding.indexOf(">, <", pointerA);
        String forward_str = encoding.substring(pointerA, pointerB);
        String backward_str = encoding.substring(pointerB + 4, encoding.length() - 2);

        if (forward_str.length() != 0) {
            pointerA = 0;
            pointerB = 0;
            while (true) {
                pointerB = forward_str.indexOf(", ", pointerA);
                if (pointerB == -1) {
                    _forward_vertexes.add(new AdjVertexEdge(forward_str.substring(pointerA, forward_str.length())));
                    break;
                } else {
                    _forward_vertexes.add(new AdjVertexEdge(forward_str.substring(pointerA, pointerB)));
                }
                pointerA = pointerB + 2;
            }
        }

        if (backward_str.length() != 0) {
            pointerA = 0;
            pointerB = 0;
            while (true) {
                pointerB = backward_str.indexOf(", ", pointerA);
                if (pointerB == -1) {
                    _backward_vertexes
                            .add(new AdjVertexEdge(backward_str.substring(pointerA, backward_str.length())));
                    break;
                } else {
                    _backward_vertexes.add(new AdjVertexEdge(backward_str.substring(pointerA, pointerB)));
                }
                pointerA = pointerB + 2;
            }
        }
    }

    @Override
    public Iterator<AbstractEdge> getIncidentElements() {
        class Itr implements Iterator<AbstractEdge> {
            int status = 0;
            Iterator<AdjVertexEdge> itrForward;
            Iterator<AdjVertexEdge> itrBackward;

            @Override
            public boolean hasNext() {
                boolean ret = false;

                if (status == 0) {
                    if (itrForward != null) {
                        status = 1;
                        return itrForward.hasNext();
                    }
                    if (itrBackward != null) {
                        status = 2;
                        return itrBackward.hasNext();
                    }
                    status = 3;
                    return false;
                } else if (status == 1) {
                    ret = itrForward.hasNext();
                    if (!ret) {
                        if (itrBackward != null) {
                            status = 2;
                            return itrBackward.hasNext();
                        }
                        status = 3;
                        return false;
                    }
                } else if (status == 2) {
                    ret = itrBackward.hasNext();
                    if (!ret) {
                        status = 3;
                        return false;
                    }
                } else if (status == 3) {
                    return false;
                }

                return ret;
            }

            @Override
            public AbstractEdge next() {
                if (status == 1) {
                    return itrForward.next();
                } else if (status == 2) {
                    return itrBackward.next();
                }
                return null;
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException("This is a read-only iterator");
            }

            public void setItrForward(Iterator<AdjVertexEdge> itr) {
                this.itrForward = itr;
            }

            public void setItrBackward(Iterator<AdjVertexEdge> itr) {
                this.itrBackward = itr;
            }
        }

        Itr ret = new Itr();

        if (_forward_vertexes != null) {
            ret.setItrForward(_forward_vertexes.iterator());
        }
        if (_backward_vertexes != null) {
            ret.setItrBackward(_backward_vertexes.iterator());
        }

        return ret;
    }
}