The LevAWC Project
 All Data Structures Files Functions Variables Typedefs Enumerations Macros Pages
demo10.c
1 /*
2  * _____
3  * ANSI / ___/
4  * / /__
5  * \___/
6  *
7  * Filename: demo10.c
8  * Author : Dan Levin
9  * Date : Fri Feb 20 12:14:56 2015
10  * Version : 0.51
11  * ---
12  * Description: A demo program testing/showing the Open-addressed Hash Table ADT
13  *
14  * Revision history: (this is where you document the diffs between versions...)
15  * Date Revision
16  * 150204 Created this demo - and made it menu-driven
17  * 150220 Moved some utility functions from here - to file ../utils.c
18  * 150220 This source ready for version 0.5!
19  * 150318 This source ready for version 0.51
20  *
21  */
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <time.h>
26 #include "ohashtbl.h"
27 #include "utils.h"
28 
29 #ifndef OK
30 #define OK 0
31 #endif
32 
33 #ifndef TRUE
34 #define TRUE 1
35 #endif
36 
37 #ifndef FALSE
38 #define FALSE 0
39 #endif
40 
41 #define NR_OF_ITEMS 7
42 #define NR_OF_SLOTS 11
43 
44 /* Some string macros for the main menu... */
45 #define MAIN_MENU_ROW "--- OPEN-ADDRESSED HASH TABLE DEMO ---\nMENU: 0=Exit 1=Add_Node 2=Rem_Node 3=Search 4=Print\nSelection "
46 
47 /* FUNCTION-DECLARATIONS */
48 void my_destroy(void *data);
49 void print(const void *data);
50 int my_cmp(const void *key1, const void *key2);
51 int my_match(const void *k1, const void *k2);
52 int my_hash1(const void *key);
53 int my_hash2(const void *key);
54 
55 /* Functions handling menu selections */
56 void ins_node(OHtbl tbl);
57 void rem_node(OHtbl tbl);
58 void search_node(OHtbl tbl);
59 void print_table(OHtbl tbl);
60 void final_status(OHtbl tbl);
61 
62 /* Misc. application functions.. */
63 void create_nodes(OHtbl tbl, int nr_of_nodes);
64 /* END-OF-FUNCTION-DECLARATIONS */
65 
66 /* FUNCTION-DEFINITIONS - the rest of the program */
67 /* --- Function: void my_destroy(void *data) --- */
68 void my_destroy(void *data)
69 {
70  free(data);
71 }
72 
73 /* --- Function: void print(const void *data) --- */
74 void print(const void *data)
75 {
76  printf("\n%02d", *(int *)data);
77 }
78 
79 /* --- Function: int my_cmp(const int *key1, const int *key2) --- */
80 int my_cmp(const void *key1, const void *key2)
81 {
82  return (*(int *)key1 - *(int *)key2);
83 }
84 
85 /* --- Function: int my_match(const void *k1, const void *k2) --- */
86 int my_match(const void *k1, const void *k2)
87 {
88  return *(int *)k1 == *(int *)k2;
89 }
90 
91 /* --- Function: int my_hash1(const void *key) --- */
92 int my_hash1(const void *key)
93 {
94  return (*(const int *)key % NR_OF_SLOTS);
95 }
96 
97 /* --- Function: int my_hash2(const void *key) --- */
98 int my_hash2(const void *key)
99 {
100  return 1 + (*(const int *)key % (NR_OF_SLOTS - 2));
101 }
102 
103 /* --- Function: void add_nodes(OHtbl tbl, int nr_of_nodes) --- */
104 void create_nodes(OHtbl tbl, int nr_of_nodes)
105 {
106  int i=0, *pi, retval, dupctr=0;
107 
108  my_clearscrn();
109  printf("--- INITIALIZING A OPEN-ADDRESSED HASHTABLE, %d NODES, RANDOM INTEGER DATA ---", NR_OF_ITEMS);
110 
111  do
112  {
113  pi = (int *)malloc(sizeof(int));
114  MALCHK(pi);
115 
116  *pi = rand_int(1,99);
117 
118  if ((retval = OHTBLinsert(tbl, pi)) != OK) /* Insertion failed... */
119  {
120  if (retval == 1) /* Duplicate key value.. */
121  {
122  dupctr++;
123  my_destroy(pi); /* Free node - since duplicate.. */
124  }
125  else
126  {
127  if (retval == -1)
128  {
129  prompt_and_pause("Table full - or fatal error..!\n");
130  }
131  else
132  {
133  prompt_and_pause("Fatal error - bailing out..!\n");
134  }
135  OHTBLdestroy(tbl);
136  exit(retval);
137  }
138  }
139  } while (++i < nr_of_nodes);
140 
141  printf("\n\nCurrent table status:");
142  print_table(tbl);
143  printf("\n\n%d/%d successful insertions -- %d duplicate(s) rejected...", OHTBLsize(tbl), nr_of_nodes, dupctr);
144  prompt_and_pause("\n\n");
145 }
146 
147 /* --- Function: void ins_node(OHtbl tbl) --- */
148 void ins_node(OHtbl tbl)
149 {
150  int tmp, *pi, retval;
151  char mess[BUFSIZ];
152 
153  do
154  {
155  my_clearscrn();
156  printf("--- INSERT NODE ---");
157  printf("\n\nCurrent table status(%d nodes): ", OHTBLsize(tbl));
158  print_table(tbl);
159 
160  tmp = read_int("\nEnter data for node to be inserted (-1=Quit): ", 0, 0);
161 
162  if (tmp == -1)
163  break;
164 
165  pi = (int *)malloc(sizeof(int));
166  MALCHK(pi);
167 
168  *pi = tmp;
169 
170  if ((retval = OHTBLinsert(tbl, pi)) != OK) /* Insertion failed... */
171  {
172  if (retval == 1) /* Duplicate key value.. */
173  {
174  sprintf(mess, "Error: Duplicate - node %d already present..!", *pi);
175  prompt_and_pause(mess);
176  my_destroy(pi); /* Free node - since being duplicate.. */
177  }
178  else if (retval == -1)
179  {
180  prompt_and_pause("Table full - no more insertions possible..!\n");
181  my_destroy(pi); /* Free node - since being duplicate.. */
182  }
183  else
184  {
185  prompt_and_pause("\nFatal error - bailing out..!\n");
186  OHTBLdestroy(tbl);
187  exit(-1);
188  }
189  }
190  else
191  {
192  sprintf(mess, "Node %d will be inserted..", *(int *)pi);
193  prompt_and_pause(mess);
194  }
195  } while (TRUE);
196 }
197 
198 /* --- Function: void remove_nodes(OHtbl tbl) --- */
199 void rem_node(OHtbl tbl)
200 {
201  int tmp, *pi, retval;
202  char mess[BUFSIZ];
203 
204  do
205  {
206  my_clearscrn();
207  printf("--- REMOVE NODE ---");
208  printf("\n\nCurrent table status(%d nodes): ", OHTBLsize(tbl));
209  print_table(tbl);
210 
211  tmp = read_int("\nEnter (key)data for node to be removed (-1=Quit): ", 0, 0);
212 
213  if (tmp == -1)
214  break;
215 
216  pi = &tmp;
217  if ((retval = OHTBLremove(tbl, (void **)&pi)) != OK) /* Node removal failed.. */
218  {
219  /* Removal didn't work - node NOT found... */
220  if (retval == -1)
221  {
222  sprintf(mess, "Error: Node %d not found..!", *(int *)pi);
223  prompt_and_pause(mess);
224  }
225  else
226  {
227  printf("\nFatal failure - bailing out...");
228  OHTBLdestroy(tbl);
229  exit(retval);
230  }
231  }
232  else
233  {
234  /* Removal succesful - notify user.. */
235  sprintf(mess, "Node %d will be removed..!", *(int *)pi);
236  prompt_and_pause(mess);
237  /* Free node - after being removed from table.. */
238  my_destroy(pi);
239  }
240  } while (TRUE);
241 }
242 
243 /* --- Function: void search_node(OHtbl tbl) --- */
244 void search_node(OHtbl tbl)
245 {
246  int tmp, *pi, retval;
247  char mess[BUFSIZ];
248 
249  do
250  {
251  my_clearscrn();
252  printf("--- SEARCH NODE ---\n");
253  print_table(tbl);
254 
255  tmp = read_int("\nEnter (key)data for node to be found (-1=Quit): ", 0, 0);
256 
257  if (tmp == -1)
258  break;
259 
260  pi = &tmp;
261 
262  if ((retval = OHTBLlookup(tbl, (void **)&pi)) != OK) /* Node search failed.. */
263  {
264  /* Searching didn't work - node NOT found... */
265  if (retval == -1)
266  {
267  sprintf(mess, "Node %d NOT found..!", *(int *)pi);
268  prompt_and_pause(mess);
269  }
270  else /* Should not get here.. */
271  {
272  printf("Fatal failure - bailing out...");
273  getchar();
274  exit(retval);
275  }
276  }
277  else
278  {
279  /* Removal succesful - notify user.. */
280  sprintf(mess, "Node %d FOUND..!", *(int *)pi);
281  prompt_and_pause(mess);
282  }
283  } while (TRUE);
284 }
285 
286 /* --- Function: void print_table(parameter_list) --- */
287 void print_table(OHtbl tbl)
288 {
289  OHTBLprint(tbl, print);
290 }
291 
292 /* --- Function: void final_status(OHtbl tbl) --- */
293 void final_status(OHtbl tbl)
294 {
295  /* Final list status... */
296  my_clearscrn();
297  printf("--- FINAL STATUS ---");
298  printf("\n\nFinal table contents(%d nodes): ", OHTBLsize(tbl));
299  OHTBLprint(tbl, print);
300 }
301 
302 int main(void)
303 {
304  /* Declare YOUR variables here ! */
305  OHtbl mytbl;
306  int menu_choice;
307 
308  srand((unsigned int)time(NULL));
309 
310  if ((mytbl = OHTBLinit(NR_OF_SLOTS, my_hash1, my_hash2, my_match, my_destroy)) == NULL)
311  {
312  printf("\nFatal error - bailing out...\n!");
313  OHTBLdestroy(mytbl);
314  exit(-1);
315  }
316 
317  /* Initialize - and add nodes to the table... */
318  create_nodes(mytbl, NR_OF_ITEMS);
319 
320  /* Enter menu loop... */
321  do
322  {
323  menu_choice = menu(MAIN_MENU_ROW, 0, 4);
324 
325  switch (menu_choice)
326  {
327  case 1:
328  ins_node(mytbl);
329  break;
330  case 2:
331  rem_node(mytbl);
332  break;
333  case 3:
334  search_node(mytbl);
335  break;
336  case 4:
337  my_clearscrn();
338  printf("--- PRINT TABLE ---");
339  printf("\n\nFinal table contents(%d nodes): ", OHTBLsize(mytbl));
340  print_table(mytbl);
341  prompt_and_pause("\n\n");
342  break;
343  default:
344  final_status(mytbl);
345  break;
346  }
347  }
348  while (menu_choice);
349 
350  prompt_and_pause("\n\nLet's tidy up and destroy the hashtable..- Bye!");
351  OHTBLdestroy(mytbl);
352 
353  return 0;
354 }