/**
   * Grab pivot's adjacency list into memory.
   */
 int grab_adj(graphchi_vertex<uint32_t, uint32_t> &v) {
     if(is_pivot(v.id())) {            
         int ncount = v.num_edges();
         // Count how many neighbors have larger id than v
         v.sort_edges_indirect();
  
         
         int actcount = 0;
         vid_t lastvid = 0;
         for(int i=0; i<ncount; i++) {
             if (v.edge(i)->vertexid > v.id() && v.edge(i)->vertexid != lastvid)  
                 actcount++;  // Need to store only ids larger than me
             lastvid = v.edge(i)->vertex_id();
         }
         
         // Allocate the in-memory adjacency list, using the
         // knowledge of the number of edges.
         dense_adj dadj = dense_adj(actcount, (vid_t*) calloc(sizeof(vid_t), actcount));
         actcount = 0;
         lastvid = 0;
         for(int i=0; i<ncount; i++) {
             if (v.edge(i)->vertexid > v.id() && v.edge(i)->vertexid != lastvid) {  // Need to store only ids larger than me
                 dadj.adjlist[actcount++] = v.edge(i)->vertex_id();
             }
             lastvid = v.edge(i)->vertex_id();
         }
         assert(dadj.count == actcount);
         adjs[v.id() - pivot_st] = dadj;
         assert(v.id() - pivot_st < adjs.size());
         __sync_add_and_fetch(&grabbed_edges, actcount);
         return actcount;
     }
     return 0;
 }
    /**
     *  Vertex update function.
     */
    void update(graphchi_vertex<VertexDataType, EdgeDataType> &v, graphchi_context &gcontext) {
        
        if (gcontext.iteration % 2 == 0) {
            adjcontainer->grab_adj(v);
        } else {
            uint32_t oldcount = v.get_data();
            uint32_t newcounts = 0;

            v.sort_edges_indirect();
            
            vid_t lastvid = 0;
            
            /**
              * Iterate through the edges, and if an edge is from a 
              * pivot vertex, compute intersection of the relevant
              * adjacency lists.
              */
            for(int i=0; i<v.num_edges(); i++) {
                graphchi_edge<uint32_t> * e = v.edge(i);
                if (e->vertexid > v.id() && e->vertexid >= adjcontainer->pivot_st) {
                    assert(!is_deleted_edge_value(e->get_data()));
                    if (e->vertexid != lastvid) {  // Handles reciprocal edges (a->b, b<-a)
                        if (adjcontainer->is_pivot(e->vertexid)) {
                            uint32_t pivot_triangle_count = adjcontainer->intersection_size(v, e->vertexid, i);
                            newcounts += pivot_triangle_count;
                            
                            /* Write the number of triangles into edge between this vertex and pivot */
                            if (pivot_triangle_count == 0 && e->get_data() == 0) {
                                /* ... or remove the edge, if the count is zero. */
                                v.remove_edge(i); 
                            } else {
                                
                                e->set_data(e->get_data() + pivot_triangle_count);
                            }
                        } else {
                            break;
                        }
                    }
                    lastvid = e->vertexid;
                }  
                assert(newcounts >= 0);
            }
            
            if (newcounts > 0) {
                v.set_data(oldcount + newcounts);
            }
        }
        
        
        /* Collect triangle counts matched by vertices with id lower than
            his one, and delete */
        if (gcontext.iteration % 2 == 0) {
            int newcounts = 0;
          
            for(int i=0; i < v.num_edges(); i++) {
                graphchi_edge<uint32_t> * e = v.edge(i);
                if (e->vertexid < v.id()) {
                    newcounts += e->get_data();
                    e->set_data(0);
                    
                    // This edge can be now deleted. Is there some other situations we can delete?
                    if (v.id() < adjcontainer->pivot_st && e->vertexid < adjcontainer->pivot_st) {
                        v.remove_edge(i);
                    }
                }
            }
            v.set_data(v.get_data() + newcounts);
        }
        
     }