zoukankan      html  css  js  c++  java
  • Giraph源代码分析(六)——Edge 分析

    HamaWhite 原创,转载请注明出处。欢迎大家增加Giraph 技术交流群: 228591158

    欢迎訪问: 西北工业大学 - 大数据与知识管理研究室 (Northwestern Polytechnical University - BigData and Knowledge Management Lab),链接:http://wowbigdata.cn/http://wowbigdata.net.cn/http://wowbigdata.com.cn

    1. 在Vertex类中,顶点的存储方式採用邻接表形式。每一个顶点有 VertexId、VertexValue、OutgoingEdges和Halt,boolean型的halt变量用于记录顶点的状态,false时表示active,true表示inactive状态。 片段代码例如以下:

    /** Vertex id. */
      private I id;
      /** Vertex value. */
      private V value;
      /** Outgoing edges. */
      private OutEdges<I, E> edges;
      /** If true, do not do anymore computation on this vertex. */
      private boolean halt;
      /** Global graph state **/
      private GraphState<I, V, E, M> graphState;

    2 org.apache.giraph.edge.Edge 接口,用于存储顶点的边。每条边包括targetVertexId和edgeValue两个属性。 类关系图例如以下:


         Giraph默认使用DefaultEdge类存储边,该类中有两个变量: I targetVertexId和 E value。I为顶点ID的类型。E为边的类型。注意。DefaultEdge类同一时候继承ReusableEdge<I,E>接口。在ReusableEdge<I,E>类的定义中,有例如以下说明文字:

    A complete edge, the target vertex and the edge value. Can only be one edge with a destination vertex id per edge map. This edge can be reused, that is you can set it's target vertex ID and edge value. Note: this class is useful for certain optimizations, but it's not meant to be exposed to the user. Look at MutableEdge instead.

        从上述说明文字可知,edge能够被重用,仅仅须要改动targetVertexId和value的值即可。即每一个Vertex若有多条出边。仅仅会创建一个DefaultEdge对象来存储边

    3. org.apache.giraph.edge.OutEdges<I,E> 用于存储每一个顶点的out-edges。从Vertex类的定义可知,顶点的每条边都被存储在OutEdges<I,E>类型的edge对象中。OutEdges<I,E>接口的关系图例如以下:

        Giraph默认的使用ByteArrayEdges<I,E>,每一个顶点的全部边都被存储在byte[ ]中。当顶点向它的出边发送消息时,须要遍历Vertex类中的edges对象。

    演示样例代码例如以下:

    //遍历全部的边。getEdges()返回的是Vertex中的edges对象,
    //那么该for循环会调用edges对象的iterator()方法,即调用ByteArrayEdges类中的iterator方法。
    for (Edge<LongWritable, FloatWritable> edge : getEdges()) {
    	//edge对象表示每条边。默觉得DefaultEdge类型。

    double distance = minDist + edge.getValue().get(); sendMessage(edge.getTargetVertexId(), new DoubleWritable(distance)); }

    注意:由DefaultEdge的定义可知,遍历getEdges时,返回的Edge对象时同一个对象。仅仅是该对象中值改变了

    以下继续查看代码来证明此观点。

    查看ByteArrayEdges类的iterator()方法,例如以下。

     @Override
      public Iterator<Edge<I, E>> iterator() {
        return new ByteArrayEdgeIterator();
      }

    返回的是内部类ByteArrayEdgeIterator对象。定义例如以下:

     /**
       * Iterator that reuses the same Edge object.
       */
      private class ByteArrayEdgeIterator
          extends UnmodifiableIterator<Edge<I, E>> {
    	 //extendedDataInput存储全部Edge边相应的字节
        /** Input for processing the bytes */
        private ExtendedDataInput extendedDataInput =
            getConf().createExtendedDataInput(
                serializedEdges, 0, serializedEdgesBytesUsed);
    	//创建一个Edge对象,默认返回的是DefaultEdge对象。

    /** Representative edge object. */ private ReusableEdge<I, E> representativeEdge = getConf().createReusableEdge(); @Override public boolean hasNext() { return serializedEdges != null && extendedDataInput.available() > 0; } @Override public Edge<I, E> next() { try { //核心:此处遍历每条Edge时,都是从extendedDataInput读入每天边的数据存储在representativeEdge对象中。 //从此处就可知,每一个顶点的全部出边仅仅有一个Edge对象, 遍历时改动每条边的数据的就可以 WritableUtils.readEdge(extendedDataInput, representativeEdge); } catch (IOException e) { throw new IllegalStateException("next: Failed on pos " + extendedDataInput.getPos() + " edge " + representativeEdge); } return representativeEdg } }

    总结:当顶点的出度非常大时,此优化甚好,能非常好的节约内存。如UK-2005数据中,顶点的最大出度为 5213。

    如果顶点1的出度顶点有<2 , 0.4>。<3 , 7.8> ,<5 , 6.4> 。

    例如以下代码:

    //定义list列表用于存储出度顶点的Id。
    List<LongWritable> list=new ArrayList<LongWritable>();
    for (Edge<LongWritable, FloatWritable> edge : getEdges()) {
    	list.add(edge.getTargetVertexId());
    	System.out.println(list);
    }

    输出结果为:

    [ 2 ]

    [ 3 ,  3 ]

    [ 5 , 5 , 5 ]

    并不是是希望的 [ 2 , 3 , 5 ]

    完。

    本人原创,转载请注明出处!

     本人QQ:530422429。欢迎大家指正、讨论。

  • 相关阅读:
    silverlight 视频
    Win7/Vista下安装SQL Server 2005/2008后,进行附加数据库错误的解决
    IIS篇
    ARCGIS 定位篇
    sqlserver 2008 修改表结构不能保存
    更新silverlight 后 无法启动调试 未安装silverlight developer 运行时解决办法
    2点经纬度计算相对方位
    VS2010中文旗舰版在WIN7 64位操作系统下安装
    self = [super init]
    NSXMLParser XML 解析 解压
  • 原文地址:https://www.cnblogs.com/llguanli/p/8280147.html
Copyright © 2011-2022 走看看