|
Graphviz 2.29.20120208.0545
|
00001 /* $Id$ $Revision$ */ 00002 /* vim:set shiftwidth=4 ts=8: */ 00003 00004 /************************************************************************* 00005 * Copyright (c) 2011 AT&T Intellectual Property 00006 * All rights reserved. This program and the accompanying materials 00007 * are made available under the terms of the Eclipse Public License v1.0 00008 * which accompanies this distribution, and is available at 00009 * http://www.eclipse.org/legal/epl-v10.html 00010 * 00011 * Contributors: See CVS logs. Details at http://www.graphviz.org/ 00012 *************************************************************************/ 00013 00014 00015 #include <deglist.h> 00016 #include <circular.h> 00017 #include <blockpath.h> 00018 #include <assert.h> 00019 00020 typedef struct { 00021 Dtlink_t link; 00022 int deg; 00023 Agnode_t *np; /* linked list of nodes of same degree */ 00024 } degitem; 00025 00026 static degitem *mkItem(Dt_t * d, degitem * obj, Dtdisc_t * disc) 00027 { 00028 degitem *ap = GNEW(degitem); 00029 00030 ap->np = NULL; 00031 ap->deg = obj->deg; 00032 return ap; 00033 } 00034 00035 static void freeItem(Dt_t * d, degitem * obj, Dtdisc_t * disc) 00036 { 00037 free(obj); 00038 } 00039 00040 static int cmpDegree(Dt_t * d, int *key1, int *key2, Dtdisc_t * disc) 00041 { 00042 if (*key1 < *key2) 00043 return -1; 00044 else if (*key1 > *key2) 00045 return 1; 00046 else 00047 return 0; 00048 } 00049 00050 static Dtdisc_t nodeDisc = { 00051 offsetof(degitem, deg), /* key */ 00052 sizeof(int), /* size */ 00053 offsetof(degitem, link), /* link */ 00054 (Dtmake_f) mkItem, 00055 (Dtfree_f) freeItem, 00056 (Dtcompar_f) cmpDegree, 00057 (Dthash_f) 0, 00058 (Dtmemory_f) 0, 00059 (Dtevent_f) 0 00060 }; 00061 00062 /* mkDeglist: 00063 * Create an empty list of nodes. 00064 */ 00065 deglist_t *mkDeglist(void) 00066 { 00067 deglist_t *s = dtopen(&nodeDisc, Dtoset); 00068 return s; 00069 } 00070 00071 /* freeDeglist: 00072 * Delete the node list. 00073 * Nodes are not deleted. 00074 */ 00075 void freeDeglist(deglist_t * s) 00076 { 00077 dtclose(s); 00078 } 00079 00080 /* insertDeglist: 00081 * Add a node to the node list. 00082 * Nodes are kept sorted by DEGREE, smallest degrees first. 00083 */ 00084 void insertDeglist(deglist_t * ns, Agnode_t * n) 00085 { 00086 degitem key; 00087 degitem *kp; 00088 00089 key.deg = DEGREE(n); 00090 kp = dtinsert(ns, &key); 00091 ND_next(n) = kp->np; 00092 kp->np = n; 00093 } 00094 00095 /* removeDeglist: 00096 * Remove n from list, if it is in the list. 00097 */ 00098 void removeDeglist(deglist_t * list, Agnode_t * n) 00099 { 00100 degitem key; 00101 degitem *ip; 00102 Agnode_t *np; 00103 Agnode_t *prev; 00104 00105 key.deg = DEGREE(n); 00106 ip = (degitem *) dtsearch(list, &key); 00107 assert(ip); 00108 if (ip->np == n) { 00109 ip->np = ND_next(n); 00110 if (ip->np == NULL) 00111 dtdelete(list, ip); 00112 } else { 00113 prev = ip->np; 00114 np = ND_next(prev); 00115 while (np && (np != n)) { 00116 prev = np; 00117 np = ND_next(np); 00118 } 00119 if (np) 00120 ND_next(prev) = ND_next(np); 00121 } 00122 } 00123 00124 /* firstDeglist: 00125 * Return the first node in the list (smallest degree) 00126 * Remove from list. 00127 * If the list is empty, return NULL 00128 */ 00129 Agnode_t *firstDeglist(deglist_t * list) 00130 { 00131 degitem *ip; 00132 Agnode_t *np; 00133 00134 ip = (degitem *) dtfirst(list); 00135 if (ip) { 00136 np = ip->np; 00137 ip->np = ND_next(np); 00138 if (ip->np == NULL) 00139 dtdelete(list, ip); 00140 return np; 00141 } else 00142 return 0; 00143 } 00144 00145 #ifdef DEBUG 00146 void printDeglist(deglist_t * dl) 00147 { 00148 degitem *ip; 00149 node_t *np; 00150 fprintf(stderr, " dl:\n"); 00151 for (ip = (degitem *) dtfirst(dl); ip; ip = (degitem *) dtnext(dl, ip)) { 00152 np = ip->np; 00153 if (np) 00154 fprintf(stderr, " (%d)", ip->deg); 00155 for (; np; np = ND_next(np)) { 00156 fprintf(stderr, " %s", np->name); 00157 } 00158 fprintf(stderr, "\n"); 00159 } 00160 00161 } 00162 #endif
1.7.4