OZ_DECLARE(struct hashtable_iterator *) hashtable_first(struct hashtable *h) { h->iterator.pos = 0; h->iterator.e = NULL; h->iterator.h = h; return hashtable_next(&h->iterator); }
void commit_data(struct config *conf) { int dbid = 0, done = 0; setitimer(ITIMER_PROF, &global_itimer, NULL); pthread_mutex_lock(&shutdown_lock); while (!done) { struct timespec sleep_time; struct timeval tv; gettimeofday(&tv, NULL); sleep_time.tv_sec = tv.tv_sec + conf->commit_interval; sleep_time.tv_nsec = tv.tv_usec * 1e3; if (pthread_cond_timedwait(&shutdown_cond, &shutdown_lock, &sleep_time) == 0) done = 1; debug("commit: checking for new data\n"); for (dbid = 0; dbid < MAX_SUBSTREAMS; dbid++) { unsigned long long *key = NULL; ReadingSet *val; while (1) { if (pthread_mutex_lock(&dbs[dbid].lock) != 0) break; key = NULL; val = hashtable_next(dbs[dbid].dirty_data, (void **)&key); if (val == NULL) { pthread_mutex_unlock(&dbs[dbid].lock); break; } val = hashtable_remove(dbs[dbid].dirty_data, key); pthread_mutex_unlock(&dbs[dbid].lock); assert(val != NULL); debug("adding dbid: %i streamid: %llu nrecs: %i\n", val->substream, val->streamid, val->n_data); if (add(conf, dbs[dbid].dbp, val) < 0) { warn("Transaction aborted in commit thread... retrying\n"); sleep(rand() % 10 ); if (add(conf, dbs[dbid].dbp, val) < 0) { warn("Transaction retry failed in commit thread... giving up\n"); INCR_STAT(failed_adds); } } _rpc_free_rs(val); } debug("Syncing...\n"); dbs[dbid].dbp->sync(dbs[dbid].dbp, 0); debug("Done!\n"); continue; } } pthread_mutex_unlock(&shutdown_lock); }
/** * Save a hashtable to disk * * @param table Hashtable to save * @param filename Filename to write hashtable into * @param keywrite Pointer to function that writes a single key * @param valuewrite Pointer to function that writes a single value * @return Number of entries written or -1 on error */ int hashtable_save(HASHTABLE *table, char *filename, int (*keywrite)(int, void*), int (*valuewrite)(int, void*)) { int fd, rval = 0; HASHITERATOR *iter; void *key, *value; if ((fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666)) == -1) { return -1; } if (write(fd, "HASHTABLE", 7) != 7) // Magic number { close(fd); return -1; } write(fd, &rval, sizeof(rval)); // Write zero counter, will be overrwriten at end if ((iter = hashtable_iterator(table)) != NULL) { while ((key = hashtable_next(iter)) != NULL) { if (!(*keywrite)(fd, key)) { close(fd); hashtable_iterator_free(iter); return -1; } if ((value = hashtable_fetch(table, key)) == NULL || (*valuewrite)(fd, value) == 0) { close(fd); hashtable_iterator_free(iter); return -1; } rval++; } } /* Now go back and write the count of entries */ if (lseek(fd, 7L, SEEK_SET) != -1) { write(fd, &rval, sizeof(rval)); } close(fd); hashtable_iterator_free(iter); return rval; }
/** * test1 spinlock_acquire_nowait tests * * Test that spinlock_acquire_nowait returns false if the spinlock * is already taken. * * Test that spinlock_acquire_nowait returns true if the spinlock * is not taken. * * Test that spinlock_acquire_nowait does hold the spinlock. */ static bool do_hashtest( int argelems, int argsize) { bool succp = true; HASHTABLE* h; int nelems; int i; int* val_arr; int hsize; int longest; int* iter; ss_dfprintf(stderr, "testhash : creating hash table of size %d, including %d " "elements in total, at time %g.", argsize, argelems, (double)clock()-start); val_arr = (int *)malloc(sizeof(void *)*argelems); h = hashtable_alloc(argsize, hfun, cmpfun); ss_dfprintf(stderr, "\t..done\nAdd %d elements to hash table.", argelems); for (i=0; i<argelems; i++) { val_arr[i] = i; hashtable_add(h, (void *)&val_arr[i], (void *)&val_arr[i]); } if (argelems > 1000) ss_dfprintf(stderr, "\t..done\nOperation took %g", (double)clock()-start); ss_dfprintf(stderr, "\t..done\nRead hash table statistics."); hashtable_get_stats((void *)h, &hsize, &nelems, &longest); ss_dfprintf(stderr, "\t..done\nValidate read values."); ss_info_dassert(hsize == (argsize > 0 ? argsize: 1), "Invalid hash size"); ss_info_dassert((nelems == argelems) || (nelems == 0 && argsize == 0), "Invalid element count"); ss_info_dassert(longest <= nelems, "Too large longest list value"); if (argelems > 1000) ss_dfprintf(stderr, "\t..done\nOperation took %g", (double)clock()-start); ss_dfprintf(stderr, "\t..done\nValidate iterator."); HASHITERATOR *iterator = hashtable_iterator(h); read_lock(h); for (i=0; i < (argelems+1); i++) { iter = (int *)hashtable_next(iterator); if (iter == NULL) break; if (argelems < 100) ss_dfprintf(stderr, "\nNext item, iter = %d, i = %d", *iter, i); } read_unlock(h); ss_info_dassert((i == argelems) || (i == 0 && argsize == 0), "\nIncorrect number of elements from iterator"); hashtable_iterator_free(iterator); if (argelems > 1000) ss_dfprintf(stderr, "\t..done\nOperation took %g", (double)clock()-start); ss_dfprintf(stderr, "\t\t..done\n\nTest completed successfully.\n\n"); CHK_HASHTABLE(h); hashtable_free(h); free(val_arr); return succp; }
/* Test driver for hashtable. */ int main(int argc, char **argv) { /* Test key_hashtable instance. */ hashtable_t *kt; hashtable_iter_t ki; key_t k1, k2; key_init(&k1, 1); key_init(&k2, 2); assert((kt = key_hashtable_new(16)) != NULL); assert(key_hashtable_add(kt, &k1) == &k1); assert(key_hashtable_find(kt, &k1) == &k1); assert(key_hashtable_find(kt, &k2) == NULL); assert(key_hashtable_iter(&ki, kt) == &k1); assert(key_hashtable_next(&ki) == NULL); /* Test hashtable instance. */ hashtable_t *t; entry_t entry[256]; entry_t e; match_t m; int i; entry_init(&e, 0); for (i = 0; i < 256; i++) entry_init(&entry[i], i); /* Test hashtable_new() */ t = hashtable_new(256); assert(t->size == 512); assert(t->count == 0); assert(t->etable != NULL); assert(t->ktable != NULL); /* Test hashtable_add() */ assert(hashtable_add(t, &e) == &e); /* Added duplicated copy. */ assert(hashtable_add(t, &entry[0]) == &entry[0]); /* Added duplicated instance. */ for (i = 0; i < 256; i++) assert(hashtable_add(t, &entry[i]) == &entry[i]); assert(t->count == 258); /* Test hashtable_find() */ match_init(&m, 0); assert(hashtable_find(t, &m) == &e); /* Finds first duplicate added. */ assert(m.value == m.source); /* match_cmp() updated m.value. */ for (i = 1; i < 256; i++) { match_init(&m, i); assert(hashtable_find(t, &m) == &entry[i]); assert(m.value == m.source); /* match_cmp() updated m.value. */ } match_init(&m, 256); assert(hashtable_find(t, &m) == NULL); /* Find missing entry. */ assert(m.value == 0); /* match_cmp() didn't update m.value. */ #ifndef HASHTABLE_NSTATS assert(t->find_count == 257); assert(t->match_count == 256); assert(t->hashcmp_count >= 256); assert(t->entrycmp_count >= 256); hashtable_stats_init(t); assert(t->find_count == 0); assert(t->match_count == 0); assert(t->hashcmp_count == 0); assert(t->entrycmp_count == 0); #endif /* Test hashtable iterators */ entry_t *p; hashtable_iter_t iter; int count = 0; for (p = hashtable_iter(&iter, t); p != NULL; p = hashtable_next(&iter)) { assert(p == &e || (&entry[0] <= p && p <= &entry[255])); count++; } assert(count == 258); hashtable_free(t); return 0; }