-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcc_index.cpp
180 lines (165 loc) · 4.42 KB
/
cc_index.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <cstring>
#include "cc_index.h"
#include "buffer.h"
#include "node_index.h"
#include "other_functions.h"
#include "graph.h"
#include <stdint.h>
using namespace std;
CC_Index::CC_Index(uint32_t n)
{
cc=(uint32_t*)calloc(n,sizeof(uint32_t));
update=NULL;
size=n;
num_of_cc=0;
use_update=0;
}
CC_Index::~CC_Index()
{
free(cc);
uint32_t i;
for(i=0;i<(num_of_cc+1);i++)
{
if(update[i]!=NULL)
delete update[i];
}
free(update);
}
uint32_t CC_Index::get_cc(uint32_t i)
{
if(i>=size) //node id is larger than size
return 0;
return cc[i];
}
void CC_Index::set_cc(uint32_t i,uint32_t count)
{
if(i>=size) //node id is larger than size
double_size(i);
cc[i]=count;
}
uint32_t CC_Index::get_size()
{
return size;
}
void CC_Index::double_size(uint32_t i)
{
int new_megethos=2;
while(i>=new_megethos*size) //calculate until node id can fit in cc
{
new_megethos=new_megethos*2;
}
cc=(uint32_t *)realloc(cc,new_megethos*size*(sizeof(uint32_t)));
memset(cc+size,0,(new_megethos*size-size)*sizeof(uint32_t)); //set the newly alloced memory to 0
size=new_megethos*size;
}
void CC_Index::cc_create(Graph* G,int* marked_out,int * marked_in)
{
uint32_t cc_num=0;
uint32_t *check=(uint32_t*)malloc(sizeof(uint32_t)); //used for marking
*check=-1;
uint32_t node=0;
uint32_t size=this->get_size();
while(node<size) //find the nodes belong to a cc with a bfs search
{
if(this->get_cc(node)==0&& ((G->get_table_out())->exists_node(node)==0||(G->get_table_in())->exists_node(node)==0)) //if the node doesn't belong yet to any cc ,have a bfs search to make the next cc
{
cc_num++;
bfs(node,G,marked_out,marked_in,this,cc_num,*check);
}
(*check)=(*check)-1;
node++;
}
this->num_of_cc=cc_num;
free(check);
}
void CC_Index::create_update_index()
{
update=(Node_upd **)calloc(num_of_cc+1,sizeof(Node_upd*));
}
void CC_Index::update_cc_indexes(uint32_t node1,uint32_t node2)
{
uint32_t cc_node1,cc_node2;
cc_node1=this->get_cc(node1);
cc_node2=this->get_cc(node2);
if(cc_node1==0&&cc_node2!=0) //if cc_node1 is now inserted in the graph,it belongs to cc_node2's cc
{
this->set_cc(node1,cc_node2);
}
else if(cc_node2==0&&cc_node1!=0) //if cc_node2 is now inserted in the graph,it belongs to cc_node1's cc
{
this->set_cc(node2,cc_node1);
}
else if(cc_node1==0&&cc_node2==0) //practicly this case is ureachable but needed for checking
{
cerr<<"unreachable case\n";
return;
}
else if(cc_node1==cc_node2) //no need for changes
{
return;
}
else //if node1,belongs to different cc from node2
{
if(update[cc_node1]==NULL) //node1's cc hasn't any merges yet
update[cc_node1]= new Node_upd();
update[cc_node1]->add_update(cc_node2);
if(update[cc_node2]==NULL) //node2's cc hasn't any merges yet
update[cc_node2]= new Node_upd();
update[cc_node2]->add_update(cc_node1);
}
}
int CC_Index::exists_path(uint32_t node1,uint32_t node2)
{
uint32_t cc_node1,cc_node2;
cc_node1=get_cc(node1);
cc_node2=get_cc(node2);
if(cc_node1>num_of_cc || cc_node2>num_of_cc ) //practicly this case is ureachable but needed for checking
{
return 0;
}
if(cc_node1==0 || cc_node2==0) //node doesn't exist
{
return 0;
}
else if(cc_node1==cc_node2 && cc_node2!=0) //they belong to the same cc
{
return 1;
}
else if(cc_node1!=cc_node2) //they do not belong to the same cc
{
if((update[cc_node1]!=NULL) && (update[cc_node2]!=NULL) && update[cc_node1]->get_next_available()<update[cc_node2]->get_next_available()) //node1's cc has less updates,check firts node1;s updates
{
if((update[cc_node1]!=NULL)&&(update[cc_node1]->exists(cc_node2)==1)) //node1'cc,node2's cc are merged
{
this->use_update++; //update the metric of using updateindex properly
return 2;
}
else if((update[cc_node2]!=NULL)&&(update[cc_node2]->exists(cc_node1)==1))
{
this->use_update++; //update the metric of using updateindex properly
return 2;
}
else
return 0;
}
else //node2's cc has less updates(or equal),check first node2's updates
{
if((update[cc_node2]!=NULL)&&(update[cc_node2]->exists(cc_node1)==1))
{
this->use_update++; //update the metric of using updateindex properly
return 2;
}
else if((update[cc_node1]!=NULL)&&(update[cc_node1]->exists(cc_node2)==1))
{
this->use_update++; //update the metric of using updateindex properly
return 2;
}
else
return 0;
}
}
return 0;
}