1- #include "transaction.h"
1+ #include <stddef.h>
2+ #include <stdlib.h>
3+ #include <string.h>
4+ #include "ddd.h"
25
3- typedef struct Instance {
4- struct Edge * edges ; /* local subgraph */
5- } Instance ;
6-
7- typedef struct Edge {
8- L2List node ; /* node of list of outgoing eedges */
9- struct Edge * next ; /* list of edges of local subgraph */
10- struct Vertex * dst ;
11- struct Vertex * src ;
12- } Edge ;
13-
14- typedef struct Vertex
15- {
16- L2List outgoingEdges ;
17- xid_t xid ;
18- int nIncomingEdges ;
19- bool visited ;
20- } Vertex ;
21-
22- typedef struct Graph
23- {
24- Vertex * hashtable [MAX_TRANSACTIONS ];
25- Edge * freeEdges ;
26- Vertex * freeVertexes ;
27- } Graph ;
6+ static bool recursiveTraverseGraph (Vertex * root , Vertex * v , int marker );
287
298void initGraph (Graph * graph )
309{
31- memset (graph -> hashtable , 0. sizeof (graph -> hashtable ));
10+ memset (graph -> hashtable , 0 , sizeof (graph -> hashtable ));
3211 graph -> freeEdges = NULL ;
3312 graph -> freeVertexes = NULL ;
13+ graph -> marker = 0 ;
3414}
3515
36- Edge * newEdge (Graph * graph )
16+ static inline Edge * newEdge (Graph * graph )
3717{
3818 Edge * edge = graph -> freeEdges ;
3919 if (edge == NULL ) {
@@ -44,44 +24,51 @@ Edge* newEdge(Graph* graph)
4424 return edge ;
4525}
4626
47- void freeVertex (Graph * graph , Vertex * vertex )
27+ static inline void freeVertex (Graph * graph , Vertex * vertex )
4828{
49- vertex -> node .next = (L2List * )graph -> freeVertexes ;
29+ int h = vertex -> xid % MAX_TRANSACTIONS ;
30+ Vertex * * vpp = & graph -> hashtable [h ];
31+ while (* vpp != vertex ) {
32+ vpp = & (* vpp )-> next ;
33+ }
34+ * vpp = vertex -> next ;
35+ vertex -> next = graph -> freeVertexes ;
5036 graph -> freeVertexes = vertex ;
37+
5138}
5239
53- void freeEdge (Graph * graph , Edge * edge )
40+ static inline void freeEdge (Graph * graph , Edge * edge )
5441{
5542 edge -> next = graph -> freeEdges ;
5643 graph -> freeEdges = edge ;
5744}
5845
59- Vertex * newVertex (Graph * graph )
46+ static inline Vertex * newVertex (Graph * graph )
6047{
6148 Vertex * v = graph -> freeVertexes ;
6249 if (v == NULL ) {
6350 v = (Vertex * )malloc (sizeof (Vertex ));
6451 } else {
65- graph -> freeVertexes = ( Vertex * ) v . node . next ;
52+ graph -> freeVertexes = v -> next ;
6653 }
6754 return v ;
6855}
6956
70- Vertex * findVertex (Graph * graph , xid_t xid )
57+ static inline Vertex * findVertex (Graph * graph , xid_t xid )
7158{
72- xid_t h = xid ;
59+ xid_t h = xid % MAX_TRANSACTIONS ;
7360 Vertex * v ;
74- while (( v = graph -> hashtable [h % MAX_TRANSACTIONS ]) != NULL ) {
61+ for ( v = graph -> hashtable [h ]; v != NULL ; v = v -> next ) {
7562 if (v -> xid == xid ) {
7663 return v ;
7764 }
78- h += 1 ;
7965 }
8066 v = newVertex (graph );
81- l2_list_init (v -> outgoingEdges );
67+ l2_list_init (& v -> outgoingEdges );
8268 v -> xid = xid ;
8369 v -> nIncomingEdges = 0 ;
84- graph -> hashtable [h % MAX_TRANSACTIONS ] = v ;
70+ v -> next = graph -> hashtable [h ];
71+ graph -> hashtable [h ] = v ;
8572 return v ;
8673}
8774
@@ -107,15 +94,38 @@ void addSubgraph(Instance* instance, Graph* graph, xid_t* xids, int n_xids)
10794 next = e -> next ;
10895 l2_list_unlink (& e -> node );
10996 if (-- e -> dst -> nIncomingEdges == 0 && l2_list_is_empty (& e -> dst -> outgoingEdges )) {
110- freeVertex (e -> dst );
97+ freeVertex (graph , e -> dst );
11198 }
11299 if (e -> src -> nIncomingEdges == 0 && l2_list_is_empty (& e -> src -> outgoingEdges )) {
113- freeVertex (e -> src );
100+ freeVertex (graph , e -> src );
114101 }
115- freeEdge (e );
102+ freeEdge (graph , e );
116103 }
117104}
118105
119- bool findLoop ( Graph * graph )
106+ static bool recursiveTraverseGraph ( Vertex * root , Vertex * v , int marker )
120107{
108+ L2List * l ;
109+ Edge * e ;
110+ v -> visited = marker ;
111+ for (l = v -> outgoingEdges .next ; l != & v -> outgoingEdges ; l = e -> node .next ) {
112+ e = (Edge * )l ;
113+ if (e -> dst == root ) {
114+ return true;
115+ } else if (e -> dst -> visited != marker && recursiveTraverseGraph (root , e -> dst , marker )) { /* loop */
116+ return true;
117+ }
118+ }
119+ return false;
120+ }
121+
122+ bool findLoop (Graph * graph , xid_t root )
123+ {
124+ Vertex * v ;
125+ for (v = graph -> hashtable [root % MAX_TRANSACTIONS ]; v != NULL ; v = v -> next ) {
126+ if (v -> xid == root ) {
127+ return recursiveTraverseGraph (v , v , ++ graph -> marker );
128+ }
129+ }
130+ return false;
121131}
0 commit comments