static int test_hash_iter_after_del(const struct test *t) { struct hash *h = hash_new(8, NULL); struct hash *h2 = hash_new(8, NULL); const char *k1 = "k1", *k2 = "k2", *k3 = "k3"; const char *v1 = "v1", *v2 = "v2", *v3 = "v3"; struct hash_iter iter; const char *k, *v; hash_add(h, k1, v1); hash_add(h2, k1, v1); hash_add(h, k2, v2); hash_add(h2, k2, v2); hash_add(h, k3, v3); hash_add(h2, k3, v3); hash_del(h, k1); for (hash_iter_init(h, &iter); hash_iter_next(&iter, &k, (const void **) &v);) { v2 = hash_find(h2, k); assert_return(v2 != NULL, EXIT_FAILURE); hash_del(h2, k); } assert_return(hash_get_count(h) == 2, EXIT_FAILURE); assert_return(hash_get_count(h2) == 1, EXIT_FAILURE); hash_free(h); hash_free(h2); return 0; }
static void check_buffer(EFLOWDESC *ex, void *mdl) { /* * lookup for a item in the hash table with sequence number = ex->next_seq. * if found, repeat until not found */ block_t * block; hash_iter_t iterator; block = (block_t *)hash_lookup_ulong(ex->htable, ex->next_seq); while (block != NULL) { if (block->seq == ex->next_seq) { /* must ALWAYS be true :) */ add_block(ex, block, mdl); unbuffer_block(ex, block->seq, block->len); } block = (block_t *)hash_lookup_ulong(ex->htable, ex->next_seq); } /* * in case there are overlapped packets, iterate on the hash table to look * for sequence numbers < ex->next_seq */ hash_iter_init(ex->htable, &iterator); while (hash_iter_next (&iterator)) { block = (block_t *)hash_iter_get_value(&iterator); if (block->seq <= ex->next_seq) { add_block(ex, block, mdl); /* * remove from hash with current key value, because the sequence * number could have changed (in case of overlap with valid data), * so no longer would coincide with the hash key */ unbuffer_block(ex, hash_iter_get_ulong_key(&iterator), block->len); /* start again */ hash_iter_init(ex->htable, &iterator); } } }
hash_iter_t *hash_iter_new(hash_t *ht) { hash_iter_t *iter = (hash_iter_t *)calloc(1, sizeof(*iter)); if (!iter) { return NULL; } if (hash_iter_init(iter, ht) != 0) { free(iter); return NULL; } return iter; }
int qname_iterator(char **label) { qnameobj *obj; static char label_buf[MAX_QNAME_SZ]; if (0 == next_idx) return -1; if (NULL == label) { hash_iter_init(theHash); return next_idx; } if ((obj = hash_iterate(theHash)) == NULL) return -1; snprintf(label_buf, MAX_QNAME_SZ, "%s", obj->qname); *label = label_buf; return obj->index; }
int cip_net_iterator(char **label) { ipnetobj *obj; static char label_buf[128]; if (0 == next_idx) return -1; if (NULL == label) { hash_iter_init(theHash); return next_idx; } if ((obj = hash_iterate(theHash)) == NULL) return -1; inXaddr_ntop(&obj->addr, label_buf, 128); *label = label_buf; return obj->index; }
int tld_iterator(char **label) { tldobj *obj; static char label_buf[MAX_QNAME_SZ]; if (0 == next_idx) return -1; if (NULL == label) { /* initialize and tell caller how big the array is */ hash_iter_init(theHash); return next_idx; } if ((obj = hash_iterate(theHash)) == NULL) return -1; snprintf(label_buf, MAX_QNAME_SZ, "%s", obj->tld); *label = label_buf; return obj->index; }
static void sort_buffer(EFLOWDESC *ex, void *mdl) { /* * this only happens when FIN / RST arrives for a flow that was already * established when sniffing started. so SYN was not captured (initial * sequence number). in this case, just sort what we have captured. */ hash_iter_t iterator; block_t * block, * min_block; min_block = NULL; hash_iter_init(ex->htable, &iterator); while (hash_iter_next(&iterator)) { block = (block_t *)hash_iter_get_value (&iterator); if (min_block == NULL || block->seq < min_block->seq) min_block = block; } /* * min_block is now the 'first' block of all. so set it as the first block, * then call check_buffer to put everything in place. */ if (min_block != NULL) { ex->base_seq = min_block->seq; ex->next_seq = min_block->seq; add_block(ex, min_block, mdl); unbuffer_block(ex, min_block->seq, min_block->len); check_buffer(ex, mdl); } /* now all possible blocks to be ordered (if any) should be in order */ }
int hash_iter_reset(hash_iter_t *iter) { hash_t *tmp; tmp = iter->ht; hash_iter_destroy(iter); return hash_iter_init(iter, tmp); }
void set_iter_init(set *s, set_iter *iter) { hash_iter_init(s->ht, iter); }