modified: nfig1.py
[GalaxyCodeBases.git] / BGI / SOAPdenovo2 / standardPregraph / dfib.c
blob64f7c5ca74e3369c1859326db39f4458630a9aed
1 /*
2 * dfib.c
4 * This file is part of SOAPdenovo.
6 */
8 /*-
9 * Copyright 1997-2003 John-Mark Gurney.
10 * All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
33 * $Id: dfib.c,v 1.12 2007/10/19 13:09:26 zerbino Exp $
36 #include <limits.h>
37 #include <stdlib.h>
39 #include "dfib.h"
40 #include "dfibpriv.h"
41 #include "extfunc2.h"
43 #define HEAPBLOCKSIZE 1000
44 static int dfh_comparedata ( DFibHeap * h, Time key, unsigned int data, DFibHeapNode * b );
45 static DFibHeapNode * allocateDFibHeapNode ( DFibHeap * heap )
47 return ( DFibHeapNode * ) getItem ( heap->nodeMemory );
50 static void deallocateDFibHeapNode ( DFibHeapNode * a, DFibHeap * heap )
52 returnItem ( heap->nodeMemory, a );
55 IDnum dfibheap_getSize ( DFibHeap * heap )
57 return heap->dfh_n;
60 #define swap(type, a, b) \
61 do { \
62 type c; \
63 c = a; \
64 a = b; \
65 b = c; \
66 } while (0) \
68 #define INT_BITS (sizeof(IDnum) * 8)
70 static inline IDnum ceillog2 ( IDnum a )
72 IDnum oa;
73 IDnum i;
74 IDnum b;
75 IDnum cons;
76 oa = a;
77 b = INT_BITS / 2;
78 i = 0;
80 while ( b )
82 i = ( i << 1 );
83 cons = ( ( IDnum ) 1 ) << b;
85 if ( a >= cons )
87 a /= cons;
88 i = i | 1;
90 else
92 a &= cons - 1;
95 b /= 2;
98 if ( ( ( ( IDnum ) 1 << i ) ) == oa )
100 return i;
102 else
104 return i + 1;
109 * Public Heap Functions
111 DFibHeap * dfh_makekeyheap ()
113 DFibHeap * n;
115 if ( ( n = malloc ( sizeof * n ) ) == NULL )
117 return NULL;
120 n->nodeMemory = createMem_manager ( HEAPBLOCKSIZE, sizeof ( DFibHeapNode ) );
121 n->dfh_n = 0;
122 n->dfh_Dl = -1;
123 n->dfh_cons = NULL;
124 n->dfh_min = NULL;
125 n->dfh_root = NULL;
126 return n;
129 void dfh_deleteheap ( DFibHeap * h )
131 fprintf ( stderr, "DFibHeap: %lld node(s) allocated.\n", h->nodeMemory->counter );
132 freeMem_manager ( h->nodeMemory );
133 h->nodeMemory = NULL;
135 if ( h->dfh_cons != NULL )
137 free ( h->dfh_cons );
140 free ( h );
144 * Public Key Heap Functions
146 DFibHeapNode * dfh_insertkey ( DFibHeap * h, Time key, unsigned int data )
148 DFibHeapNode * x;
150 if ( ( x = dfhe_newelem ( h ) ) == NULL )
152 return NULL;
155 /* just insert on root list, and make sure it's not the new min */
156 x->dfhe_data = data;
157 x->dfhe_key = key;
158 dfh_insertel ( h, x );
159 return x;
162 Time dfh_replacekey ( DFibHeap * h, DFibHeapNode * x, Time key )
164 Time ret;
165 ret = x->dfhe_key;
166 ( void ) dfh_replacekeydata ( h, x, key, x->dfhe_data );
167 return ret;
170 unsigned int minInDHeap ( DFibHeap * h )
172 if ( h->dfh_min )
174 return h->dfh_min->dfhe_data;
176 else
178 return 0;
182 boolean HasMin ( DFibHeap * h )
184 if ( h->dfh_min )
186 return 1;
188 else
190 return 0;
194 unsigned int dfh_replacekeydata ( DFibHeap * h, DFibHeapNode * x, Time key, unsigned int data )
196 unsigned int odata;
197 Time okey;
198 DFibHeapNode * y;
199 int r;
200 odata = x->dfhe_data;
201 okey = x->dfhe_key;
204 * we can increase a key by deleting and reinserting, that
205 * requires O(lgn) time.
207 if ( ( r = dfh_comparedata ( h, key, data, x ) ) > 0 )
209 /* XXX - bad code! */
210 abort ();
213 x->dfhe_data = data;
214 x->dfhe_key = key;
216 /* because they are equal, we don't have to do anything */
217 if ( r == 0 )
219 return odata;
222 y = x->dfhe_p;
224 if ( okey == key )
226 return odata;
229 if ( y != NULL && dfh_compare ( h, x, y ) <= 0 )
231 dfh_cut ( h, x, y );
232 dfh_cascading_cut ( h, y );
236 * the = is so that the call from dfh_delete will delete the proper
237 * element.
239 if ( dfh_compare ( h, x, h->dfh_min ) <= 0 )
241 h->dfh_min = x;
244 return odata;
248 * Public void * Heap Functions
251 * this will return these values:
252 * NULL failed for some reason
253 * ptr token to use for manipulation of data
255 unsigned int dfh_extractmin ( DFibHeap * h )
257 DFibHeapNode * z;
258 unsigned int ret;
259 ret = 0;
261 if ( h->dfh_min != NULL )
263 z = dfh_extractminel ( h );
264 ret = z->dfhe_data;
265 deallocateDFibHeapNode ( z, h );
268 return ret;
271 unsigned int dfh_replacedata ( DFibHeapNode * x, unsigned int data )
273 unsigned int odata = x->dfhe_data;
274 //printf("replace node value %d with %d\n",x->dfhe_data,data);
275 x->dfhe_data = data;
276 return odata;
279 unsigned int dfh_delete ( DFibHeap * h, DFibHeapNode * x )
281 unsigned int k;
282 //printf("destroy node %d in dheap\n",x->dfhe_data);
283 k = x->dfhe_data;
284 dfh_replacekey ( h, x, INT_MIN );
285 dfh_extractmin ( h );
286 return k;
290 * begin of private element fuctions
292 static DFibHeapNode * dfh_extractminel ( DFibHeap * h )
294 DFibHeapNode * ret;
295 DFibHeapNode * x, *y, *orig;
296 ret = h->dfh_min;
297 orig = NULL;
299 /* put all the children on the root list */
300 /* for true consistancy, we should use dfhe_remove */
301 for ( x = ret->dfhe_child; x != orig && x != NULL; )
303 if ( orig == NULL )
305 orig = x;
308 y = x->dfhe_right;
309 x->dfhe_p = NULL;
310 dfh_insertrootlist ( h, x );
311 x = y;
314 /* remove minimum from root list */
315 dfh_removerootlist ( h, ret );
316 h->dfh_n--;
318 /* if we aren't empty, consolidate the heap */
319 if ( h->dfh_n == 0 )
321 h->dfh_min = NULL;
323 else
325 h->dfh_min = ret->dfhe_right;
326 dfh_consolidate ( h );
329 return ret;
332 static void dfh_insertrootlist ( DFibHeap * h, DFibHeapNode * x )
334 if ( h->dfh_root == NULL )
336 h->dfh_root = x;
337 x->dfhe_left = x;
338 x->dfhe_right = x;
339 return;
342 dfhe_insertafter ( h->dfh_root, x );
345 static void dfh_removerootlist ( DFibHeap * h, DFibHeapNode * x )
347 if ( x->dfhe_left == x )
349 h->dfh_root = NULL;
351 else
353 h->dfh_root = dfhe_remove ( x );
357 static void dfh_consolidate ( DFibHeap * h )
359 DFibHeapNode ** a;
360 DFibHeapNode * w;
361 DFibHeapNode * y;
362 DFibHeapNode * x;
363 IDnum i;
364 IDnum d;
365 IDnum D;
366 dfh_checkcons ( h );
367 /* assign a the value of h->dfh_cons so I don't have to rewrite code */
368 D = h->dfh_Dl + 1;
369 a = h->dfh_cons;
371 for ( i = 0; i < D; i++ )
373 a[i] = NULL;
376 while ( ( w = h->dfh_root ) != NULL )
378 x = w;
379 dfh_removerootlist ( h, w );
380 d = x->dfhe_degree;
382 /* XXX - assert that d < D */
383 while ( a[d] != NULL )
385 y = a[d];
387 if ( dfh_compare ( h, x, y ) > 0 )
389 swap ( DFibHeapNode *, x, y );
392 dfh_heaplink ( h, y, x );
393 a[d] = NULL;
394 d++;
397 a[d] = x;
400 h->dfh_min = NULL;
402 for ( i = 0; i < D; i++ )
403 if ( a[i] != NULL )
405 dfh_insertrootlist ( h, a[i] );
407 if ( h->dfh_min == NULL || dfh_compare ( h, a[i], h->dfh_min ) < 0 )
409 h->dfh_min = a[i];
414 static void dfh_heaplink ( DFibHeap * h, DFibHeapNode * y, DFibHeapNode * x )
416 /* make y a child of x */
417 if ( x->dfhe_child == NULL )
419 x->dfhe_child = y;
421 else
423 dfhe_insertbefore ( x->dfhe_child, y );
426 y->dfhe_p = x;
427 x->dfhe_degree++;
428 y->dfhe_mark = 0;
431 static void dfh_cut ( DFibHeap * h, DFibHeapNode * x, DFibHeapNode * y )
433 dfhe_remove ( x );
434 y->dfhe_degree--;
435 dfh_insertrootlist ( h, x );
436 x->dfhe_p = NULL;
437 x->dfhe_mark = 0;
440 static void dfh_cascading_cut ( DFibHeap * h, DFibHeapNode * y )
442 DFibHeapNode * z;
444 while ( ( z = y->dfhe_p ) != NULL )
446 if ( y->dfhe_mark == 0 )
448 y->dfhe_mark = 1;
449 return;
451 else
453 dfh_cut ( h, y, z );
454 y = z;
460 * begining of handling elements of dfibheap
462 static DFibHeapNode * dfhe_newelem ( DFibHeap * h )
464 DFibHeapNode * e;
466 if ( ( e = allocateDFibHeapNode ( h ) ) == NULL )
468 return NULL;
471 e->dfhe_degree = 0;
472 e->dfhe_mark = 0;
473 e->dfhe_p = NULL;
474 e->dfhe_child = NULL;
475 e->dfhe_left = e;
476 e->dfhe_right = e;
477 e->dfhe_data = 0;
478 return e;
481 static void dfhe_insertafter ( DFibHeapNode * a, DFibHeapNode * b )
483 if ( a == a->dfhe_right )
485 a->dfhe_right = b;
486 a->dfhe_left = b;
487 b->dfhe_right = a;
488 b->dfhe_left = a;
490 else
492 b->dfhe_right = a->dfhe_right;
493 a->dfhe_right->dfhe_left = b;
494 a->dfhe_right = b;
495 b->dfhe_left = a;
499 static inline void dfhe_insertbefore ( DFibHeapNode * a, DFibHeapNode * b )
501 dfhe_insertafter ( a->dfhe_left, b );
504 static DFibHeapNode * dfhe_remove ( DFibHeapNode * x )
506 DFibHeapNode * ret;
508 if ( x == x->dfhe_left )
510 ret = NULL;
512 else
514 ret = x->dfhe_left;
517 /* fix the parent pointer */
518 if ( x->dfhe_p != NULL && x->dfhe_p->dfhe_child == x )
520 x->dfhe_p->dfhe_child = ret;
523 x->dfhe_right->dfhe_left = x->dfhe_left;
524 x->dfhe_left->dfhe_right = x->dfhe_right;
525 /* clear out hanging pointers */
526 x->dfhe_p = NULL;
527 x->dfhe_left = x;
528 x->dfhe_right = x;
529 return ret;
532 static void dfh_checkcons ( DFibHeap * h )
534 IDnum oDl;
536 /* make sure we have enough memory allocated to "reorganize" */
537 if ( h->dfh_Dl == -1 || h->dfh_n > ( 1 << h->dfh_Dl ) )
539 oDl = h->dfh_Dl;
541 if ( ( h->dfh_Dl = ceillog2 ( h->dfh_n ) + 1 ) < 8 )
543 h->dfh_Dl = 8;
546 if ( oDl != h->dfh_Dl )
547 { h->dfh_cons = ( DFibHeapNode ** ) realloc ( h->dfh_cons, sizeof * h->dfh_cons * ( h->dfh_Dl + 1 ) ); }
549 if ( h->dfh_cons == NULL )
551 abort ();
556 static int dfh_compare ( DFibHeap * h, DFibHeapNode * a, DFibHeapNode * b )
558 if ( a->dfhe_key < b->dfhe_key )
560 return -1;
563 if ( a->dfhe_key == b->dfhe_key )
565 return 0;
568 return 1;
571 static int dfh_comparedata ( DFibHeap * h, Time key, unsigned int data, DFibHeapNode * b )
573 DFibHeapNode a;
574 a.dfhe_key = key;
575 a.dfhe_data = data;
576 return dfh_compare ( h, &a, b );
579 static void dfh_insertel ( DFibHeap * h, DFibHeapNode * x )
581 dfh_insertrootlist ( h, x );
583 if ( h->dfh_min == NULL || x->dfhe_key < h->dfh_min->dfhe_key )
585 h->dfh_min = x;
588 h->dfh_n++;
591 Time dfibheap_el_getKey ( DFibHeapNode * node )
593 return node->dfhe_key;