int regusers_save(const struct bot *bot, const char *file) { FILE *f; if ((f = fopen(file, "w"))) { struct hashtable_iterator iter; void *k; void *v; hashtable_iterator_init(&iter, bot->regusers); while (hashtable_iterator_next(&iter, &k, &v)) { char flgstr[33] = {0}; struct reguser *usr = v; _reguser_flgtostr(usr->flags, flgstr, sizeof(flgstr)); fprintf(f, "%s:%s:%s\n", usr->name, flgstr, usr->mask); } } else { log_perror("fopen()", LOG_ERROR); return 1; } fclose(f); return 0; }
struct reguser *reguser_find(const struct bot *bot, const char *pre) { struct hashtable_iterator iter; void *k; void *v; hashtable_iterator_init(&iter, bot->regusers); while (hashtable_iterator_next(&iter, &k, &v)) if (regex_match(((struct reguser *)v)->mask, pre)) return v; return NULL; }
void print_bitcoin_ticker(struct json_value *ticker) { struct hashtable *rootobj = json_get_object(ticker); struct hashtable_iterator iter; hashtable_iterator_init(&iter, rootobj); const char *key; struct json_value *val; while (hashtable_iterator_next(&iter, (void**)&key, (void **)&val)) { printf(" %s (%s) / BTC: %.2lf\n", key, JSON_GET(JSON_OBJECT_LOOKUP(val, "symbol"), const char*), JSON_GET(JSON_OBJECT_LOOKUP(val, "15m"), double)); } }
/* main */ int main(int argc, char *argv[]) { struct hashtable * hashtable; struct hashtable_iterator iter; struct hashtable_entry entry; void * valuepointer; int valueint, seed = 0, stringcount = 0, stringlength, key_bytes = 0, value_bytes = 0, entrynumber, collisions = 0, delete_count; char * source, * destination, * value; diag("02b-hashtable"); plan(4); hashtable = hashtable_new(); srand(seed); /* TODO: get a portable seed from for example current time */ while (stringcount<STRINGCOUNT) { /* nondeterministic because of collisions */ char * key = random_string(MAXKEYLENGTH); /* create a value consisting of the key reversed followed by */ /* the original key, for example 'abc' -> 'cbaabc' */ stringlength = strlen(key); value = (char *) malloc(2 * stringlength + 1); destination=value+stringlength; * destination -- = '\0'; for (source=key; stringlength-->0; ) { * destination -- = * source ++; } strcat( value, key ); /* test whether the key is already in the hashtable */ if ( hashtable_fetch(hashtable, key, strlen(key), & valuepointer, & valueint) ) { /* it is already in the hash table, free these values */ free(key); free(value); ++ collisions; } else { /* it is not already in the hash table, add it */ hashtable_store(hashtable, key, strlen(key), value, strlen(value)); key_bytes += strlen(key); value_bytes += strlen(value); ++ stringcount; } } is_ii( stringcount, STRINGCOUNT, "created a hash with 5000 entries"); srand(seed); /* Test 2 - iterate the entries and delete them */ hashtable_iterator_init(hashtable, & iter); delete_count = 0; while (hashtable_iterator_next(& iter, & entry)) { key_bytes -= strlen(entry.keypointer); value_bytes -= strlen(entry.valuepointer); /* fprintf(stderr,"iter A '%s' => '%s'\n", (char *) entry.keypointer, (char *) entry.valuepointer); */ free(entry.keypointer); free(entry.valuepointer); ++delete_count; } is_ii(delete_count, stringcount, "iterate 5000 entries and delete"); /* Test 3 - verify total number of bytes in keys */ is_ii(key_bytes, 0, "all bytes in keys reclaimed"); /* Test 4 - verify total number of bytes in keys */ is_ii(value_bytes, 0, "all bytes in values reclaimed"); /* Cannot test this internally, but Valgrind should show that no */ /* bytes remain allocated on the heap. */ hashtable_free(hashtable); return 0; }