1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * 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 and
16 * limitations under the License.
17 */
18
19 package org.apache.giraph.utils;
20
21 import org.apache.giraph.conf.ImmutableClassesGiraphConfiguration;
22 import org.apache.giraph.edge.OutEdges;
23 import org.apache.giraph.graph.Vertex;
24 import org.apache.hadoop.io.Writable;
25 import org.apache.hadoop.io.WritableComparable;
26
27 import java.io.IOException;
28
29 /**
30 * Iterates over vertices stored in an ExtendedDataOutput such that
31 * the ownership of the vertex id can be transferred to another object.
32 * This optimization cuts down on the number of objects instantiated and
33 * garbage collected
34 *
35 * @param <I> Vertex id
36 * @param <V> Vertex value
37 * @param <E> Edge value
38 */
39 public class VertexIterator<I extends WritableComparable,
40 V extends Writable, E extends Writable> {
41 /** Reader of the serialized edges */
42 private final ExtendedDataInput extendedDataInput;
43 /** Current vertex */
44 private Vertex<I, V, E> vertex;
45 /** Configuration */
46 private final ImmutableClassesGiraphConfiguration<I, V, E> configuration;
47
48 /**
49 * Constructor.
50 *
51 * @param extendedDataOutput Extended data output
52 * @param configuration Configuration
53 */
54 public VertexIterator(
55 ExtendedDataOutput extendedDataOutput,
56 ImmutableClassesGiraphConfiguration<I, V, E> configuration) {
57 extendedDataInput = configuration.createExtendedDataInput(
58 extendedDataOutput.getByteArray(), 0, extendedDataOutput.getPos());
59 this.configuration = configuration;
60 resetEmptyVertex();
61 }
62
63 /**
64 * Reset the empty Vertex to an initial state.
65 */
66 private void resetEmptyVertex() {
67 vertex = configuration.createVertex();
68 I id = configuration.createVertexId();
69 V value = configuration.createVertexValue();
70 OutEdges<I, E> edges = configuration.createOutEdges();
71 vertex.initialize(id, value, edges);
72 }
73
74 /**
75 * Returns true if the iteration has more elements.
76 *
77 * @return True if the iteration has more elements.
78 */
79 public boolean hasNext() {
80 return !extendedDataInput.endOfInput();
81 }
82
83 /**
84 * Moves to the next element in the iteration.
85 */
86 public void next() {
87 // If the vertex was released, create another one
88 if (vertex == null) {
89 resetEmptyVertex();
90 }
91
92 // If the vertex id was released, create another one
93 if (vertex.getId() == null) {
94 vertex.initialize(configuration.createVertexId(), vertex.getValue());
95 }
96
97 try {
98 WritableUtils.reinitializeVertexFromDataInput(
99 extendedDataInput, vertex, configuration);
100 } catch (IOException e) {
101 throw new IllegalStateException("next: IOException", e);
102 }
103 }
104
105 /**
106 * Get the current vertex id. Ihis object's contents are only guaranteed
107 * until next() is called. To take ownership of this object call
108 * releaseCurrentVertexId() after getting a reference to this object.
109 *
110 * @return Current vertex id
111 */
112 public I getCurrentVertexId() {
113 return vertex.getId();
114 }
115
116 /**
117 * The backing store of the current vertex id is now released.
118 * Further calls to getCurrentVertexId () without calling next()
119 * will return null.
120 *
121 * @return Current vertex id that was released
122 */
123 public I releaseCurrentVertexId() {
124 I releasedVertexId = vertex.getId();
125 vertex.initialize(null, vertex.getValue());
126 return releasedVertexId;
127 }
128
129 public Vertex<I, V, E> getVertex() {
130 return vertex;
131 }
132
133 /**
134 * Release the ownership of the Vertex object to the caller
135 *
136 * @return Released Vertex object
137 */
138 public Vertex<I, V, E> releaseVertex() {
139 Vertex<I, V, E> releasedVertex = vertex;
140 vertex = null;
141 return releasedVertex;
142 }
143 }