1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.giraph.edge;
19
20 import java.io.DataInput;
21 import java.io.DataOutput;
22 import java.io.IOException;
23 import java.util.Iterator;
24 import java.util.NoSuchElementException;
25
26 import org.apache.giraph.conf.ImmutableClassesGiraphConfigurable;
27 import org.apache.giraph.conf.ImmutableClassesGiraphConfiguration;
28 import org.apache.giraph.types.ops.PrimitiveIdTypeOps;
29 import org.apache.giraph.types.ops.PrimitiveTypeOps;
30 import org.apache.giraph.types.ops.TypeOpsUtils;
31 import org.apache.giraph.types.ops.collections.array.WArrayList;
32 import org.apache.giraph.utils.EdgeIterables;
33 import org.apache.hadoop.io.Writable;
34 import org.apache.hadoop.io.WritableComparable;
35
36 import com.google.common.collect.UnmodifiableIterator;
37
38
39
40
41
42
43
44
45
46
47
48 public class IdAndValueArrayEdges<I extends WritableComparable,
49 E extends Writable> implements ReuseObjectsOutEdges<I, E>,
50 MutableOutEdges<I, E>,
51 ImmutableClassesGiraphConfigurable<I, Writable, E> {
52
53
54 private WArrayList<I> neighborIds;
55
56 private WArrayList<E> neighborEdgeValues;
57
58 @Override
59 public ImmutableClassesGiraphConfiguration<I, Writable, E> getConf() {
60 throw new UnsupportedOperationException();
61 }
62
63 @Override
64 public void setConf(
65 ImmutableClassesGiraphConfiguration<I, Writable, E> conf) {
66 PrimitiveIdTypeOps<I> idTypeOps =
67 TypeOpsUtils.getPrimitiveIdTypeOps(conf.getVertexIdClass());
68 neighborIds = idTypeOps.createArrayList(10);
69
70 PrimitiveTypeOps<E> edgeTypeOps =
71 TypeOpsUtils.getPrimitiveTypeOps(conf.getEdgeValueClass());
72 neighborEdgeValues = edgeTypeOps.createArrayList(10);
73 }
74
75 @Override
76 public void initialize(Iterable<Edge<I, E>> edges) {
77 EdgeIterables.initialize(this, edges);
78 }
79
80 @Override
81 public void initialize(int capacity) {
82 neighborIds.clear();
83 neighborIds.setCapacity(capacity);
84 neighborEdgeValues.clear();
85 neighborEdgeValues.setCapacity(capacity);
86 }
87
88 @Override
89 public void initialize() {
90 initialize(10);
91 }
92
93 @Override
94 public void add(Edge<I, E> edge) {
95 neighborIds.addW(edge.getTargetVertexId());
96 neighborEdgeValues.addW(edge.getValue());
97 }
98
99
100
101
102
103 private void trim() {
104 if (neighborIds.capacity() > 4 * neighborIds.size()) {
105 neighborIds.setCapacity(neighborIds.size() * 2);
106 neighborEdgeValues.setCapacity(neighborIds.size() * 2);
107 }
108 }
109
110
111
112
113
114
115 private void removeAt(int i) {
116
117
118
119 I tmpId = neighborIds.getElementTypeOps().create();
120 E tmpValue = neighborEdgeValues.getElementTypeOps().create();
121
122 neighborIds.popIntoW(tmpId);
123 neighborEdgeValues.popIntoW(tmpValue);
124 if (i != neighborIds.size()) {
125 neighborIds.setW(i, tmpId);
126 neighborEdgeValues.setW(i, tmpValue);
127 }
128
129 trim();
130 }
131
132 @Override
133 public void remove(I targetVertexId) {
134
135
136 I tmpId = neighborIds.getElementTypeOps().create();
137 for (int i = neighborIds.size() - 1; i >= 0; --i) {
138 neighborIds.getIntoW(i, tmpId);
139 if (tmpId.equals(targetVertexId)) {
140 removeAt(i);
141 }
142 }
143 }
144
145 @Override
146 public int size() {
147 return neighborIds.size();
148 }
149
150 @Override
151 public Iterator<Edge<I, E>> iterator() {
152
153 return new UnmodifiableIterator<Edge<I, E>>() {
154 private int index;
155
156
157 private final Edge<I, E> representativeEdge = EdgeFactory.create(
158 neighborIds.getElementTypeOps().create(),
159 neighborEdgeValues.getElementTypeOps().create());
160
161 @Override
162 public boolean hasNext() {
163 return index < neighborIds.size();
164 }
165
166 @Override
167 public Edge<I, E> next() {
168 if (!hasNext()) {
169 throw new NoSuchElementException();
170 }
171 neighborIds.getIntoW(index, representativeEdge.getTargetVertexId());
172 neighborEdgeValues.getIntoW(index, representativeEdge.getValue());
173 index++;
174 return representativeEdge;
175 }
176 };
177 }
178
179
180 private class ArrayMutableEdge extends DefaultEdge<I, E> {
181
182 private int index;
183
184
185 public ArrayMutableEdge() {
186 super(
187 neighborIds.getElementTypeOps().create(),
188 neighborEdgeValues.getElementTypeOps().create());
189 }
190
191
192
193
194
195
196 public void setIndex(int index) {
197
198 neighborIds.getIntoW(index, getTargetVertexId());
199 neighborEdgeValues.getIntoW(index, getValue());
200
201 this.index = index;
202 }
203
204 @Override
205 public void setValue(E value) {
206
207 neighborEdgeValues.getElementTypeOps().set(getValue(), value);
208
209 neighborEdgeValues.setW(index, value);
210 }
211 }
212
213 @Override
214 public Iterator<MutableEdge<I, E>> mutableIterator() {
215 return new Iterator<MutableEdge<I, E>>() {
216
217 private int index = 0;
218
219 private final ArrayMutableEdge representativeEdge =
220 new ArrayMutableEdge();
221
222 @Override
223 public boolean hasNext() {
224 return index < neighborIds.size();
225 }
226
227 @Override
228 public MutableEdge<I, E> next() {
229 if (!hasNext()) {
230 throw new NoSuchElementException();
231 }
232 representativeEdge.setIndex(index++);
233 return representativeEdge;
234 }
235
236 @Override
237 public void remove() {
238
239
240
241 removeAt(--index);
242 }
243 };
244 }
245
246 @Override
247 public void write(DataOutput out) throws IOException {
248 neighborIds.write(out);
249 neighborEdgeValues.write(out);
250 }
251
252 @Override
253 public void readFields(DataInput in) throws IOException {
254 neighborIds.readFields(in);
255 neighborEdgeValues.readFields(in);
256 }
257 }