static int proc_mq_dointvec(ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { struct ctl_table mq_table; memcpy(&mq_table, table, sizeof(mq_table)); mq_table.data = get_mq(table); return proc_dointvec(&mq_table, write, buffer, lenp, ppos); }
/* * Logger process * * Reads incoming log message from a message queue and * logs them to a file. * It takes the loglevel as a optional argument. By default * only error and info messages are logged. * * Loglevel: 1 = debug, info, error * 0 = info, error (default) */ int main(int argc, char **argv) { key_t lmq_key = ftok(FTOK_PATH, LMQ_ID); int mq_id; struct logmessage buffer; FILE* file; int debug = 0; /* * Set debug mode * (49 is the ASCII representation of 1) */ if ((argc > 1) && (argv[1][0] == 49)) { debug = 1; } /* Open logfile */ if ((file = fopen("server.log", "w")) == NULL) { perror("fopen"); exit(1); } /* Open the message queue */ mq_id = get_mq(lmq_key); fprintf(stdout, "Logger: process started and waiting for log messages\n"); /* Wait for new messages to arrive */ while(1) { /* Get a new log message */ buffer = read_mq(mq_id); /* Write log message to file */ switch(buffer.level) { case 1: /* Log error message */ fprintf(file, "[ERROR] %ld %s \n", buffer.time, buffer.message); break; case 2: /* Log info message */ fprintf(file, "[INFO] %ld %s \n", buffer.time, buffer.message); break; case 3: /* Log debug message */ if(debug) { fprintf(file, "[DEBUG] %ld %s \n", buffer.time, buffer.message); } break; } fflush(file); // Flush logfile } fclose(file); // Close logfile }
Multilevel_MQ_Clustering Multilevel_MQ_Clustering_init(SparseMatrix A, int level) { Multilevel_MQ_Clustering grid; int n = A->n, i; int *matching; assert(A->type == MATRIX_TYPE_REAL); assert(SparseMatrix_is_symmetric(A, FALSE)); if (!A) return NULL; assert(A->m == n); grid = MALLOC(sizeof(struct Multilevel_MQ_Clustering_struct)); grid->level = level; grid->n = n; grid->A = A; grid->P = NULL; grid->R = NULL; grid->next = NULL; grid->prev = NULL; grid->delete_top_level_A = FALSE; matching = grid->matching = MALLOC(sizeof(real)*(n)); grid->deg_intra = NULL; grid->dout = NULL; grid->wgt = NULL; if (level == 0) { real mq = 0, mq_in, mq_out; int n = A->n, ncluster; real *deg_intra, *wgt, *dout; grid->deg_intra = MALLOC(sizeof(real)*(n)); deg_intra = grid->deg_intra; grid->wgt = MALLOC(sizeof(real)*n); wgt = grid->wgt; for (i = 0; i < n; i++) { deg_intra[i] = 0; wgt[i] = 1.; } for (i = 0; i < n; i++) matching[i] = i; mq = get_mq(A, matching, &ncluster, &mq_in, &mq_out, &dout); fprintf(stderr,"ncluster = %d, mq = %f\n", ncluster, mq); grid->mq = mq; grid->mq_in = mq_in; grid->mq_out = mq_out; grid->dout = dout; grid->ncluster = ncluster; } return grid; }
/** * @brief Send a message to another peer. * * Keeps track about pending messages so they can be properly removed when the * peer is destroyed. * * @param peer receeiver of the message * @param ev envelope of the message * @param type type of the message */ void Peers_send_message (const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Envelope *ev, const char *type) { struct PendingMessage *pending_msg; struct GNUNET_MQ_Handle *mq; pending_msg = insert_pending_message (peer, ev, type); mq = get_mq (peer); GNUNET_MQ_notify_sent (ev, mq_notify_sent_cb, pending_msg); GNUNET_MQ_send (mq, ev); }
/** * Issue a check whether peer is live * * @param peer_ctx the context of the peer */ static void check_peer_live (struct PeerContext *peer_ctx) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Get informed about peer %s getting live\n", GNUNET_i2s (&peer_ctx->peer_id)); struct GNUNET_MQ_Handle *mq; struct GNUNET_MQ_Envelope *ev; ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_RPS_PP_CHECK_LIVE); peer_ctx->liveliness_check_pending = GNUNET_new (struct PendingMessage); peer_ctx->liveliness_check_pending->ev = ev; peer_ctx->liveliness_check_pending->peer_ctx = peer_ctx; peer_ctx->liveliness_check_pending->type = "Check liveliness"; mq = get_mq (&peer_ctx->peer_id); GNUNET_MQ_notify_sent (ev, mq_liveliness_check_successful, peer_ctx); GNUNET_MQ_send (mq, ev); }
Multilevel_MQ_Clustering Multilevel_MQ_Clustering_establish(Multilevel_MQ_Clustering grid, int maxcluster) { int *matching = grid->matching; SparseMatrix A = grid->A; int n = grid->n, level = grid->level, nc = 0, nclusters = n; real mq = 0, mq_in = 0, mq_out = 0, mq_new, mq_in_new, mq_out_new, mq_max = 0, mq_in_max = 0, mq_out_max = 0; int *ia = A->ia, *ja = A->ja; real *a, amax = 0; real *deg_intra = grid->deg_intra, *wgt = grid->wgt; real *deg_intra_new, *wgt_new = NULL; int i, j, k, jj, jc, jmax; real *deg_inter, gain = 0, *dout = grid->dout, *dout_new, deg_in_i, deg_in_j, wgt_i, wgt_j, a_ij, dout_i, dout_j, dout_max = 0, wgt_jmax = 0; int *mask; real maxgain = 0; real total_gain = 0; SingleLinkedList *neighbors = NULL, lst; neighbors = MALLOC(sizeof(SingleLinkedList)*n); for (i = 0; i < n; i++) neighbors[i] = NULL; mq = grid->mq; mq_in = grid->mq_in; mq_out = grid->mq_out; deg_intra_new = MALLOC(sizeof(real)*n); wgt_new = MALLOC(sizeof(real)*n); deg_inter = MALLOC(sizeof(real)*n); mask = MALLOC(sizeof(int)*n); dout_new = MALLOC(sizeof(real)*n); for (i = 0; i < n; i++) mask[i] = -1; assert(n == A->n); for (i = 0; i < n; i++) matching[i] = UNMATCHED; /* gain in merging node A into cluster B is mq_in_new = mq_in - |E(A,A)|/(V(A))^2 - |E(B,B)|/(V(B))^2 + (|E(A,A)|+|E(B,B)|+|E(A,B)|)/(|V(A)|+|V(B)|)^2 . = mq_in - deg_intra(A)/|A|^2 - deg_intra(B)/|B|^2 + (deg_intra(A)+deg_intra(B)+a(A,B))/(|A|+|B|)^2 mq_out_new = mq_out - |E(A,B)|/(|V(A)|*V(B)|)-\sum_{C and A connected, C!=B} |E(A,C)|/(|V(A)|*|V(C)|)-\sum_{C and B connected,C!=B} |E(B,C)|/(|V(B)|*|V(C)|) . + \sum_{C connected to A or B, C!=A, C!=B} (|E(A,C)|+|E(B,C)|)/(|V(C)|*(|V(A)|+|V(B)|) . = mq_out + a(A,B)/(|A|*|B|)-\sum_{C and A connected} a(A,C)/(|A|*|C|)-\sum_{C and B connected} a(B,C)/(|B|*|C|) . + \sum_{C connected to A or B, C!=A, C!=B} (a(A,C)+a(B,C))/(|C|*(|A|+|B|)) Denote: dout(i) = \sum_{j -- i} a(i,j)/|j| then mq_out_new = mq_out - |E(A,B)|/(|V(A)|*V(B)|)-\sum_{C and A connected, C!=B} |E(A,C)|/(|V(A)|*|V(C)|)-\sum_{C and B connected,C!=B} |E(B,C)|/(|V(B)|*|V(C)|) . + \sum_{C connected to A or B, C!=A, C!=B} (|E(A,C)|+|E(B,C)|)/(|V(C)|*(|V(A)|+|V(B)|) . = mq_out + a(A,B)/(|A|*|B|)-dout(A)/|A| - dout(B)/|B| . + (dout(A)+dout(B))/(|A|+|B|) - (a(A,B)/|A|+a(A,B)/|B|)/(|A|+|B|) . = mq_out -dout(A)/|A| - dout(B)/|B| + (dout(A)+dout(B))/(|A|+|B|) after merging A and B into cluster AB, dout(AB) = dout(A) + dout(B); dout(C) := dout(C) - a(A,C)/|A| - a(B,C)/|B| + a(A,C)/(|A|+|B|) + a(B, C)/(|A|+|B|) mq_new = mq_in_new/(k-1) - mq_out_new/((k-1)*(k-2)) gain = mq_new - mq */ a = (real*) A->a; for (i = 0; i < n; i++) { if (matching[i] != UNMATCHED) continue; /* accumulate connections between i and clusters */ for (j = ia[i]; j < ia[i+1]; j++) { jj = ja[j]; if (jj == i) continue; if ((jc=matching[jj]) != UNMATCHED) { if (mask[jc] != i) { mask[jc] = i; deg_inter[jc] = a[j]; } else { deg_inter[jc] += a[j]; } } } deg_in_i = deg_intra[i]; wgt_i = wgt[i]; dout_i = dout[i]; maxgain = 0; jmax = -1; for (j = ia[i]; j < ia[i+1]; j++) { jj = ja[j]; if (jj == i) continue; jc = matching[jj]; if (jc == UNMATCHED) { a_ij = a[j]; wgt_j = wgt[jj]; deg_in_j = deg_intra[jj]; dout_j = dout[jj]; } else if (deg_inter[jc] < 0) { continue; } else { a_ij = deg_inter[jc]; wgt_j = wgt_new[jc]; deg_inter[jc] = -1; /* so that we do not redo the calulation when we hit another neighbor in cluster jc */ deg_in_j = deg_intra_new[jc]; dout_j = dout_new[jc]; } mq_in_new = mq_in - deg_in_i/pow(wgt_i, 2) - deg_in_j/pow(wgt_j,2) + (deg_in_i + deg_in_j + a_ij)/pow(wgt_i + wgt_j,2); mq_out_new = mq_out - dout_i/wgt_i - dout_j/wgt_j + (dout_i + dout_j)/(wgt_i + wgt_j); if (nclusters > 2) { mq_new = 2*(mq_in_new/(nclusters - 1) - mq_out_new/((nclusters - 1)*(nclusters - 2))); } else { mq_new = 2*mq_in_new/(nclusters - 1); } #ifdef DEBUG { int ncluster; double mq2, mq_in2, mq_out2, *dout2; int *matching2, nc2 = nc; matching2 = MALLOC(sizeof(int)*A->m); matching2 = MEMCPY(matching2, matching, sizeof(real)*A->m); if (jc != UNMATCHED) { matching2[i] = jc; } else { matching2[i] = nc2; matching2[jj] = nc2; nc2++; } for (k = 0; k < n; k++) if (matching2[k] == UNMATCHED) matching2[k] =nc2++; mq2 = get_mq(A, matching2, &ncluster, &mq_in2, &mq_out2, &dout2); fprintf(stderr," {dout_i, dout_j}={%f,%f}, {predicted, calculated}: mq = {%f, %f}, mq_in ={%f,%f}, mq_out = {%f,%f}\n",dout_i, dout_j, mq_new, mq2, mq_in_new, mq_in2, mq_out_new, mq_out2); mq_new = mq2; } #endif gain = mq_new - mq; if (Verbose) fprintf(stderr,"gain in merging node %d with node %d = %f-%f = %f\n", i, jj, mq, mq_new, gain); if (j == ia[i] || gain > maxgain) { maxgain = gain; jmax = jj; amax = a_ij; dout_max = dout_j; wgt_jmax = wgt_j; mq_max = mq_new; mq_in_max = mq_in_new; mq_out_max = mq_out_new; } } /* now merge i and jmax */ if (maxgain > 0 || (nc >= 1 && nc > maxcluster)) { total_gain += maxgain; jc = matching[jmax]; if (jc == UNMATCHED) { fprintf(stderr, "maxgain=%f, merge %d, %d\n",maxgain, i, jmax); neighbors[nc] = SingleLinkedList_new_int(jmax); neighbors[nc] = SingleLinkedList_prepend_int(neighbors[nc], i); dout_new[nc] = dout_i + dout_max; matching[i] = matching[jmax] = nc; wgt_new[nc] = wgt[i] + wgt[jmax]; deg_intra_new[nc] = deg_intra[i] + deg_intra[jmax] + amax; nc++; } else { fprintf(stderr,"maxgain=%f, merge with existing cluster %d, %d\n",maxgain, i, jc); neighbors[jc] = SingleLinkedList_prepend_int(neighbors[jc], i); dout_new[jc] = dout_i + dout_max; wgt_new[jc] += wgt[i]; matching[i] = jc; deg_intra_new[jc] += deg_intra[i] + amax; } mq = mq_max; mq_in = mq_in_max; mq_out = mq_out_max; nclusters--; } else { fprintf(stderr,"gain: %f -- no gain, skip merging node %d\n", maxgain, i); assert(maxgain <= 0); neighbors[nc] = SingleLinkedList_new_int(i); matching[i] = nc; deg_intra_new[nc] = deg_intra[i]; wgt_new[nc] = wgt[i]; nc++; } /* update scaled outdegree of neighbors of i and its merged node/cluster jmax */ jc = matching[i]; lst = neighbors[jc]; do { mask[*((int*) SingleLinkedList_get_data(lst))] = n+i; lst = SingleLinkedList_get_next(lst); } while (lst); lst = neighbors[jc]; do { k = *((int*) SingleLinkedList_get_data(lst)); for (j = ia[k]; j < ia[k+1]; j++) { jj = ja[j]; if (mask[jj] == n+i) continue;/* link to within cluster */ if ((jc = matching[jj]) == UNMATCHED) { if (k == i) { dout[jj] += -a[j]/wgt_i + a[j]/(wgt_i + wgt_jmax); } else { dout[jj] += -a[j]/wgt_jmax + a[j]/(wgt_i + wgt_jmax); } } else { if (k == i) { dout_new[jc] += -a[j]/wgt_i + a[j]/(wgt_i + wgt_jmax); } else { dout_new[jc] += -a[j]/wgt_jmax + a[j]/(wgt_i + wgt_jmax); } } } lst = SingleLinkedList_get_next(lst); } while (lst); } fprintf(stderr,"verbose=%d\n",Verbose); if (Verbose) fprintf(stderr,"mq = %f new mq = %f level = %d, n = %d, nc = %d, gain = %g, mq_in = %f, mq_out = %f\n", mq, mq + total_gain, level, n, nc, total_gain, mq_in, mq_out); #ifdef DEBUG { int ncluster; mq = get_mq(A, matching, &ncluster, &mq_in, &mq_out, &dout); fprintf(stderr," mq = %f\n",mq); } #endif if (nc >= 1 && (total_gain > 0 || nc < n)) { /* now set up restriction and prolongation operator */ SparseMatrix P, R, R0, B, cA; real one = 1.; Multilevel_MQ_Clustering cgrid; R0 = SparseMatrix_new(nc, n, 1, MATRIX_TYPE_REAL, FORMAT_COORD); for (i = 0; i < n; i++) { jj = matching[i]; SparseMatrix_coordinate_form_add_entries(R0, 1, &jj, &i, &one); } R = SparseMatrix_from_coordinate_format(R0); SparseMatrix_delete(R0); P = SparseMatrix_transpose(R); B = SparseMatrix_multiply(R, A); if (!B) goto RETURN; cA = SparseMatrix_multiply(B, P); if (!cA) goto RETURN; SparseMatrix_delete(B); grid->P = P; grid->R = R; level++; cgrid = Multilevel_MQ_Clustering_init(cA, level); deg_intra_new = REALLOC(deg_intra_new, nc*sizeof(real)); wgt_new = REALLOC(wgt_new, nc*sizeof(real)); cgrid->deg_intra = deg_intra_new; cgrid->mq = grid->mq + total_gain; cgrid->wgt = wgt_new; dout_new = REALLOC(dout_new, nc*sizeof(real)); cgrid->dout = dout_new; cgrid = Multilevel_MQ_Clustering_establish(cgrid, maxcluster); grid->next = cgrid; cgrid->prev = grid; } else { /* no more improvement, stop and final clustering found */ for (i = 0; i < n; i++) matching[i] = i; FREE(deg_intra_new); FREE(wgt_new); FREE(dout_new); } RETURN: for (i = 0; i < n; i++) SingleLinkedList_delete(neighbors[i], free); FREE(neighbors); FREE(deg_inter); FREE(mask); return grid; }