/* should be faster than sorting the list */ void sort_sub_list (GHolder * h, GSort sort) { int i, j, k; GHolderItem *arr_items; for (i = 0; i < h->idx; i++) { GSubList *sub_list = h->items[i].sub_list; GSubItem *iter; arr_items = new_gholder_item (sub_list->size); /* copy items from the linked-list into an rray */ for (j = 0, iter = sub_list->head; iter; iter = iter->next) { arr_items[j].data = (char *) iter->data; arr_items[j++].hits = iter->hits; } sort_holder_items (arr_items, j, sort); delete_sub_list (sub_list); sub_list = new_gsublist (); for (k = 0; k < j; k++) { if (k > 0) sub_list = h->items[i].sub_list; add_sub_item_back (sub_list, h->module, arr_items[k].data, arr_items[k].hits, 0); h->items[i].sub_list = sub_list; } free (arr_items); } }
/* load raw hash table's data into holder */ void load_data_to_holder (GRawData * raw_data, GHolder * h, GModule module, GSort sort) { char *data; int hits, i; int size = 0;; unsigned long long bw = 0; size = raw_data->size; h->holder_size = size > MAX_CHOICES ? MAX_CHOICES : size; h->idx = 0; h->module = module; h->sub_items_size = 0; h->items = new_gholder_item (h->holder_size); for (i = 0; i < h->holder_size; i++) { bw = raw_data->items[i].bw; data = raw_data->items[i].data; hits = raw_data->items[i].hits; switch (module) { case OS: case BROWSERS: add_os_browser_node (h, hits, data, bw); break; case HOSTS: add_host_node (h, hits, data, bw, raw_data->items[i].usecs); break; case STATUS_CODES: add_status_code_node (h, hits, data, bw); break; default: h->items[h->idx].bw = bw; h->items[h->idx].data = xstrdup (data); h->items[h->idx].hits = hits; if (conf.serve_usecs) h->items[h->idx].usecs = raw_data->items[i].usecs; h->idx++; } } sort_holder_items (h->items, h->idx, sort); /* HOSTS module does not have "real" sub items, thus we don't include it */ if (module == OS || module == BROWSERS || module == STATUS_CODES) sort_sub_list (h, sort); free_raw_data (raw_data); }
/* Copy linked-list items to an array, sort, and move them back * to the list. Should be faster than sorting the list */ static void sort_sub_list (GHolder * h, GSort sort) { GHolderItem *arr; GSubItem *iter; GSubList *sub_list; int i, j, k; /* iterate over root-level nodes */ for (i = 0; i < h->idx; i++) { sub_list = h->items[i].sub_list; if (sub_list == NULL) continue; arr = new_gholder_item (sub_list->size); /* copy items from the linked-list into an array */ for (j = 0, iter = sub_list->head; iter; iter = iter->next, j++) { arr[j].metrics = new_gmetrics (); arr[j].metrics->bw.nbw = iter->metrics->bw.nbw; arr[j].metrics->data = xstrdup (iter->metrics->data); arr[j].metrics->hits = iter->metrics->hits; arr[j].metrics->id = iter->metrics->id; arr[j].metrics->visitors = iter->metrics->visitors; if (conf.serve_usecs) { arr[j].metrics->avgts.nts = iter->metrics->avgts.nts; arr[j].metrics->cumts.nts = iter->metrics->cumts.nts; arr[j].metrics->maxts.nts = iter->metrics->maxts.nts; } } sort_holder_items (arr, j, sort); delete_sub_list (sub_list); sub_list = new_gsublist (); for (k = 0; k < j; k++) { if (k > 0) sub_list = h->items[i].sub_list; add_sub_item_back (sub_list, h->module, arr[k].metrics); h->items[i].sub_list = sub_list; } free (arr); } }
/* Load raw data into our holder structure */ void load_holder_data (GRawData * raw_data, GHolder * h, GModule module, GSort sort) { int i, size = 0; const GPanel *panel = panel_lookup (module); size = raw_data->size; h->holder_size = size > MAX_CHOICES ? MAX_CHOICES : size; h->ht_size = size; h->idx = 0; h->module = module; h->sub_items_size = 0; h->items = new_gholder_item (h->holder_size); for (i = 0; i < h->holder_size; i++) { panel->insert (raw_data->items[i], h, panel); } sort_holder_items (h->items, h->idx, sort); if (h->sub_items_size) sort_sub_list (h, sort); free_raw_data (raw_data); }