Giraph中改进代码,想在Edge上面加点属性,结果发现修改后的值无法生效,Pagereank用的EdgeNoValue类中增加一个属性,但是始终读不出来值,
开始以为是使用int导致类型中间没有进行readFIles或者write的序列化问题, 但是EdgeNoValue根本没有相关方法,
且实际初始化使用的是 WritableUtils.reinitializeVertexFromDataInput( //实际读入顶点值和边值的函数
extendedDataInput, vertex, configuration)方法;
然后开始打印每条边对象的hashCode值, 结果发现每次都不一样,于是就懵逼了,为啥?
许久后终于发现DefaultVertex 的OutEdges<I, E> edges 类型居然是ByteArrayEdges,进去后查看发现:
private byte[] serializedEdges;
@Override
public void add(Edge<I, E> edge) {
ExtendedDataOutput extendedDataOutput =
getConf().createExtendedDataOutput(
serializedEdges, serializedEdgesBytesUsed);
try {
WritableUtils.writeEdge(extendedDataOutput, edge);
} catch (IOException e) {
throw new IllegalStateException("add: Failed to write to the new " +
"byte array");
}
serializedEdges = extendedDataOutput.getByteArray();
serializedEdgesBytesUsed = extendedDataOutput.getPos();
++edgeCount;
}
private class ByteArrayEdgeIterator
extends UnmodifiableIterator<Edge<I, E>> {
/** Input for processing the bytes */
private ExtendedDataInput extendedDataInput =
getConf().createExtendedDataInput(
serializedEdges, 0, serializedEdgesBytesUsed);
/** Representative edge object. */
private ReusableEdge<I, E> representativeEdge =
getConf().createReusableEdge();
@Override
public boolean hasNext() {
return serializedEdges != null && !extendedDataInput.endOfInput();
}
@Override
public Edge<I, E> next() {
try {
WritableUtils.readEdge(extendedDataInput, representativeEdge);
} catch (IOException e) {
throw new IllegalStateException("next: Failed on pos " +
extendedDataInput.getPos() + " edge " + representativeEdge);
}
return representativeEdge;
}
}
泪奔。。。 原来该方法为了节省边的内存空间,每次读入读出都进行了序列化操作,妹的难怪每次生成的边对象都不一样。。。 都是
representativeEdge
对象,能一样么 妹的。。。。。。。。。。。。。。。。。。。。
我的方法需要在边上增加属性,所以换成边对象更符合我需求,改为ArrayListEdges :
<property>
<name>giraph.outEdgesClass</name>
<value>org.apache.giraph.edge.ArrayListEdges</value>
</property>
问题解决。