1/*2 * Licensed to the Apache Software Foundation (ASF) under one3 * or more contributor license agreements. See the NOTICE file4 * distributed with this work for additional information5 * regarding copyright ownership. The ASF licenses this file6 * to you under the Apache License, Version 2.0 (the7 * "License"); you may not use this file except in compliance8 * with the License. You may obtain a copy of the License at9 *10 * http://www.apache.org/licenses/LICENSE-2.011 *12 * Unless required by applicable law or agreed to in writing, software13 * distributed under the License is distributed on an "AS IS" BASIS,14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.15 * See the License for the specific language governing permissions and16 * limitations under the License.17 */1819package org.apache.giraph.edge;
2021import org.apache.giraph.conf.ImmutableClassesGiraphConfiguration;
22import org.apache.hadoop.io.Writable;
23import org.apache.hadoop.io.WritableComparable;
2425import java.io.DataInput;
26import java.io.DataOutput;
27import java.io.IOException;
28import java.util.Iterator;
2930/**31 * Helper class that wraps the current out-edges and inserts them into a new32 * data structure as they are iterated over.33 * Used by Vertex to provide a mutable iterator when the chosen34 * {@link OutEdges} doesn't offer a specialized one.35 * The edges are "unwrapped" back to the chosen {@link OutEdges} data36 * structure as soon as possible: either when the iterator is exhausted,37 * or after compute() if iteration has been terminated early.38 *39 * @param <I> Vertex id40 * @param <E> Edge value41 */42publicclass MutableEdgesWrapper<I extends WritableComparable,
43 E extends Writable> implements OutEdges<I, E> {
44/** New edges data structure (initially empty). */45privatefinal OutEdges<I, E> newEdges;
46/** Iterator over the old edges. */47privatefinal Iterator<Edge<I, E>> oldEdgesIterator;
48/** Last edge that was returned during iteration. */49private MutableEdge<I, E> currentEdge;
50/** Number of edges. */51privateint numEdges;
5253/**54 * Private constructor: instantiation happens through the {@code wrap()}55 * factory method.56 *57 * @param oldEdges Current out-edges58 * @param newEdges New (empty) edges data structure59 */60privateMutableEdgesWrapper(OutEdges<I, E> oldEdges,
61 OutEdges<I, E> newEdges) {
62 oldEdgesIterator = oldEdges.iterator();
63this.newEdges = newEdges;
64 numEdges = oldEdges.size();
65 }
6667/**68 * Factory method to create a new wrapper over the existing out-edges.69 *70 * @param edges Current out-edges71 * @param conf Configuration72 * @param <I> Vertex id73 * @param <E> Edge value74 * @return The wrapped edges75 */76publicstatic <I extends WritableComparable, E extends Writable>
77 MutableEdgesWrapper<I, E> wrap(
78 OutEdges<I, E> edges,
79 ImmutableClassesGiraphConfiguration<I, ?, E> conf) {
80 MutableEdgesWrapper<I, E> wrapper = new MutableEdgesWrapper<I, E>(
81 edges, conf.createAndInitializeOutEdges(edges.size()));
82return wrapper;
83 }
8485/**86 * Moves all the remaining edges to the new data structure, and returns it.87 *88 * @return The new {@link OutEdges} data structure.89 */90public OutEdges<I, E> unwrap() {
91if (currentEdge != null) {
92 newEdges.add(currentEdge);
93 currentEdge = null;
94 }
95while (oldEdgesIterator.hasNext()) {
96 newEdges.add(oldEdgesIterator.next());
97 }
98return newEdges;
99 }
100101/**102 * Get the new {@link OutEdges} data structure.103 *104 * @return New edges105 */106public OutEdges<I, E> getNewEdges() {
107return newEdges;
108 }
109110/**111 * Get the iterator over the old edges data structure.112 *113 * @return Old edges iterator114 */115public Iterator<Edge<I, E>> getOldEdgesIterator() {
116return oldEdgesIterator;
117 }
118119/**120 * Get the last edge returned by the mutable iterator.121 *122 * @return Last edge iterated on123 */124public MutableEdge<I, E> getCurrentEdge() {
125return currentEdge;
126 }
127128/**129 * Set the last edge returned by the mutable iterator.130 *131 * @param edge Last edge iterated on132 */133publicvoid setCurrentEdge(MutableEdge<I, E> edge) {
134 currentEdge = edge;
135 }
136137/**138 * Decrement the number of edges (to account for a deletion from the mutable139 * iterator).140 */141publicvoid decrementEdges() {
142 --numEdges;
143 }
144145 @Override
146publicvoid initialize(Iterable<Edge<I, E>> edges) {
147thrownew IllegalStateException("initialize: MutableEdgesWrapper should " +
148"never be initialized.");
149 }
150151 @Override
152publicvoid initialize(int capacity) {
153thrownew IllegalStateException("initialize: MutableEdgesWrapper should " +
154"never be initialized.");
155 }
156157 @Override
158publicvoid initialize() {
159thrownew IllegalStateException("initialize: MutableEdgesWrapper should " +
160"never be initialized.");
161 }
162163 @Override
164publicvoid add(Edge<I, E> edge) {
165 unwrap().add(edge);
166 }
167168 @Override
169publicvoid remove(I targetVertexId) {
170 unwrap().remove(targetVertexId);
171 }
172173 @Override
174publicint size() {
175return numEdges;
176 }
177178 @Override
179public Iterator<Edge<I, E>> iterator() {
180return unwrap().iterator();
181 }
182183 @Override
184publicvoid write(DataOutput out) throws IOException {
185thrownew IllegalStateException("write: MutableEdgesWrapper should " +
186"never be serialized.");
187 }
188189 @Override
190publicvoid readFields(DataInput in) throws IOException {
191thrownew IllegalStateException("readFields: MutableEdgesWrapper should " +
192"never be deserialized.");
193 }
194 }