Pour comprendre cette implantation de l'algorithme CbO (ou son dual), voici ma visite commentée du code.
 : Attention, ce n'est pas encore finie.
 : Attention, ce n'est pas encore finie.
Dans ce qui suit, les multiples contrôles ne seront pas mentionnés, seulement le “traitement pur.”
Ici, on recense le nombre d'objets ayant chaque attribut (supps, de dimension LONGSIZE * 8 * int_count_a)
for (i = ARCHBIT; i >= 0; i–) {
    mask = (BIT << i);
    cols[j][i] = ptr;
    supps[j][i] = 0;
    for (x = 0, y = j; x < objects; x++, y += int_count_a)
if (context[y] & mask) {
  ptr[x / (ARCHBIT + 1)] |= BIT << (x % (ARCHBIT + 1));
  supps[j][i]++;
}
    ptr += int_count_o;
  }
puis on appelle l'initialisation d'un tableau …
}
D'abord, on initialise la gestion des threads…pour le cas “simple” sequentiel, threads sera 1.
counts =
  (struct thread_stat *) calloc (threads, sizeof (struct thread_stat));
thread_id = (thread_id_t *) malloc (sizeof (thread_id_t) * threads);
memset (thread_id, 0, sizeof (thread_id_t) * threads);
thread_i = (int *) malloc (sizeof (int) * threads);
thread_queue =
  (unsigned char **) malloc (sizeof (unsigned char *) * threads);
thread_queue_head =
  (unsigned char **) malloc (sizeof (unsigned char *) * threads);
thread_queue_limit =
  (unsigned char **) malloc (sizeof (unsigned char *) * threads);
thread_intents =
  (unsigned long **) malloc (sizeof (unsigned long *) * threads);
queue_size = attributes;
queue_size = queue_size / threads + 1;
attrs = attributes - para_level + 1;
for (i = 0; i < threads; i++) {
  thread_i[i] = i;
  thread_queue_head[i] = thread_queue[i] = (unsigned char *)
    malloc ((BYTE_COUNT_A + BYTE_COUNT_O + (INT_SIZE << 1)) * queue_size);
  thread_queue_limit[i] =
    thread_queue_head[i] + (BYTE_COUNT_A + BYTE_COUNT_O +
		      (INT_SIZE << 1)) * queue_size;
  thread_intents[i] =
    (unsigned long *) malloc ((BYTE_COUNT_A + BYTE_COUNT_O) * attrs);
}
Ensuite on calcule la première fermeture:
compute_closure (thread_intents[0], thread_intents[0] + int_count_a, NULL, NULL, NULL);
les prochains appels (avec atr_extent existant) feront :
for (k = 0; k < int_count_o; k++) {
extent[k] = prev_extent[k] & atr_extent[k];
C'est à dire, calculer la nouvelle extension par intersection de l'extension precedente et l'extension de l'attribut. Si le résultat n'est pas null,
    if (extent[k])
for (l = 0; l <= ARCHBIT; l++)
  if (extent[k] & (BIT << l)) {
    for (i = 0, j =
	 int_count_a * (k * (ARCHBIT + 1) + l);
	 i < int_count_a; i++, j++)
      intent[i] &= context[j];
    (*supp)++;
  }
  }
}
counts[0].closures++; counts[0].computed++; print_attributes (thread_intents[0]); if (thread_intents[0][int_count_a - 1] & BIT) return;