Introduced a struct hash_table_t to clean the code a bit.
authorFrancois Fleuret <francois@fleuret.org>
Sun, 5 Jul 2009 11:41:08 +0000 (13:41 +0200)
committerFrancois Fleuret <francois@fleuret.org>
Sun, 5 Jul 2009 11:41:08 +0000 (13:41 +0200)
selector.c

index 6c0f7f5..41f29e0 100644 (file)
@@ -126,62 +126,78 @@ void error_feedback() {
   }
 }
 
-/*********************************************************************
- A quick and dirty hash table
+/* A quick and dirty hash table */
+
+/* The table itself stores indexes of the strings taken in a char
+   **table. When a string is added, if it was already in the table,
+   **the new index replaces the previous one.  */
+
+typedef struct {
+  int size;
+  int *entries;
+} hash_table_t;
 
- The table itself stores indexes of the strings taken in a char
- **table. When a string is added, if it was already in the table, the
- new index replaces the previous one. */
+hash_table_t *new_hash_table(int size) {
+  int k;
+  hash_table_t *hash_table;
+
+  hash_table = (hash_table_t *) malloc(sizeof(hash_table_t));
 
-int *new_hash_table(int hash_table_size) {
-  int *result, k;
-  result = (int *) malloc(hash_table_size * sizeof(int));
-  for(k = 0; k < hash_table_size; k++) {
-    result[k] = -1;
+  hash_table->size = size;
+  hash_table->entries = (int *) malloc(hash_table->size * sizeof(int));
+
+  for(k = 0; k < hash_table->size; k++) {
+    hash_table->entries[k] = -1;
   }
-  return result;
+
+  return hash_table;
+}
+
+void free_hash_table(hash_table_t *hash_table) {
+  free(hash_table->entries);
+  free(hash_table);
 }
 
 /* Adds new_string in the table, associated to new_index. If this
    string was not already in the table, returns -1. Otherwise, returns
    the previous index it had. */
 
-int add_and_get_previous_index(const char *new_string, int new_index,
-                               char **strings,
-                               int *hash_table, int hash_table_size) {
+int add_and_get_previous_index(hash_table_t *hash_table,
+                               const char *new_string, int new_index,
+                               char **strings) {
 
   unsigned int code = 0;
   int k;
 
   /* This is my recipe. I checked, it seems to work (as long as
-     hash_table_size is not a multiple of 387433 that should be
+     hash_table->size is not a multiple of 387433 that should be
      okay) */
 
   for(k = 0; new_string[k]; k++) {
     code = code * 387433 + (unsigned int) (new_string[k]);
   }
 
-  code = code % hash_table_size;
+  code = code % hash_table->size;
 
-  while(hash_table[code] >= 0) {
+  while(hash_table->entries[code] >= 0) {
     /* There is a string with that code */
-    if(strcmp(new_string, strings[hash_table[code]]) == 0) {
+    if(strcmp(new_string, strings[hash_table->entries[code]]) == 0) {
       /* It is the same string, we keep a copy of the stored index */
-      int result = hash_table[code];
+      int result = hash_table->entries[code];
       /* Put the new one */
-      hash_table[code] = new_index;
+      hash_table->entries[code] = new_index;
       /* And return the previous one */
       return result;
     }
     /* This collision was not the same string, let's move to the next
        in the table */
-    code = (code + 1) % hash_table_size;
+    code = (code + 1) % hash_table->size;
   }
 
   /* This string was not already in there, store the index in the
      table and return -1 */
 
-  hash_table[code] = new_index;
+  hash_table->entries[code] = new_index;
   return -1;
 }
 
@@ -574,9 +590,9 @@ void update_screen(int *current_focus_line, int *displayed_focus_line,
 
 /*********************************************************************/
 
-void store_line(const char *t,
-                int nb_lines_max, int *nb_lines, char **lines,
-                int hash_table_size, int *hash_table) {
+void store_line(hash_table_t *hash_table,
+                const char *t,
+                int nb_lines_max, int *nb_lines, char **lines) {
   int dup;
 
   /* Remove the zsh history prefix */
@@ -598,7 +614,7 @@ void store_line(const char *t,
      the list if necessary */
 
   if(hash_table) {
-    dup = add_and_get_previous_index(t, *nb_lines, lines, hash_table, hash_table_size);
+    dup = add_and_get_previous_index(hash_table, t, *nb_lines, lines);
   } else {
     dup = -1;
   }
@@ -616,9 +632,9 @@ void store_line(const char *t,
   (*nb_lines)++;
 }
 
-void read_file(const char *input_filename,
-               int nb_lines_max, int *nb_lines, char **lines,
-               int hash_table_size, int *hash_table) {
+void read_file(hash_table_t *hash_table,
+               const char *input_filename,
+               int nb_lines_max, int *nb_lines, char **lines) {
 
   char raw_line[BUFFER_SIZE];
   int start, end, k;
@@ -659,9 +675,8 @@ void read_file(const char *input_filename,
 
     raw_line[eol] = '\0';
 
-    store_line(raw_line + start,
-               nb_lines_max, nb_lines, lines,
-               hash_table_size, hash_table);
+    store_line(hash_table, raw_line + start,
+               nb_lines_max, nb_lines, lines);
 
     start = eol + 1;
   }
@@ -686,7 +701,8 @@ int main(int argc, char **argv) {
   int color_fg_highlight, color_bg_highlight;
 
   char **lines, **labels;
-  int nb_lines, hash_table_size, *hash_table;
+  int nb_lines;
+  hash_table_t *hash_table;
 
   if(!ttyname(STDIN_FILENO)) {
     fprintf(stderr, "The standard input is not a tty.\n");
@@ -855,27 +871,29 @@ int main(int argc, char **argv) {
   lines = (char **) malloc(nb_lines_max * sizeof(char *));
 
   nb_lines = 0;
-  hash_table_size = nb_lines_max * 10;
-  hash_table = 0;
 
   if(remove_duplicates) {
-    hash_table = new_hash_table(hash_table_size);
+    hash_table = new_hash_table(nb_lines_max * 10);
+  } else {
+    hash_table = 0;
   }
 
   if(input_filename[0]) {
-    read_file(input_filename,
-              nb_lines_max, &nb_lines, lines,
-              hash_table_size, hash_table);
+    read_file(hash_table,
+              input_filename,
+              nb_lines_max, &nb_lines, lines);
   }
 
   while(i < argc) {
-    read_file(argv[i],
-              nb_lines_max, &nb_lines, lines,
-              hash_table_size, hash_table);
+    read_file(hash_table,
+              argv[i],
+              nb_lines_max, &nb_lines, lines);
     i++;
   }
 
-  free(hash_table);
+  if(hash_table) {
+    free_hash_table(hash_table);
+  }
 
   /* Now remove the null strings */