Exemplo n.º 1
0
int main(int argc, char *argv[])
{
	struct tdb_context *tdb;
	TDB_DATA key, data;

	plan_tests(4);
	tdb = tdb_open_ex(NULL, 1024, TDB_INTERNAL, O_CREAT|O_TRUNC|O_RDWR,
			  0600, &taplogctx, NULL);
	ok1(tdb);

	/* Tickle bug on appending zero length buffer to zero length buffer. */
	key.dsize = strlen("hi");
	key.dptr = (void *)"hi";
	data.dptr = (void *)"world";
	data.dsize = 0;

	ok1(tdb_append(tdb, key, data) == 0);
	ok1(tdb_append(tdb, key, data) == 0);
	data = tdb_fetch(tdb, key);
	ok1(data.dsize == 0);
	tdb_close(tdb);
	free(data.dptr);

	return exit_status();
}
Exemplo n.º 2
0
int main(int argc, char *argv[])
{
	struct tdb_context *tdb;
	TDB_DATA key, data;
	union tdb_attribute hsize;

	hsize.base.attr = TDB_ATTRIBUTE_TDB1_HASHSIZE;
	hsize.base.next = &tap_log_attr;
	hsize.tdb1_hashsize.hsize = 1024;

	plan_tests(5);
	tdb = tdb_open(NULL, TDB_INTERNAL|TDB_VERSION1, O_CREAT|O_TRUNC|O_RDWR,
		       0600, &hsize);
	ok1(tdb);

	/* Tickle bug on appending zero length buffer to zero length buffer. */
	key = tdb_mkdata("hi", strlen("hi"));
	data = tdb_mkdata("world", 0);

	ok1(tdb_append(tdb, key, data) == TDB_SUCCESS);
	ok1(tdb_append(tdb, key, data) == TDB_SUCCESS);
	ok1(tdb_fetch(tdb, key, &data) == TDB_SUCCESS);
	ok1(data.dsize == 0);
	free(data.dptr);
	tdb_close(tdb);

	return exit_status();
}
Exemplo n.º 3
0
static PyObject *obj_append(PyTdbObject *self, PyObject *args)
{
	TDB_DATA key, data;
	PyObject *py_key, *py_data;
	int ret;

	PyErr_TDB_RAISE_IF_CLOSED(self);

	if (!PyArg_ParseTuple(args, "OO", &py_key, &py_data))
		return NULL;

	key = PyString_AsTDB_DATA(py_key);
	if (!key.dptr)
		return NULL;
	data = PyString_AsTDB_DATA(py_data);
	if (!data.dptr)
		return NULL;

	ret = tdb_append(self->ctx, key, data);
	PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx);
	Py_RETURN_NONE;
}
Exemplo n.º 4
0
int main(int argc, char *argv[])
{
	unsigned int i, j, num = 1000, stage = 0, stopat = -1;
	int flags = TDB_DEFAULT;
	bool transaction = false, summary = false;
	TDB_DATA key, data;
	struct tdb_context *tdb;
	struct timeval start, stop;
	union tdb_attribute seed, log;
	bool do_stats = false;
	enum TDB_ERROR ecode;

	/* Try to keep benchmarks even. */
	seed.base.attr = TDB_ATTRIBUTE_SEED;
	seed.base.next = NULL;
	seed.seed.seed = 0;

	log.base.attr = TDB_ATTRIBUTE_LOG;
	log.base.next = &seed;
	log.log.fn = tdb_log;

	if (argv[1] && strcmp(argv[1], "--internal") == 0) {
		flags = TDB_INTERNAL;
		argc--;
		argv++;
	}
	if (argv[1] && strcmp(argv[1], "--transaction") == 0) {
		transaction = true;
		argc--;
		argv++;
	}
	if (argv[1] && strcmp(argv[1], "--no-sync") == 0) {
		flags |= TDB_NOSYNC;
		argc--;
		argv++;
	}
	if (argv[1] && strcmp(argv[1], "--summary") == 0) {
		summary = true;
		argc--;
		argv++;
	}
	if (argv[1] && strcmp(argv[1], "--stats") == 0) {
		do_stats = true;
		argc--;
		argv++;
	}

	tdb = tdb_open("/tmp/speed.tdb", flags, O_RDWR|O_CREAT|O_TRUNC,
		       0600, &log);
	if (!tdb)
		err(1, "Opening /tmp/speed.tdb");

	key.dptr = (void *)&i;
	key.dsize = sizeof(i);
	data = key;

	if (argv[1]) {
		num = atoi(argv[1]);
		argv++;
		argc--;
	}

	if (argv[1]) {
		stopat = atoi(argv[1]);
		argv++;
		argc--;
	}

	/* Add 1000 records. */
	printf("Adding %u records: ", num); fflush(stdout);
	if (transaction && (ecode = tdb_transaction_start(tdb)))
		errx(1, "starting transaction: %s", tdb_errorstr(ecode));
	gettimeofday(&start, NULL);
	for (i = 0; i < num; i++)
		if ((ecode = tdb_store(tdb, key, data, TDB_INSERT)) != 0)
			errx(1, "Inserting key %u in tdb: %s",
			     i, tdb_errorstr(ecode));
	gettimeofday(&stop, NULL);
	if (transaction && (ecode = tdb_transaction_commit(tdb)))
		errx(1, "committing transaction: %s", tdb_errorstr(ecode));
	printf(" %zu ns (%zu bytes)\n",
	       normalize(&start, &stop, num), file_size());

	if (tdb_check(tdb, NULL, NULL))
		errx(1, "tdb_check failed!");
	if (summary) {
		char *sumstr = NULL;
		tdb_summary(tdb, TDB_SUMMARY_HISTOGRAMS, &sumstr);
		printf("%s\n", sumstr);
		free(sumstr);
	}
	if (do_stats)
		dump_and_clear_stats(&tdb, flags, &log);

	if (++stage == stopat)
		exit(0);

	/* Finding 1000 records. */
	printf("Finding %u records: ", num); fflush(stdout);
	if (transaction && (ecode = tdb_transaction_start(tdb)))
		errx(1, "starting transaction: %s", tdb_errorstr(ecode));
	gettimeofday(&start, NULL);
	for (i = 0; i < num; i++) {
		struct tdb_data dbuf;
		if ((ecode = tdb_fetch(tdb, key, &dbuf)) != TDB_SUCCESS
		    || *(int *)dbuf.dptr != i) {
			errx(1, "Fetching key %u in tdb gave %u",
			     i, ecode ? ecode : *(int *)dbuf.dptr);
		}
	}
	gettimeofday(&stop, NULL);
	if (transaction && (ecode = tdb_transaction_commit(tdb)))
		errx(1, "committing transaction: %s", tdb_errorstr(ecode));
	printf(" %zu ns (%zu bytes)\n",
	       normalize(&start, &stop, num), file_size());
	if (tdb_check(tdb, NULL, NULL))
		errx(1, "tdb_check failed!");
	if (summary) {
		char *sumstr = NULL;
		tdb_summary(tdb, TDB_SUMMARY_HISTOGRAMS, &sumstr);
		printf("%s\n", sumstr);
		free(sumstr);
	}
	if (do_stats)
		dump_and_clear_stats(&tdb, flags, &log);
	if (++stage == stopat)
		exit(0);

	/* Missing 1000 records. */
	printf("Missing %u records: ", num); fflush(stdout);
	if (transaction && (ecode = tdb_transaction_start(tdb)))
		errx(1, "starting transaction: %s", tdb_errorstr(ecode));
	gettimeofday(&start, NULL);
	for (i = num; i < num*2; i++) {
		struct tdb_data dbuf;
		ecode = tdb_fetch(tdb, key, &dbuf);
		if (ecode != TDB_ERR_NOEXIST)
			errx(1, "Fetching key %u in tdb gave %s",
			     i, tdb_errorstr(ecode));
	}
	gettimeofday(&stop, NULL);
	if (transaction && (ecode = tdb_transaction_commit(tdb)))
		errx(1, "committing transaction: %s", tdb_errorstr(ecode));
	printf(" %zu ns (%zu bytes)\n",
	       normalize(&start, &stop, num), file_size());
	if (tdb_check(tdb, NULL, NULL))
		errx(1, "tdb_check failed!");
	if (summary) {
		char *sumstr = NULL;
		tdb_summary(tdb, TDB_SUMMARY_HISTOGRAMS, &sumstr);
		printf("%s\n", sumstr);
		free(sumstr);
	}
	if (do_stats)
		dump_and_clear_stats(&tdb, flags, &log);
	if (++stage == stopat)
		exit(0);

	/* Traverse 1000 records. */
	printf("Traversing %u records: ", num); fflush(stdout);
	if (transaction && (ecode = tdb_transaction_start(tdb)))
		errx(1, "starting transaction: %s", tdb_errorstr(ecode));
	i = 0;
	gettimeofday(&start, NULL);
	if (tdb_traverse(tdb, count_record, &i) != num)
		errx(1, "Traverse returned wrong number of records");
	if (i != (num - 1) * (num / 2))
		errx(1, "Traverse tallied to %u", i);
	gettimeofday(&stop, NULL);
	if (transaction && (ecode = tdb_transaction_commit(tdb)))
		errx(1, "committing transaction: %s", tdb_errorstr(ecode));
	printf(" %zu ns (%zu bytes)\n",
	       normalize(&start, &stop, num), file_size());
	if (tdb_check(tdb, NULL, NULL))
		errx(1, "tdb_check failed!");
	if (summary) {
		char *sumstr = NULL;
		tdb_summary(tdb, TDB_SUMMARY_HISTOGRAMS, &sumstr);
		printf("%s\n", sumstr);
		free(sumstr);
	}
	if (do_stats)
		dump_and_clear_stats(&tdb, flags, &log);
	if (++stage == stopat)
		exit(0);

	/* Delete 1000 records (not in order). */
	printf("Deleting %u records: ", num); fflush(stdout);
	if (transaction && (ecode = tdb_transaction_start(tdb)))
		errx(1, "starting transaction: %s", tdb_errorstr(ecode));
	gettimeofday(&start, NULL);
	for (j = 0; j < num; j++) {
		i = (j + 100003) % num;
		if ((ecode = tdb_delete(tdb, key)) != TDB_SUCCESS)
			errx(1, "Deleting key %u in tdb: %s",
			     i, tdb_errorstr(ecode));
	}
	gettimeofday(&stop, NULL);
	if (transaction && (ecode = tdb_transaction_commit(tdb)))
		errx(1, "committing transaction: %s", tdb_errorstr(ecode));
	printf(" %zu ns (%zu bytes)\n",
	       normalize(&start, &stop, num), file_size());
	if (tdb_check(tdb, NULL, NULL))
		errx(1, "tdb_check failed!");
	if (summary) {
		char *sumstr = NULL;
		tdb_summary(tdb, TDB_SUMMARY_HISTOGRAMS, &sumstr);
		printf("%s\n", sumstr);
		free(sumstr);
	}
	if (do_stats)
		dump_and_clear_stats(&tdb, flags, &log);
	if (++stage == stopat)
		exit(0);

	/* Re-add 1000 records (not in order). */
	printf("Re-adding %u records: ", num); fflush(stdout);
	if (transaction && (ecode = tdb_transaction_start(tdb)))
		errx(1, "starting transaction: %s", tdb_errorstr(ecode));
	gettimeofday(&start, NULL);
	for (j = 0; j < num; j++) {
		i = (j + 100003) % num;
		if ((ecode = tdb_store(tdb, key, data, TDB_INSERT)) != 0)
			errx(1, "Inserting key %u in tdb: %s",
			     i, tdb_errorstr(ecode));
	}
	gettimeofday(&stop, NULL);
	if (transaction && (ecode = tdb_transaction_commit(tdb)))
		errx(1, "committing transaction: %s", tdb_errorstr(ecode));
	printf(" %zu ns (%zu bytes)\n",
	       normalize(&start, &stop, num), file_size());
	if (tdb_check(tdb, NULL, NULL))
		errx(1, "tdb_check failed!");
	if (summary) {
		char *sumstr = NULL;
		tdb_summary(tdb, TDB_SUMMARY_HISTOGRAMS, &sumstr);
		printf("%s\n", sumstr);
		free(sumstr);
	}
	if (do_stats)
		dump_and_clear_stats(&tdb, flags, &log);
	if (++stage == stopat)
		exit(0);

	/* Append 1000 records. */
	if (transaction && (ecode = tdb_transaction_start(tdb)))
		errx(1, "starting transaction: %s", tdb_errorstr(ecode));
	printf("Appending %u records: ", num); fflush(stdout);
	gettimeofday(&start, NULL);
	for (i = 0; i < num; i++)
		if ((ecode = tdb_append(tdb, key, data)) != TDB_SUCCESS)
			errx(1, "Appending key %u in tdb: %s",
			     i, tdb_errorstr(ecode));
	gettimeofday(&stop, NULL);
	if (transaction && (ecode = tdb_transaction_commit(tdb)))
		errx(1, "committing transaction: %s", tdb_errorstr(ecode));
	printf(" %zu ns (%zu bytes)\n",
	       normalize(&start, &stop, num), file_size());
	if (tdb_check(tdb, NULL, NULL))
		errx(1, "tdb_check failed!");
	if (summary) {
		char *sumstr = NULL;
		tdb_summary(tdb, TDB_SUMMARY_HISTOGRAMS, &sumstr);
		printf("%s\n", sumstr);
		free(sumstr);
	}
	if (++stage == stopat)
		exit(0);

	/* Churn 1000 records: not in order! */
	if (transaction && (ecode = tdb_transaction_start(tdb)))
		errx(1, "starting transaction: %s", tdb_errorstr(ecode));
	printf("Churning %u records: ", num); fflush(stdout);
	gettimeofday(&start, NULL);
	for (j = 0; j < num; j++) {
		i = (j + 1000019) % num;
		if ((ecode = tdb_delete(tdb, key)) != TDB_SUCCESS)
			errx(1, "Deleting key %u in tdb: %s",
			     i, tdb_errorstr(ecode));
		i += num;
		if ((ecode = tdb_store(tdb, key, data, TDB_INSERT)) != 0)
			errx(1, "Inserting key %u in tdb: %s",
			     i, tdb_errorstr(ecode));
	}
	gettimeofday(&stop, NULL);
	if (transaction && (ecode = tdb_transaction_commit(tdb)))
		errx(1, "committing transaction: %s", tdb_errorstr(ecode));
	printf(" %zu ns (%zu bytes)\n",
	       normalize(&start, &stop, num), file_size());

	if (tdb_check(tdb, NULL, NULL))
		errx(1, "tdb_check failed!");
	if (summary) {
		char *sumstr = NULL;
		tdb_summary(tdb, TDB_SUMMARY_HISTOGRAMS, &sumstr);
		printf("%s\n", sumstr);
		free(sumstr);
	}
	if (do_stats)
		dump_and_clear_stats(&tdb, flags, &log);
	if (++stage == stopat)
		exit(0);

	return 0;
}
Exemplo n.º 5
0
static void addrec_db(void)
{
	int klen, dlen;
	char *k, *d;
	TDB_DATA key, data;

	klen = 1 + (rand() % KEYLEN);
	dlen = 1 + (rand() % DATALEN);

	k = randbuf(klen);
	d = randbuf(dlen);

	key.dptr = (unsigned char *)k;
	key.dsize = klen+1;

	data.dptr = (unsigned char *)d;
	data.dsize = dlen+1;

#if REOPEN_PROB
	if (in_transaction == 0 && random() % REOPEN_PROB == 0) {
		tdb_reopen_all(0);
		goto next;
	}
#endif

#if TRANSACTION_PROB
	if (in_transaction == 0 &&
	    (always_transaction || random() % TRANSACTION_PROB == 0)) {
		if (tdb_transaction_start(db) != 0) {
			fatal("tdb_transaction_start failed");
		}
		in_transaction++;
		goto next;
	}
	if (in_transaction && random() % TRANSACTION_PROB == 0) {
		if (random() % TRANSACTION_PREPARE_PROB == 0) {
			if (tdb_transaction_prepare_commit(db) != 0) {
				fatal("tdb_transaction_prepare_commit failed");
			}
		}
		if (tdb_transaction_commit(db) != 0) {
			fatal("tdb_transaction_commit failed");
		}
		in_transaction--;
		goto next;
	}
	if (in_transaction && random() % TRANSACTION_PROB == 0) {
		if (tdb_transaction_cancel(db) != 0) {
			fatal("tdb_transaction_cancel failed");
		}
		in_transaction--;
		goto next;
	}
#endif

#if DELETE_PROB
	if (random() % DELETE_PROB == 0) {
		tdb_delete(db, key);
		goto next;
	}
#endif

#if STORE_PROB
	if (random() % STORE_PROB == 0) {
		if (tdb_store(db, key, data, TDB_REPLACE) != 0) {
			fatal("tdb_store failed");
		}
		goto next;
	}
#endif

#if APPEND_PROB
	if (random() % APPEND_PROB == 0) {
		if (tdb_append(db, key, data) != 0) {
			fatal("tdb_append failed");
		}
		goto next;
	}
#endif

#if LOCKSTORE_PROB
	if (random() % LOCKSTORE_PROB == 0) {
		tdb_chainlock(db, key);
		data = tdb_fetch(db, key);
		if (tdb_store(db, key, data, TDB_REPLACE) != 0) {
			fatal("tdb_store failed");
		}
		if (data.dptr) free(data.dptr);
		tdb_chainunlock(db, key);
		goto next;
	} 
#endif

#if TRAVERSE_PROB
	if (random() % TRAVERSE_PROB == 0) {
		tdb_traverse(db, cull_traverse, NULL);
		goto next;
	}
#endif

#if TRAVERSE_READ_PROB
	if (random() % TRAVERSE_READ_PROB == 0) {
		tdb_traverse_read(db, NULL, NULL);
		goto next;
	}
#endif

	data = tdb_fetch(db, key);
	if (data.dptr) free(data.dptr);

next:
	free(k);
	free(d);
}
Exemplo n.º 6
0
int main(int argc, char *argv[])
{
	unsigned int i, extra_msgs;
	struct tdb_context *tdb;
	struct tdb_data key = tdb_mkdata("key", 3);
	struct tdb_data data = tdb_mkdata("data", 4);
	int flags[] = { TDB_DEFAULT, TDB_NOMMAP,
			TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT,
			TDB_VERSION1, TDB_NOMMAP|TDB_VERSION1,
			TDB_CONVERT|TDB_VERSION1,
			TDB_NOMMAP|TDB_CONVERT|TDB_VERSION1 };

	plan_tests(sizeof(flags) / sizeof(flags[0]) * 48);

	for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
		/* RW -> R0 */
		tdb = tdb_open("run-92-get-set-readonly.tdb", flags[i],
			       O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
		ok1(tdb);
		ok1(!(tdb_get_flags(tdb) & TDB_RDONLY));

		/* TDB1 complains multiple times. */
		if (flags[i] & TDB_VERSION1) {
			extra_msgs = 1;
		} else {
			extra_msgs = 0;
		}

		ok1(tdb_store(tdb, key, data, TDB_INSERT) == TDB_SUCCESS);

		tdb_add_flag(tdb, TDB_RDONLY);
		ok1(tdb_get_flags(tdb) & TDB_RDONLY);

		/* Can't store, append, delete. */
		ok1(tdb_store(tdb, key, data, TDB_MODIFY) == TDB_ERR_RDONLY);
		ok1(tap_log_messages == 1);
		ok1(tdb_append(tdb, key, data) == TDB_ERR_RDONLY);
		tap_log_messages -= extra_msgs;
		ok1(tap_log_messages == 2);
		ok1(tdb_delete(tdb, key) == TDB_ERR_RDONLY);
		tap_log_messages -= extra_msgs;
		ok1(tap_log_messages == 3);

		/* Can't start a transaction, or any write lock. */
		ok1(tdb_transaction_start(tdb) == TDB_ERR_RDONLY);
		ok1(tap_log_messages == 4);
		ok1(tdb_chainlock(tdb, key) == TDB_ERR_RDONLY);
		tap_log_messages -= extra_msgs;
		ok1(tap_log_messages == 5);
		ok1(tdb_lockall(tdb) == TDB_ERR_RDONLY);
		ok1(tap_log_messages == 6);
		ok1(tdb_wipe_all(tdb) == TDB_ERR_RDONLY);
		ok1(tap_log_messages == 7);

		/* Back to RW. */
		tdb_remove_flag(tdb, TDB_RDONLY);
		ok1(!(tdb_get_flags(tdb) & TDB_RDONLY));

		ok1(tdb_store(tdb, key, data, TDB_MODIFY) == TDB_SUCCESS);
		ok1(tdb_append(tdb, key, data) == TDB_SUCCESS);
		ok1(tdb_delete(tdb, key) == TDB_SUCCESS);

		ok1(tdb_transaction_start(tdb) == TDB_SUCCESS);
		ok1(tdb_store(tdb, key, data, TDB_INSERT) == TDB_SUCCESS);
		ok1(tdb_transaction_commit(tdb) == TDB_SUCCESS);

		ok1(tdb_chainlock(tdb, key) == TDB_SUCCESS);
		tdb_chainunlock(tdb, key);
		ok1(tdb_lockall(tdb) == TDB_SUCCESS);
		tdb_unlockall(tdb);
		ok1(tdb_wipe_all(tdb) == TDB_SUCCESS);
		ok1(tap_log_messages == 7);

		tdb_close(tdb);

		/* R0 -> RW */
		tdb = tdb_open("run-92-get-set-readonly.tdb", flags[i],
			       O_RDONLY, 0600, &tap_log_attr);
		ok1(tdb);
		ok1(tdb_get_flags(tdb) & TDB_RDONLY);

		/* Can't store, append, delete. */
		ok1(tdb_store(tdb, key, data, TDB_INSERT) == TDB_ERR_RDONLY);
		ok1(tap_log_messages == 8);
		ok1(tdb_append(tdb, key, data) == TDB_ERR_RDONLY);
		tap_log_messages -= extra_msgs;
		ok1(tap_log_messages == 9);
		ok1(tdb_delete(tdb, key) == TDB_ERR_RDONLY);
		tap_log_messages -= extra_msgs;
		ok1(tap_log_messages == 10);

		/* Can't start a transaction, or any write lock. */
		ok1(tdb_transaction_start(tdb) == TDB_ERR_RDONLY);
		ok1(tap_log_messages == 11);
		ok1(tdb_chainlock(tdb, key) == TDB_ERR_RDONLY);
		tap_log_messages -= extra_msgs;
		ok1(tap_log_messages == 12);
		ok1(tdb_lockall(tdb) == TDB_ERR_RDONLY);
		ok1(tap_log_messages == 13);
		ok1(tdb_wipe_all(tdb) == TDB_ERR_RDONLY);
		ok1(tap_log_messages == 14);

		/* Can't remove TDB_RDONLY since we opened with O_RDONLY */
		tdb_remove_flag(tdb, TDB_RDONLY);
		ok1(tap_log_messages == 15);
		ok1(tdb_get_flags(tdb) & TDB_RDONLY);
		tdb_close(tdb);

		ok1(tap_log_messages == 15);
		tap_log_messages = 0;
	}
	return exit_status();
}
Exemplo n.º 7
0
static BOOL message_send_pid_internal(struct process_id pid, int msg_type,
				      const void *buf, size_t len,
				      BOOL duplicates_allowed,
				      unsigned int timeout)
{
	TDB_DATA kbuf;
	TDB_DATA dbuf;
	TDB_DATA old_dbuf;
	struct message_rec rec;
	char *ptr;
	struct message_rec prec;

	/* NULL pointer means implicit length zero. */
	if (!buf) {
		SMB_ASSERT(len == 0);
	}

	/*
	 * Doing kill with a non-positive pid causes messages to be
	 * sent to places we don't want.
	 */

	SMB_ASSERT(procid_to_pid(&pid) > 0);

	rec.msg_version = MESSAGE_VERSION;
	rec.msg_type = msg_type;
	rec.dest = pid;
	rec.src = procid_self();
	rec.len = buf ? len : 0;

	kbuf = message_key_pid(pid);

	dbuf.dptr = (void *)SMB_MALLOC(len + sizeof(rec));
	if (!dbuf.dptr)
		return False;

	memcpy(dbuf.dptr, &rec, sizeof(rec));
	if (len > 0 && buf)
		memcpy((void *)((char*)dbuf.dptr+sizeof(rec)), buf, len);

	dbuf.dsize = len + sizeof(rec);

	if (duplicates_allowed) {

		/* If duplicates are allowed we can just append the message and return. */

		/* lock the record for the destination */
		if (timeout) {
			if (tdb_chainlock_with_timeout(tdb, kbuf, timeout) == -1) {
				DEBUG(0,("message_send_pid_internal: failed to get chainlock with timeout %ul.\n", timeout));
				return False;
			}
		} else {
			if (tdb_chainlock(tdb, kbuf) == -1) {
				DEBUG(0,("message_send_pid_internal: failed to get chainlock.\n"));
				return False;
			}
		}	
		tdb_append(tdb, kbuf, dbuf);
		tdb_chainunlock(tdb, kbuf);

		SAFE_FREE(dbuf.dptr);
		errno = 0;                    /* paranoia */
		return message_notify(pid);
	}

	/* lock the record for the destination */
	if (timeout) {
		if (tdb_chainlock_with_timeout(tdb, kbuf, timeout) == -1) {
			DEBUG(0,("message_send_pid_internal: failed to get chainlock with timeout %ul.\n", timeout));
			return False;
		}
	} else {
		if (tdb_chainlock(tdb, kbuf) == -1) {
			DEBUG(0,("message_send_pid_internal: failed to get chainlock.\n"));
			return False;
		}
	}	

	old_dbuf = tdb_fetch(tdb, kbuf);

	if (!old_dbuf.dptr) {
		/* its a new record */

		tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
		tdb_chainunlock(tdb, kbuf);

		SAFE_FREE(dbuf.dptr);
		errno = 0;                    /* paranoia */
		return message_notify(pid);
	}

	/* Not a new record. Check for duplicates. */

	for(ptr = (char *)old_dbuf.dptr; ptr < old_dbuf.dptr + old_dbuf.dsize; ) {
		/*
		 * First check if the message header matches, then, if it's a non-zero
		 * sized message, check if the data matches. If so it's a duplicate and
		 * we can discard it. JRA.
		 */

		if (!memcmp(ptr, &rec, sizeof(rec))) {
			if (!len || (len && !memcmp( ptr + sizeof(rec), buf, len))) {
				tdb_chainunlock(tdb, kbuf);
				DEBUG(10,("message_send_pid_internal: discarding duplicate message.\n"));
				SAFE_FREE(dbuf.dptr);
				SAFE_FREE(old_dbuf.dptr);
				return True;
			}
		}
		memcpy(&prec, ptr, sizeof(prec));
		ptr += sizeof(rec) + prec.len;
	}

	/* we're adding to an existing entry */

	tdb_append(tdb, kbuf, dbuf);
	tdb_chainunlock(tdb, kbuf);

	SAFE_FREE(old_dbuf.dptr);
	SAFE_FREE(dbuf.dptr);

	errno = 0;                    /* paranoia */
	return message_notify(pid);
}
Exemplo n.º 8
0
int main(int argc, char *argv[])
{
	unsigned int i, j, num = 1000, stage = 0, stopat = -1;
	int flags = TDB_DEFAULT;
	bool transaction = false;
	TDB_DATA key, data;
	struct tdb_context *tdb;
	struct timeval start, stop;
	union tdb_attribute seed, stats;

	/* Try to keep benchmarks even. */
	seed.base.attr = TDB_ATTRIBUTE_SEED;
	seed.base.next = NULL;
	seed.seed.seed = 0;

	memset(&stats, 0, sizeof(stats));
	stats.base.attr = TDB_ATTRIBUTE_STATS;
	stats.base.next = NULL;
	stats.stats.size = sizeof(stats);

	if (argv[1] && strcmp(argv[1], "--internal") == 0) {
		flags = TDB_INTERNAL;
		argc--;
		argv++;
	}
	if (argv[1] && strcmp(argv[1], "--transaction") == 0) {
		transaction = true;
		argc--;
		argv++;
	}
	if (argv[1] && strcmp(argv[1], "--stats") == 0) {
		seed.base.next = &stats;
		argc--;
		argv++;
	}

	tdb = tdb_open("/tmp/speed.tdb", flags, O_RDWR|O_CREAT|O_TRUNC,
		       0600, &seed);
	if (!tdb)
		err(1, "Opening /tmp/speed.tdb");

	key.dptr = (void *)&i;
	key.dsize = sizeof(i);
	data = key;

	if (argv[1]) {
		num = atoi(argv[1]);
		argv++;
		argc--;
	}

	if (argv[1]) {
		stopat = atoi(argv[1]);
		argv++;
		argc--;
	}

	if (transaction && tdb_transaction_start(tdb))
		errx(1, "starting transaction: %s", tdb_errorstr(tdb));

	/* Add 1000 records. */
	printf("Adding %u records: ", num); fflush(stdout);
	gettimeofday(&start, NULL);
	for (i = 0; i < num; i++)
		if (tdb_store(tdb, key, data, TDB_INSERT) != 0)
			errx(1, "Inserting key %u in tdb: %s",
			     i, tdb_errorstr(tdb));
	gettimeofday(&stop, NULL);
	if (transaction && tdb_transaction_commit(tdb))
		errx(1, "committing transaction: %s", tdb_errorstr(tdb));
	printf(" %zu ns (%zu bytes)\n",
	       normalize(&start, &stop, num), file_size());

	if (seed.base.next)
		dump_and_clear_stats(&stats.stats);
	if (++stage == stopat)
		exit(0);

	if (transaction && tdb_transaction_start(tdb))
		errx(1, "starting transaction: %s", tdb_errorstr(tdb));

	/* Finding 1000 records. */
	printf("Finding %u records: ", num); fflush(stdout);
	gettimeofday(&start, NULL);
	for (i = 0; i < num; i++) {
		int *dptr;
		dptr = (int *)tdb_fetch(tdb, key).dptr;
		if (!dptr || *dptr != i)
			errx(1, "Fetching key %u in tdb gave %u",
			     i, dptr ? *dptr : -1);
	}
	gettimeofday(&stop, NULL);
	if (transaction && tdb_transaction_commit(tdb))
		errx(1, "committing transaction: %s", tdb_errorstr(tdb));
	printf(" %zu ns (%zu bytes)\n",
	       normalize(&start, &stop, num), file_size());
	if (seed.base.next)
		dump_and_clear_stats(&stats.stats);
	if (++stage == stopat)
		exit(0);

	if (transaction && tdb_transaction_start(tdb))
		errx(1, "starting transaction: %s", tdb_errorstr(tdb));

	/* Missing 1000 records. */
	printf("Missing %u records: ", num); fflush(stdout);
	gettimeofday(&start, NULL);
	for (i = num; i < num*2; i++) {
		int *dptr;
		dptr = (int *)tdb_fetch(tdb, key).dptr;
		if (dptr)
			errx(1, "Fetching key %u in tdb gave %u", i, *dptr);
	}
	gettimeofday(&stop, NULL);
	if (transaction && tdb_transaction_commit(tdb))
		errx(1, "committing transaction: %s", tdb_errorstr(tdb));
	printf(" %zu ns (%zu bytes)\n",
	       normalize(&start, &stop, num), file_size());
	if (seed.base.next)
		dump_and_clear_stats(&stats.stats);
	if (++stage == stopat)
		exit(0);

	if (transaction && tdb_transaction_start(tdb))
		errx(1, "starting transaction: %s", tdb_errorstr(tdb));

	/* Traverse 1000 records. */
	printf("Traversing %u records: ", num); fflush(stdout);
	i = 0;
	gettimeofday(&start, NULL);
	if (tdb_traverse(tdb, count_record, &i) != num)
		errx(1, "Traverse returned wrong number of records");
	if (i != (num - 1) * (num / 2))
		errx(1, "Traverse tallied to %u", i);
	gettimeofday(&stop, NULL);
	if (transaction && tdb_transaction_commit(tdb))
		errx(1, "committing transaction: %s", tdb_errorstr(tdb));
	printf(" %zu ns (%zu bytes)\n",
	       normalize(&start, &stop, num), file_size());
	if (seed.base.next)
		dump_and_clear_stats(&stats.stats);
	if (++stage == stopat)
		exit(0);

	if (transaction && tdb_transaction_start(tdb))
		errx(1, "starting transaction: %s", tdb_errorstr(tdb));

	/* Delete 1000 records (not in order). */
	printf("Deleting %u records: ", num); fflush(stdout);
	gettimeofday(&start, NULL);
	for (j = 0; j < num; j++) {
		i = (j + 100003) % num;
		if (tdb_delete(tdb, key) != 0)
			errx(1, "Deleting key %u in tdb: %s",
			     i, tdb_errorstr(tdb));
	}
	gettimeofday(&stop, NULL);
	if (transaction && tdb_transaction_commit(tdb))
		errx(1, "committing transaction: %s", tdb_errorstr(tdb));
	printf(" %zu ns (%zu bytes)\n",
	       normalize(&start, &stop, num), file_size());
	if (seed.base.next)
		dump_and_clear_stats(&stats.stats);
	if (++stage == stopat)
		exit(0);

	if (transaction && tdb_transaction_start(tdb))
		errx(1, "starting transaction: %s", tdb_errorstr(tdb));

	/* Re-add 1000 records (not in order). */
	printf("Re-adding %u records: ", num); fflush(stdout);
	gettimeofday(&start, NULL);
	for (j = 0; j < num; j++) {
		i = (j + 100003) % num;
		if (tdb_store(tdb, key, data, TDB_INSERT) != 0)
			errx(1, "Inserting key %u in tdb: %s",
			     i, tdb_errorstr(tdb));
	}
	gettimeofday(&stop, NULL);
	if (transaction && tdb_transaction_commit(tdb))
		errx(1, "committing transaction: %s", tdb_errorstr(tdb));
	printf(" %zu ns (%zu bytes)\n",
	       normalize(&start, &stop, num), file_size());
	if (seed.base.next)
		dump_and_clear_stats(&stats.stats);
	if (++stage == stopat)
		exit(0);

	if (transaction && tdb_transaction_start(tdb))
		errx(1, "starting transaction: %s", tdb_errorstr(tdb));

	/* Append 1000 records. */
	printf("Appending %u records: ", num); fflush(stdout);
	gettimeofday(&start, NULL);
	for (i = 0; i < num; i++)
		if (tdb_append(tdb, key, data) != 0)
			errx(1, "Appending key %u in tdb: %s",
			     i, tdb_errorstr(tdb));
	gettimeofday(&stop, NULL);
	if (transaction && tdb_transaction_commit(tdb))
		errx(1, "committing transaction: %s", tdb_errorstr(tdb));
	printf(" %zu ns (%zu bytes)\n",
	       normalize(&start, &stop, num), file_size());
	if (++stage == stopat)
		exit(0);

	if (transaction && tdb_transaction_start(tdb))
		errx(1, "starting transaction: %s", tdb_errorstr(tdb));

	/* Churn 1000 records: not in order! */
	printf("Churning %u records: ", num); fflush(stdout);
	gettimeofday(&start, NULL);
	for (j = 0; j < num; j++) {
		i = (j + 1000019) % num;
		if (tdb_delete(tdb, key) != 0)
			errx(1, "Deleting key %u in tdb: %s",
			     i, tdb_errorstr(tdb));
		i += num;
		if (tdb_store(tdb, key, data, TDB_INSERT) != 0)
			errx(1, "Inserting key %u in tdb: %s",
			     i, tdb_errorstr(tdb));
	}
	gettimeofday(&stop, NULL);
	if (transaction && tdb_transaction_commit(tdb))
		errx(1, "committing transaction: %s", tdb_errorstr(tdb));
	printf(" %zu ns (%zu bytes)\n",
	       normalize(&start, &stop, num), file_size());

	if (seed.base.next)
		dump_and_clear_stats(&stats.stats);
	if (++stage == stopat)
		exit(0);

	return 0;
}
Exemplo n.º 9
0
int main(int argc, char *argv[])
{
	unsigned int i, j, moves;
	struct tdb_context *tdb;
	unsigned char *buffer;
	tdb_off_t oldoff = 0, newoff;
	int flags[] = { TDB_INTERNAL, TDB_DEFAULT, TDB_NOMMAP,
			TDB_INTERNAL|TDB_CONVERT, TDB_CONVERT, 
			TDB_NOMMAP|TDB_CONVERT };
	struct tdb_data key = { (unsigned char *)"key", 3 };
	struct tdb_data data;

	buffer = malloc(MAX_SIZE);
	for (i = 0; i < MAX_SIZE; i++)
		buffer[i] = i;

	plan_tests(sizeof(flags) / sizeof(flags[0])
		   * ((3 + MAX_SIZE/SIZE_STEP * 4) * 2 + 6)
		   + 1);

	/* Using tdb_store. */
	for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
		tdb = tdb_open("run-append.tdb", flags[i],
			       O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
		ok1(tdb);
		if (!tdb)
			continue;

		moves = 0;
		for (j = 0; j < MAX_SIZE; j += SIZE_STEP) {
			data.dptr = buffer;
			data.dsize = j;
			ok1(tdb_store(tdb, key, data, TDB_REPLACE) == 0);
			ok1(tdb_check(tdb, NULL, NULL) == 0);
			data = tdb_fetch(tdb, key);
			ok1(data.dsize == j);
			ok1(memcmp(data.dptr, buffer, data.dsize) == 0);
			free(data.dptr);
			newoff = tdb_offset(tdb, key);
			if (newoff != oldoff)
				moves++;
			oldoff = newoff;
		}
		ok1(tdb->allrecord_lock.count == 0 && tdb->num_lockrecs == 0);
		/* We should increase by 50% each time... */
		ok(moves <= ilog64(j / SIZE_STEP)*2, "Moved %u times", moves);
		tdb_close(tdb);
	}

	/* Using tdb_append. */
	for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
		size_t prev_len = 0;
		tdb = tdb_open("run-append.tdb", flags[i],
			       O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
		ok1(tdb);
		if (!tdb)
			continue;

		moves = 0;
		for (j = 0; j < MAX_SIZE; j += SIZE_STEP) {
			data.dptr = buffer + prev_len;
			data.dsize = j - prev_len;
			ok1(tdb_append(tdb, key, data) == 0);
			ok1(tdb_check(tdb, NULL, NULL) == 0);
			data = tdb_fetch(tdb, key);
			ok1(data.dsize == j);
			ok1(memcmp(data.dptr, buffer, data.dsize) == 0);
			free(data.dptr);
			prev_len = data.dsize;
			newoff = tdb_offset(tdb, key);
			if (newoff != oldoff)
				moves++;
			oldoff = newoff;
		}
		ok1(tdb->allrecord_lock.count == 0 && tdb->num_lockrecs == 0);
		/* We should increase by 50% each time... */
		ok(moves <= ilog64(j / SIZE_STEP)*2, "Moved %u times", moves);
		tdb_close(tdb);
	}

	for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
		tdb = tdb_open("run-append.tdb", flags[i],
			       O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
		ok1(tdb);
		if (!tdb)
			continue;

		/* Huge initial store. */
		data.dptr = buffer;
		data.dsize = MAX_SIZE;
		ok1(tdb_append(tdb, key, data) == 0);
		ok1(tdb_check(tdb, NULL, NULL) == 0);
		data = tdb_fetch(tdb, key);
		ok1(data.dsize == MAX_SIZE);
		ok1(memcmp(data.dptr, buffer, data.dsize) == 0);
		free(data.dptr);
		ok1(tdb->allrecord_lock.count == 0 && tdb->num_lockrecs == 0);
		tdb_close(tdb);
	}

	ok1(tap_log_messages == 0);
	return exit_status();
}