Table des matières

visite du code de pcbo

Pour comprendre cette implantation de l'algorithme CbO (ou son dual), voici ma visite commentée du code.

FIXME : Attention, ce n'est pas encore finie.

main

Dans ce qui suit, les multiples contrôles ne seront pas mentionnés, seulement le “traitement pur.”

read_context (in_file);

fclose (in_file);

print_context_info ();

initialize_algorithm ();

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 …

table_of_ints_init (attributes);

}

find_all_intents ();

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);

compute_closure

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)++;
  }
  }
}

suite de find_all_intents ();

counts[0].closures++;
counts[0].computed++;
print_attributes (thread_intents[0]);
if (thread_intents[0][int_count_a - 1] & BIT)
  return;

fclose (out_file);