org.apache.giraph.graph.HashMapVertex.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.giraph.graph.HashMapVertex.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.giraph.graph;

import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.io.WritableComparable;
import org.apache.log4j.Logger;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * User applications can subclass {@link HashMapVertex}, which stores
 * the outbound edges in a HashMap, for efficient edge random-access.  Note
 * that {@link EdgeListVertex} is much more memory efficient for static graphs.
 * User applications which need to implement their own
 * in-memory data structures should subclass {@link MutableVertex}.
 *
 * Package access will prevent users from accessing internal methods.
 *
 * @param <I> Vertex index value
 * @param <V> Vertex value
 * @param <E> Edge value
 * @param <M> Message value
 */
@SuppressWarnings("rawtypes")
public abstract class HashMapVertex<I extends WritableComparable, V extends Writable, E extends Writable, M extends Writable>
        extends MutableVertex<I, V, E, M> {
    /** Class logger */
    private static final Logger LOG = Logger.getLogger(HashMapVertex.class);
    /** Map of destination vertices and their edge values */
    protected final Map<I, Edge<I, E>> destEdgeMap = new HashMap<I, Edge<I, E>>();
    /** Vertex id */
    private I vertexId = null;
    /** Vertex value */
    private V vertexValue = null;
    /** List of incoming messages from the previous superstep */
    private final List<M> msgList = Lists.newArrayList();

    @Override
    public void initialize(I vertexId, V vertexValue, Map<I, E> edges, Iterable<M> messages) {
        if (vertexId != null) {
            setVertexId(vertexId);
        }
        if (vertexValue != null) {
            setVertexValue(vertexValue);
        }
        if (edges != null && !edges.isEmpty()) {
            for (Map.Entry<I, E> entry : edges.entrySet()) {
                destEdgeMap.put(entry.getKey(), new Edge<I, E>(entry.getKey(), entry.getValue()));
            }
        }
        if (messages != null) {
            Iterables.<M>addAll(msgList, messages);
        }
    }

    @Override
    public final boolean addEdge(I targetVertexId, E edgeValue) {
        if (destEdgeMap.put(targetVertexId, new Edge<I, E>(targetVertexId, edgeValue)) != null) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("addEdge: Vertex=" + vertexId + ": already added an edge value for dest vertex id "
                        + targetVertexId);
            }
            return false;
        } else {
            return true;
        }
    }

    @Override
    public long getSuperstep() {
        return getGraphState().getSuperstep();
    }

    @Override
    public final void setVertexId(I vertexId) {
        this.vertexId = vertexId;
    }

    @Override
    public final I getVertexId() {
        return vertexId;
    }

    @Override
    public final V getVertexValue() {
        return vertexValue;
    }

    @Override
    public final void setVertexValue(V vertexValue) {
        this.vertexValue = vertexValue;
    }

    @Override
    public E getEdgeValue(I targetVertexId) {
        Edge<I, E> edge = destEdgeMap.get(targetVertexId);
        return edge != null ? edge.getEdgeValue() : null;
    }

    @Override
    public boolean hasEdge(I targetVertexId) {
        return destEdgeMap.containsKey(targetVertexId);
    }

    /**
     * Get an iterator to the edges on this vertex.
     *
     * @return A <em>sorted</em> iterator, as defined by the sort-order
     *         of the vertex ids
     */
    @Override
    public Iterator<I> iterator() {
        return destEdgeMap.keySet().iterator();
    }

    @Override
    public int getNumOutEdges() {
        return destEdgeMap.size();
    }

    @Override
    public E removeEdge(I targetVertexId) {
        Edge<I, E> edge = destEdgeMap.remove(targetVertexId);
        if (edge != null) {
            return edge.getEdgeValue();
        } else {
            return null;
        }
    }

    @Override
    public final void sendMsgToAllEdges(M msg) {
        if (msg == null) {
            throw new IllegalArgumentException("sendMsgToAllEdges: Cannot send null message to all edges");
        }
        for (Edge<I, E> edge : destEdgeMap.values()) {
            sendMsg(edge.getDestVertexId(), msg);
        }
    }

    @Override
    public final void readFields(DataInput in) throws IOException {
        vertexId = BspUtils.<I>createVertexIndex(getConf());
        vertexId.readFields(in);
        boolean hasVertexValue = in.readBoolean();
        if (hasVertexValue) {
            vertexValue = BspUtils.<V>createVertexValue(getConf());
            vertexValue.readFields(in);
        }
        long edgeMapSize = in.readLong();
        for (long i = 0; i < edgeMapSize; ++i) {
            Edge<I, E> edge = new Edge<I, E>();
            edge.setConf(getConf());
            edge.readFields(in);
            addEdge(edge.getDestVertexId(), edge.getEdgeValue());
        }
        long msgListSize = in.readLong();
        for (long i = 0; i < msgListSize; ++i) {
            M msg = BspUtils.<M>createMessageValue(getConf());
            msg.readFields(in);
            msgList.add(msg);
        }
        halt = in.readBoolean();
    }

    @Override
    public final void write(DataOutput out) throws IOException {
        vertexId.write(out);
        out.writeBoolean(vertexValue != null);
        if (vertexValue != null) {
            vertexValue.write(out);
        }
        out.writeLong(destEdgeMap.size());
        for (Edge<I, E> edge : destEdgeMap.values()) {
            edge.write(out);
        }
        out.writeLong(msgList.size());
        for (M msg : msgList) {
            msg.write(out);
        }
        out.writeBoolean(halt);
    }

    @Override
    void putMessages(Iterable<M> messages) {
        msgList.clear();
        for (M message : messages) {
            msgList.add(message);
        }
    }

    @Override
    public Iterable<M> getMessages() {
        return Iterables.unmodifiableIterable(msgList);
    }

    @Override
    void releaseResources() {
        // Hint to GC to free the messages
        msgList.clear();
    }

    @Override
    public String toString() {
        return "Vertex(id=" + getVertexId() + ",value=" + getVertexValue() + ",#edges=" + destEdgeMap.size() + ")";
    }
}