/**
 * hi_insert insert a key/data pair into our hashhandle
 *
 * @arg hi_handle the hashish handle
 * @return SUCCESS or a negativ return values in the case of an error
 */
int hi_insert(hi_handle_t *hi_handle, const void *key, uint32_t keylen, const void *data)
{
	int ret;

	if (hi_lookup(hi_handle, key, keylen) == SUCCESS) /* already in hash or error */
		return HI_ERR_DUPKEY;

	do_rehash(hi_handle);

	switch (hi_handle->coll_eng) {
		case COLL_ENG_LIST:
		case COLL_ENG_LIST_HASH:
		case COLL_ENG_LIST_MTF:
		case COLL_ENG_LIST_MTF_HASH:
			ret = lhi_insert_list((hi_handle_t *)hi_handle, key, keylen, data);
			break;
		case COLL_ENG_ARRAY:
		case COLL_ENG_ARRAY_HASH:
		case COLL_ENG_ARRAY_DYN:
		case COLL_ENG_ARRAY_DYN_HASH:
			ret = lhi_insert_array((hi_handle_t *)hi_handle, key, keylen, data);
			break;
		case COLL_ENG_RBTREE:
			ret = lhi_insert_rbtree(hi_handle, key, keylen, data);
			break;
		default:
			ret = HI_ERR_INTERNAL;
			break;
	}
	return ret;
}
Exemple #2
0
static void
rehash (MonoGHashTable *hash)
{
	MONO_REQ_GC_UNSAFE_MODE; //we must run in unsafe mode to make rehash safe

	int diff = ABS (hash->last_rehash - hash->in_use);
	RehashData data;
	void *old_table G_GNUC_UNUSED; /* unused on Boehm */

	/* These are the factors to play with to change the rehashing strategy */
	/* I played with them with a large range, and could not really get */
	/* something that was too good, maybe the tests are not that great */
	if (!(diff * 0.75 > hash->table_size * 2))
		return;

	data.hash = hash;
	data.new_size = g_spaced_primes_closest (hash->in_use);
	data.table = mg_new0 (Slot *, data.new_size);

	if (!mono_threads_is_coop_enabled ()) {
		old_table = mono_gc_invoke_with_gc_lock (do_rehash, &data);
	} else {
		/* We cannot be preempted */
		old_table = do_rehash (&data);
	}

	mg_free (old_table);
}
Exemple #3
0
static void
rehash (GHashTable *hash)
{
	int diff = ABS (hash->last_rehash - hash->in_use);

	/* These are the factors to play with to change the rehashing strategy */
	/* I played with them with a large range, and could not really get */
	/* something that was too good, maybe the tests are not that great */
	if (!(diff * 0.75 > hash->table_size * 2))
		return;
	do_rehash (hash);
	sanity_check (hash);
}
Exemple #4
0
static void
rehash (MonoGHashTable *hash)
{
	MONO_REQ_GC_UNSAFE_MODE; //we must run in unsafe mode to make rehash safe

	RehashData data;
	void *old_keys = hash->keys;
	void *old_values = hash->values;

	data.hash = hash;
	/*
	 * Rehash to a size that can fit the current elements. Rehash relative to in_use
	 * to allow also for compaction.
	 */
	data.new_size = g_spaced_primes_closest (hash->in_use / HASH_TABLE_MAX_LOAD_FACTOR * HASH_TABLE_RESIZE_RATIO);
	data.keys = g_new0 (MonoObject*, data.new_size);
	data.values = g_new0 (MonoObject*, data.new_size);

	if (hash->gc_type & MONO_HASH_KEY_GC)
		mono_gc_register_root_wbarrier ((char*)data.keys, sizeof (MonoObject*) * data.new_size, mono_gc_make_vector_descr (), hash->source, hash->key, hash->msg);
	if (hash->gc_type & MONO_HASH_VALUE_GC)
		mono_gc_register_root_wbarrier ((char*)data.values, sizeof (MonoObject*) * data.new_size, mono_gc_make_vector_descr (), hash->source, hash->key, hash->msg);

	if (!mono_threads_are_safepoints_enabled ()) {
		mono_gc_invoke_with_gc_lock (do_rehash, &data);
	} else {
		/* We cannot be preempted */
		do_rehash (&data);
	}

	if (hash->gc_type & MONO_HASH_KEY_GC)
		mono_gc_deregister_root ((char*)old_keys);
	if (hash->gc_type & MONO_HASH_VALUE_GC)
		mono_gc_deregister_root ((char*)old_values);

	g_free (old_keys);
	g_free (old_values);
}
int main(int argc, char *argv[])
{
	int check_integrity = 0;
	int check_iplog = 0, check_replycache = 0;
	char *timespec_iplog = NULL, *timespec_replycache = NULL;
	int vacuum_db = 0, purge_deleted = 0, set_deleted = 0, dangling_aliases = 0, rehash = 0;
	int show_help = 0;
	int do_nothing = 1;
	int is_header = 0;
	int migrate = 0, migrate_limit = 10000;
	static struct option long_options[] = {
		{ "rehash", 0, 0, 0 },
		{ 0, 0, 0, 0 }
	};
	int opt_index = 0;
	int opt;

	g_mime_init(0);
	openlog(PNAME, LOG_PID, LOG_MAIL);
	setvbuf(stdout, 0, _IONBF, 0);

	/* get options */
	opterr = 0;		/* suppress error message from getopt() */
	while ((opt = getopt_long(argc, argv, "-acbtl:r:pudsMm:" "i" "f:qnyvVh", long_options, &opt_index)) != -1) {
		/* The initial "-" of optstring allows unaccompanied
		 * options and reports them as the optarg to opt 1 (not '1') */
		switch (opt) {
		case 0:
			do_nothing = 0;
			if (strcmp(long_options[opt_index].name,"rehash")==0)
				rehash = 1;
			break;
		case 'a':
			/* This list should be kept up to date. */
			vacuum_db = 1;
			purge_deleted = 1;
			set_deleted = 1;
			dangling_aliases = 1;
			check_integrity = 1;
			is_header = 1;
			do_nothing = 0;
			break;

		case 'c':
			vacuum_db = 1;
			do_nothing = 0;
			break;

		case 'b':
			is_header = 1;
			do_nothing = 0;
			break;

		case 'p':
			purge_deleted = 1;
			do_nothing = 0;
			break;

		case 'd':
			set_deleted = 1;
			do_nothing = 0;
			break;

		case 's':
			dangling_aliases = 1;
			do_nothing = 0;
			break;

		case 't':
			check_integrity = 1;
			do_nothing = 0;
			break;

		case 'u':
			/* deprecated */
			break;

		case 'l':
			check_iplog = 1;
			do_nothing = 0;
			if (optarg)
				timespec_iplog = g_strdup(optarg);
			break;

		case 'r':
			check_replycache = 1;
			do_nothing = 0;
			if (optarg)
				timespec_replycache = g_strdup(optarg);
			break;

		case 'M':
			migrate = 1;
			do_nothing = 0;
			break;
		case 'm':
			if (optarg)
				migrate_limit = atoi(optarg);
			break;

		case 'i':
			qerrorf("Interactive console is not supported in this release.\n");
			return 1;

		/* Common options */
		case 'h':
			show_help = 1;
			do_nothing = 0;
			break;

		case 'n':
			no_to_all = 1;
			break;

		case 'y':
			yes_to_all = 1;
			break;

		case 'q':
                        /* If we get q twice, be really quiet! */
                        if (quiet)
	                                reallyquiet = 1;
                        if (!verbose)
	                                quiet = 1;
			break;

		case 'f':
			if (optarg && strlen(optarg) > 0)
				configFile = optarg;
			else {
				qerrorf("dbmail-util: -f requires a filename\n\n" );
				return 1;
			}
			break;

		case 'v':
			verbose = 1;
			break;

		case 'V':
			PRINTF_THIS_IS_DBMAIL;
			return 1;

		default:
			printf("unrecognized option [%c]\n", optopt); 
			show_help = 1;
			break;
		}
	}

	if (do_nothing || show_help || (no_to_all && yes_to_all)) {
		do_showhelp();
		return 1;
	}

 	/* Don't make any changes unless specifically authorized. */
 	if (!yes_to_all) {
		qprintf("Choosing dry-run mode. No changes will be made at this time.\n");
		no_to_all = 1;
 	}

	config_read(configFile);
	SetTraceLevel("DBMAIL");
	GetDBParams();

	qverbosef("Opening connection to database... \n");
	if (db_connect() != 0) {
		qerrorf("Failed. An error occured. Please check log.\n");
		return -1;
	}

	qverbosef("Opening connection to authentication... \n");
	if (auth_connect() != 0) {
		qerrorf("Failed. An error occured. Please check log.\n");
		return -1;
	}

	qverbosef("Ok. Connected.\n");

	if (check_integrity) do_check_integrity();
	if (purge_deleted) do_purge_deleted();
	if (is_header) do_header_cache();
	if (set_deleted) do_set_deleted();
	if (dangling_aliases) do_dangling_aliases();
	if (check_iplog) do_check_iplog(timespec_iplog);
	if (check_replycache) do_check_replycache(timespec_replycache);
	if (vacuum_db) do_vacuum_db();
	if (rehash) do_rehash();
	if (migrate) do_migrate(migrate_limit);

	if (!has_errors && !serious_errors) {
		qprintf("\nMaintenance done. No errors found.\n");
	} else {
		qerrorf("\nMaintenance done. Errors were found");
		if (serious_errors) {
			qerrorf(" but not fixed due to failures.\n");
			qerrorf("Please check the logs for further details, "
				"turning up the trace level as needed.\n");
			// Indicate that something went really wrong
			has_errors = 3;
		} else if (no_to_all) {
			qerrorf(" but not fixed.\n");
			qerrorf("Run again with the '-y' option to "
				"repair the errors.\n");
			// Indicate that the program should be run with -y
			has_errors = 2;
		} else if (yes_to_all) {
			qerrorf(" and fixed.\n");
			qerrorf("We suggest running dbmail-util again to "
				"confirm that all errors were repaired.\n");
			// Indicate that the program should be run again
			has_errors = 1;
		}
	}

	auth_disconnect();
	db_disconnect();
	config_free();
	g_mime_shutdown();
	
	return has_errors;
}