Skip to content

Commit 3492d3d

Browse files
committed
Add Bron–Kerbosch algorithm to find maximum clique in graph
1 parent 0f74000 commit 3492d3d

File tree

9 files changed

+166
-89
lines changed

9 files changed

+166
-89
lines changed

contrib/mmts/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
MODULE_big = multimaster
2-
OBJS = multimaster.o arbiter.o bytebuf.o bgwpool.o pglogical_output.o pglogical_proto.o pglogical_receiver.o pglogical_apply.o pglogical_hooks.o pglogical_config.o
2+
OBJS = multimaster.o arbiter.o bytebuf.o bgwpool.o pglogical_output.o pglogical_proto.o pglogical_receiver.o pglogical_apply.o pglogical_hooks.o pglogical_config.o ddd.o bkb.o
33

44
EXTENSION = multimaster
55
DATA = multimaster--1.0.sql

contrib/mmts/arbiter.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ typedef struct
8181
MtmMessageCode code; /* Message code: MSG_READY, MSG_PREPARE, MSG_COMMIT, MSG_ABORT */
8282
int node; /* Sender node ID */
8383
TransactionId dxid; /* Transaction ID at destination node */
84-
TransactionId sxid; /* Transaction IO at sender node */
84+
TransactionId sxid; /* Transaction ID at sender node */
8585
csn_t csn; /* local CSN in case of sending data from replica to master, global CSN master->replica */
8686
nodemask_t disabledNodeMask; /* bitmask of disabled nodes at the sender of message */
8787
} MtmArbiterMessage;
@@ -353,9 +353,11 @@ static void MtmOpenConnections()
353353

354354
static bool MtmSendToNode(int node, void const* buf, int size)
355355
{
356-
while (!MtmWriteSocket(sockets[node], buf, size)) {
356+
while (sockets[node] < 0 || !MtmWriteSocket(sockets[node], buf, size)) {
357357
elog(WARNING, "Arbiter failed to write socket: %d", errno);
358-
close(sockets[node]);
358+
if (sockets[node] >= 0) {
359+
close(sockets[node]);
360+
}
359361
sockets[node] = MtmConnectSocket(hosts[node], MtmArbiterPort + node + 1, MtmReconnectAttempts);
360362
if (sockets[node] < 0) {
361363
MtmOnLostConnection(node+1);
@@ -400,6 +402,8 @@ static void MtmAcceptOneConnection()
400402
close(fd);
401403
} else {
402404
elog(NOTICE, "Arbiter established connection with node %d", msg.node);
405+
BIT_CLEAR(ds->connectivityMask, msg.node-1);
406+
MtmOnConnectNode(msg.node);
403407
MtmRegisterSocket(fd, msg.node-1);
404408
sockets[msg.node-1] = fd;
405409
}

contrib/mmts/bkb.c

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
1+
#include "postgres.h"
2+
#include "bkb.h"
3+
14
/*
2-
* Bron–Kerbosch algorithm to find maximum clque in graph
5+
* Bron–Kerbosch algorithm to find maximum clique in graph
36
*/
47

58
typedef struct {
69
int size;
710
int nodes[MAX_NODES];
8-
} List;
11+
} NodeList;
912

10-
static void list_append(List* list, int n)
13+
static void list_append(NodeList* list, int n)
1114
{
12-
nodes[list->size++] = n;
15+
Assert(list->size < MAX_NODES);
16+
list->nodes[list->size++] = n;
1317
}
1418

15-
static void list_copy(List* dst, List* src)
19+
static void list_copy(NodeList* dst, NodeList const* src)
1620
{
1721
int i;
1822
int n = src->size;
@@ -23,13 +27,15 @@ static void list_copy(List* dst, List* src)
2327
}
2428

2529

26-
static void findMaximumIndependentSet(List* cur, List* result, nodemask_t* graph, int* oldSet, int ne, int ce)
30+
static void findMaximumIndependentSet(NodeList* cur, NodeList* result, nodemask_t* graph, int* oldSet, int ne, int ce)
2731
{
2832
int nod = 0;
2933
int minnod = ce;
3034
int fixp = -1;
3135
int s = -1;
32-
int i, j;
36+
int i, j, k;
37+
int newce, newne;
38+
int sel;
3339
int newSet[MAX_NODES];
3440

3541
for (i = 0; i < ce && minnod != 0; i++) {
@@ -39,8 +45,9 @@ static void findMaximumIndependentSet(List* cur, List* result, nodemask_t* graph
3945

4046
for (j = ne; j < ce; j++) {
4147
if (!BIT_CHECK(graph[p], oldSet[j])) {
42-
if (++cnt == minnod)
48+
if (++cnt == minnod) {
4349
break;
50+
}
4451
pos = j;
4552
}
4653
}
@@ -57,19 +64,19 @@ static void findMaximumIndependentSet(List* cur, List* result, nodemask_t* graph
5764
}
5865

5966

60-
for (int k = minnod + nod; k >= 1; k--) {
61-
int sel = oldSet[s];
67+
for (k = minnod + nod; k >= 1; k--) {
68+
sel = oldSet[s];
6269
oldSet[s] = oldSet[ne];
6370
oldSet[ne] = sel;
6471

65-
int newne = 0;
66-
for (int i = 0; i < ne; i++) {
72+
newne = 0;
73+
for (i = 0; i < ne; i++) {
6774
if (BIT_CHECK(graph[sel], oldSet[i])) {
6875
newSet[newne++] = oldSet[i];
6976
}
7077
}
71-
int newce = newne;
72-
for (int i = ne + 1; i < ce; i++) {
78+
newce = newne;
79+
for (i = ne + 1; i < ce; i++) {
7380
if (BIT_CHECK(graph[sel], oldSet[i])) {
7481
newSet[newce++] = oldSet[i];
7582
}
@@ -84,28 +91,30 @@ static void findMaximumIndependentSet(List* cur, List* result, nodemask_t* graph
8491
findMaximumIndependentSet(cur, result, graph, newSet, newne, newce);
8592
}
8693
}
87-
cur.size -= 1;
94+
cur->size -= 1;
8895
if (k > 1) {
8996
for (s = ++ne; BIT_CHECK(graph[fixp], oldSet[s]); s++);
9097
}
9198
}
9299
}
93100

94-
nodemask_t MtmFindMaxClique(nodemask_t* graphs, in n_nodes);
101+
nodemask_t MtmFindMaxClique(nodemask_t* graph, int n_nodes)
95102
{
96-
List tmp;
97-
List result;
98-
nodemask_t mask = 0;
103+
NodeList tmp;
104+
NodeList result;
105+
nodemask_t mask;
99106
int all[MAX_NODES];
100107
int i;
108+
101109
tmp.size = 0;
102110
result.size = 0;
103111
for (i = 0; i < n_nodes; i++) {
104-
all[i]= i;
112+
all[i] = i;
105113
}
106114
findMaximumIndependentSet(&tmp, &result, graph, all, 0, n_nodes);
115+
mask = 0;
107116
for (i = 0; i < result.size; i++) {
108117
mask |= (nodemask_t)1 << result.nodes[i];
109118
}
110-
return ~mask;
119+
return mask;
111120
}

contrib/mmts/bkb.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
* Bron–Kerbosch algorithm to find maximum clique in graph
3+
*/
4+
#ifndef __BKB_H__
5+
#define __BKB_H__
6+
7+
#define MAX_NODES 64
8+
9+
typedef uint64_t nodemask_t;
10+
#define BIT_CHECK(mask, bit) (((mask) & ((nodemask_t)1 << (bit))) != 0)
11+
#define BIT_CLEAR(mask, bit) (mask &= ~((nodemask_t)1 << (bit)))
12+
#define BIT_SET(mask, bit) (mask |= ((nodemask_t)1 << (bit)))
13+
14+
extern nodemask_t MtmFindMaxClique(nodemask_t* matrix, int n_modes);
15+
16+
#endif

contrib/mmts/ddd.c

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
#include <stddef.h>
2-
#include <stdlib.h>
3-
#include <string.h>
1+
#include "postgres.h"
2+
#include "access/clog.h"
3+
#include "storage/lwlock.h"
4+
#include "utils/hsearch.h"
5+
46
#include "ddd.h"
57

68

@@ -11,10 +13,10 @@ void MtmGraphInit(MtmGraph* graph)
1113

1214
static inline MtmVertex* findVertex(MtmGraph* graph, GlobalTransactionId* gtid)
1315
{
14-
xid_t h = gtid->xid % MAX_TRANSACTIONS;
16+
uint32 h = gtid->xid % MAX_TRANSACTIONS;
1517
MtmVertex* v;
16-
for (v = graph->hashtable[h]; v != NULL; v = v->next) {
17-
if (v->gtid == *gtid) {
18+
for (v = graph->hashtable[h]; v != NULL; v = v->collision) {
19+
if (EQUAL_GTID(v->gtid, *gtid)) {
1820
return v;
1921
}
2022
}
@@ -29,30 +31,28 @@ static inline MtmVertex* findVertex(MtmGraph* graph, GlobalTransactionId* gtid)
2931
void MtmGraphAdd(MtmGraph* graph, GlobalTransactionId* gtid, int size)
3032
{
3133
GlobalTransactionId* last = gtid + size;
32-
MtmEdge *e, *next, *edges = NULL;
3334
while (gtid != last) {
34-
Vertex* src = findVertex(graph, gtid++);
35+
MtmVertex* src = findVertex(graph, gtid++);
3536
while (gtid->node != 0) {
36-
Vertex* dst = findVertex(graph, gtid++);
37-
e = (MtmEdge*)palloc(sizeof(MtmEdge));
38-
dst->nIncomingEdges += 1;
37+
MtmVertex* dst = findVertex(graph, gtid++);
38+
MtmEdge* e = (MtmEdge*)palloc(sizeof(MtmEdge));
3939
e->dst = dst;
4040
e->src = src;
41-
e->next = v->outgoingEdges;
42-
v->outgoingEdges = e;
41+
e->next = src->outgoingEdges;
42+
src->outgoingEdges = e;
4343
}
4444
gtid += 1;
4545
}
4646
}
4747

4848
static bool recursiveTraverseGraph(MtmVertex* root, MtmVertex* v)
4949
{
50-
Edge* e;
51-
v->node = VISITED_NODE_MARK;
50+
MtmEdge* e;
51+
v->gtid.node = VISITED_NODE_MARK;
5252
for (e = v->outgoingEdges; e != NULL; e = e->next) {
5353
if (e->dst == root) {
5454
return true;
55-
} else if (e->dst->node != VISITED_NODE_MAR && recursiveTraverseGraph(root, e->dst)) { /* loop */
55+
} else if (e->dst->gtid.node != VISITED_NODE_MARK && recursiveTraverseGraph(root, e->dst)) { /* loop */
5656
return true;
5757
}
5858
}
@@ -61,9 +61,9 @@ static bool recursiveTraverseGraph(MtmVertex* root, MtmVertex* v)
6161

6262
bool MtmGraphFindLoop(MtmGraph* graph, GlobalTransactionId* root)
6363
{
64-
Vertex* v;
65-
for (v = graph->hashtable[root->xid % MAX_TRANSACTIONS]; v != NULL; v = v->next) {
66-
if (v->gtid == *root) {
64+
MtmVertex* v;
65+
for (v = graph->hashtable[root->xid % MAX_TRANSACTIONS]; v != NULL; v = v->collision) {
66+
if (EQUAL_GTID(v->gtid, *root)) {
6767
if (recursiveTraverseGraph(v, v)) {
6868
return true;
6969
}

contrib/mmts/ddd.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#ifndef __DDD_H__
2+
#define __DDD_H__
23

34
#include "multimaster.h"
45

@@ -20,8 +21,8 @@ typedef struct MtmVertex
2021

2122
typedef struct MtmGraph
2223
{
23-
MtmVertex* hashtable[MTM_MAX_TRANSACTIONS];
24-
} Graph;
24+
MtmVertex* hashtable[MAX_TRANSACTIONS];
25+
} MtmGraph;
2526

2627
extern void MtmGraphInit(MtmGraph* graph);
2728
extern void MtmGraphAdd(MtmGraph* graph, GlobalTransactionId* subgraph, int size);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy