[BACK]Return to tsort.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tsort

Diff for /src/usr.bin/tsort/tsort.c between version 1.7 and 1.8

version 1.7, 2001/04/18 17:57:28 version 1.8, 2001/04/30 21:03:55
Line 63 
Line 63 
  * heap.  The resulting complexity is O(e+v log v) for the worst case.   * heap.  The resulting complexity is O(e+v log v) for the worst case.
  * The average should actually be near O(e).   * The average should actually be near O(e).
  *   *
    * If the hints file is incomplete, there is some extra complexity incurred
    * by make_transparent, which does propagate order values to unmarked
    * nodes. In the worst case, make_transparent is  O(e u),
    * where u is the number of originally unmarked nodes.
    * In practice, it is much faster.
    *
  * The simple topological sort algorithm detects cycles.  This program   * The simple topological sort algorithm detects cycles.  This program
  * goes further, breaking cycles through the use of simple heuristics.   * goes further, breaking cycles through the use of simple heuristics.
  * Each cycle break checks the whole set of nodes, hence if c cycles break   * Each cycle break checks the whole set of nodes, hence if c cycles break
Line 127 
Line 133 
 static struct node *new_node __P((const char *, const char *));  static struct node *new_node __P((const char *, const char *));
   
 static unsigned int read_pairs __P((FILE *, struct ohash *, int,  static unsigned int read_pairs __P((FILE *, struct ohash *, int,
     const char *, unsigned int));      const char *, unsigned int, int));
 static void split_nodes __P((struct ohash *, struct array *, struct array *));  static void split_nodes __P((struct ohash *, struct array *, struct array *));
   static void make_transparent __P((struct ohash *));
 static void insert_arc __P((struct node *, struct node *));  static void insert_arc __P((struct node *, struct node *));
   
 #ifdef DEBUG  #ifdef DEBUG
Line 271 
Line 278 
   
         if (n->refs == 0)          if (n->refs == 0)
                 return;                  return;
         printf("%s (%u): ", n->k, n->refs);          printf("%s (%u/%u): ", n->k, n->order, n->refs);
         for (l = n->arcs; l != NULL; l = l->next)          for (l = n->arcs; l != NULL; l = l->next)
                 if (n->refs != 0)                  if (n->refs != 0)
                 printf("%s(%u) ", l->node->k, l->node->refs);                  printf("%s(%u/%u) ", l->node->k, l->node->order, l->node->refs);
         putchar('\n');          putchar('\n');
 }  }
   
Line 290 
Line 297 
   
 static void  static void
 dump_hash(h)  dump_hash(h)
         struct hash     *h;          struct ohash    *h;
 {  {
         unsigned int    i;          unsigned int    i;
         struct node     *n;          struct node     *n;
Line 324 
Line 331 
 }  }
   
 static unsigned int  static unsigned int
 read_pairs(f, h, reverse, name, order)  read_pairs(f, h, reverse, name, order, hint)
         FILE            *f;          FILE            *f;
         struct ohash    *h;          struct ohash    *h;
         int             reverse;          int             reverse;
         const char      *name;          const char      *name;
         unsigned int    order;          unsigned int    order;
           int             hint;
 {  {
         int             toggle;          int             toggle;
         struct node     *a;          struct node     *a;
Line 354 
Line 362 
                                 continue;                                  continue;
                         if (toggle) {                          if (toggle) {
                                 a = node_lookup(h, str, e);                                  a = node_lookup(h, str, e);
                                 if (a->order == NO_ORDER)                                  if (a->order == NO_ORDER && hint)
                                         a->order = order++;                                          a->order = order++;
                         } else {                          } else {
                                 struct node *b;                                  struct node *b;
Line 450 
Line 458 
         unsigned int    i;          unsigned int    i;
   
         for (i = h->entries; i != 0;) {          for (i = h->entries; i != 0;) {
                 if (h->t[--i]->order == 0 && verbose)                  if (h->t[--i]->order == NO_ORDER && verbose)
                         warnx("node %s absent from hints file", h->t[i]->k);                          warnx("node %s absent from hints file", h->t[i]->k);
                 heap_down(h, i);                  heap_down(h, i);
         }          }
Line 502 
Line 510 
         }          }
 }  }
   
   /* Nodes without order should not hinder direct dependencies.
    * Iterate until no nodes are left.
    */
   static void
   make_transparent(hash)
           struct ohash    *hash;
   {
           struct node     *n;
           unsigned int    i;
           struct link     *l;
           int             adjusted;
           int             bad;
           unsigned int    min;
   
           /* first try to solve complete nodes */
           do {
                   adjusted = 0;
                   bad = 0;
                   for (n = ohash_first(hash, &i); n != NULL;
                       n = ohash_next(hash, &i)) {
                           if (n->order == NO_ORDER) {
                                   min = NO_ORDER;
   
                                   for (l = n->arcs; l != NULL; l = l->next) {
                                           /* unsolved node -> delay resolution */
                                           if (l->node->order == NO_ORDER) {
                                                   bad = 1;
                                                   break;
                                           } else if (l->node->order < min)
                                                   min = l->node->order;
                                   }
                                   if (min < NO_ORDER && l == NULL) {
                                           n->order = min;
                                           adjusted = 1;
                                   }
                           }
                   }
   
           } while (adjusted);
   
           /* then, if incomplete nodes are left, do them */
           if (bad) do {
                   adjusted = 0;
                   for (n = ohash_first(hash, &i); n != NULL;
                       n = ohash_next(hash, &i))
                           if (n->order == NO_ORDER)
                                   for (l = n->arcs; l != NULL; l = l->next)
                                           if (l->node->order < n->order) {
                                                   n->order = l->node->order;
                                                   adjusted = 1;
                                           }
           } while (adjusted);
   }
   
   
 /***  /***
  *** Search through hash array for nodes.   *** Search through hash array for nodes.
Line 517 
Line 579 
   
         struct node *n;          struct node *n;
         unsigned int i;          unsigned int i;
           unsigned int total = ohash_entries(hash);
   
         heap->t = emalloc(sizeof(struct node *) * ohash_entries(hash));          heap->t = emalloc(sizeof(struct node *) * ohash_entries(hash));
         remaining->t = emalloc(sizeof(struct node *) * ohash_entries(hash));  
         heap->entries = 0;          heap->entries = 0;
         remaining->entries = 0;          remaining->entries = 0;
   
Line 527 
Line 589 
                 if (n->refs == 0)                  if (n->refs == 0)
                         heap->t[heap->entries++] = n;                          heap->t[heap->entries++] = n;
                 else                  else
                         remaining->t[remaining->entries++] = n;                          heap->t[total-1-remaining->entries++] = n;
         }          }
           remaining->t = heap->t + heap->entries;
 }  }
   
 /* Good point to break a cycle: live node with as few refs as possible. */  /* Good point to break a cycle: live node with as few refs as possible. */
Line 807 
Line 870 
                             warn_flag, hints_flag, verbose_flag;                              warn_flag, hints_flag, verbose_flag;
         unsigned int    order;          unsigned int    order;
   
         order = 1;          order = 0;
   
         reverse_flag = quiet_flag = long_flag =          reverse_flag = quiet_flag = long_flag =
                 warn_flag = hints_flag = verbose_flag = 0;                  warn_flag = hints_flag = verbose_flag = 0;
Line 829 
Line 892 
                                 optarg, order);                                  optarg, order);
                             fclose(f);                              fclose(f);
                     }                      }
                               hints_flag = 1;
                               break;
                             /*FALLTHRU*/                              /*FALLTHRU*/
                     case 'f':                      case 'f':
                             if (hints_flag == 1)                              hints_flag = 2;
                                 usage();  
                             hints_flag = 1;  
                             break;                              break;
                     case 'l':                      case 'l':
                             long_flag = 1;                              long_flag = 1;
Line 866 
Line 929 
                 f = fopen(argv[0], "r");                  f = fopen(argv[0], "r");
                 if (f == NULL)                  if (f == NULL)
                         err(EX_NOINPUT, "Can't open file %s", argv[1]);                          err(EX_NOINPUT, "Can't open file %s", argv[1]);
                 order = read_pairs(f, &pairs, reverse_flag, argv[1], order);                  order = read_pairs(f, &pairs, reverse_flag, argv[1], order,
                       hints_flag == 2);
                 fclose(f);                  fclose(f);
                 break;                  break;
         }          }
         case 0:          case 0:
                 order = read_pairs(stdin, &pairs, reverse_flag, "stdin", order);                  order = read_pairs(stdin, &pairs, reverse_flag, "stdin",
                       order, hints_flag == 2);
                 break;                  break;
         default:          default:
                 usage();                  usage();
Line 886 
Line 951 
             broken_arcs = 0;              broken_arcs = 0;
             broken_cycles = 0;              broken_cycles = 0;
   
               if (hints_flag)
                   make_transparent(&pairs);
             split_nodes(&pairs, &aux, &remaining);              split_nodes(&pairs, &aux, &remaining);
             ohash_delete(&pairs);              ohash_delete(&pairs);
   

Legend:
Removed from v.1.7  
changed lines
  Added in v.1.8