Example #1
0
File: obj.c Project: mattjakob/s3d
Object *obj_list_insert(Object *olist, Object *l)
{
  Object *t, *o = l;
  while (o != NULL) {
    t = o; o = o->next;
    olist = obj_insert(olist, t);
  }
  return olist;
}
static void time_obj_delpid(struct osd_device *osd, int numobj, int numiter)
{
	int ret = 0;
	int i = 0, j = 0;
	uint64_t start, end;
	double *t = 0;
	double mu, sd;

	t = Malloc(sizeof(*t) * numiter);
	if (!t)
		return;

	ret = obj_insert(osd->dbc, 1, 2, 128);
	assert(ret == 0);
	ret = obj_delete_pid(osd->dbc, 1);
	assert(ret == 0);

	for (i = 0; i < numiter; i++) {
		for (j = 0; j < numobj; j++) {
			ret = obj_insert(osd->dbc, 1, j, 128);
			assert(ret == 0);
		}

		rdtsc(start);
		ret = obj_delete_pid(osd->dbc, 1);
		rdtsc(end);
		assert(ret == 0);

		t[i] = (double) (end - start) / mhz;
		start = end = 0;
	}

	mu = mean(t, numiter);
	sd = stddev(t, mu, numiter);
	printf("%s numiter %d numobj %d avg %lf +- %lf us\n", __func__,
	       numiter, numobj, mu, sd); 
	free(t);
}
/*
 * test == 1: fetch oids
 * test == 2: fetch cids
 * test == 3: fetch pids
 * test == 4: fetch pids when each pid has some objs
 */
static void time_obj_fetch(struct osd_device *osd, int numobj, int numiter, 
			   int test)
{
	int ret = 0;
	int i = 0, j = 0, k = 0;
	uint64_t start, end;
	uint64_t *ids = NULL;
	uint64_t usedlen = 0, addlen = 0, contid = 0;
	int numpid = 0;
	uint8_t *cp = 0;
	double *t = 0;
	double mu, sd;
	const char *func = NULL;

	if (test < 1 || test > 4)
		return;

	t = Calloc(numiter, sizeof(*t));
	ids = Calloc(numobj, sizeof(*ids));
	if (!t || !ids)
		return;
	cp = (uint8_t *)ids;

	/* run pilot tests */
	switch (test) {
	case 1: {
		ret = obj_insert(osd->dbc, 20, 11, 128);
		assert(ret == 0);
		ret = obj_get_oids_in_pid(osd->dbc, 20, 0, sizeof(*ids)*1,
					  cp, &usedlen, &addlen, &contid);
		assert(ret == 0);
		assert(get_ntohll(cp) == 11);
		assert(usedlen == 8), usedlen = 0;
		assert(addlen == 8), addlen = 0;
		assert(contid == 0);
		ids[0] = 0;
		ret = obj_delete_pid(osd->dbc, 20);
		assert(ret == 0);
		func = "getoids";
		break;
	}
	case 2: {
		ret = obj_insert(osd->dbc, 20, 11, 64);
		assert(ret == 0);
		ret = obj_get_cids_in_pid(osd->dbc, 20, 0, sizeof(*ids)*1,
					  cp, &usedlen, &addlen, &contid);
		assert(ret == 0);
		assert(get_ntohll(cp) == 11);
		assert(usedlen == 8), usedlen = 0;
		assert(addlen == 8), addlen = 0;
		assert(contid == 0);
		ids[0] = 0;
		ret = obj_delete_pid(osd->dbc, 20);
		assert(ret == 0);
		func = "getcids";
		break;
	}
	case 3: 
	case 4: {
		ret = obj_insert(osd->dbc, 20, 0, 2);
		assert(ret == 0);
		ret = obj_insert(osd->dbc, 10, 0, 2);
		assert(ret == 0);
		ret = obj_get_all_pids(osd->dbc, 0, sizeof(*ids)*2, cp,
				       &usedlen, &addlen, &contid);
		assert(ret == 0);
		assert(get_ntohll(cp) == 20 || get_ntohll(cp) == 10);
		assert(get_ntohll(cp+8) == 20 || get_ntohll(cp+8) == 10);
		assert(usedlen == 2*sizeof(*ids));
		assert(addlen == usedlen);
		assert(contid == 0);
		ids[0] = ids[1] = 0;
		ret = obj_delete_pid(osd->dbc, 20);
		assert(ret == 0);
		ret = obj_delete_pid(osd->dbc, 10);
		assert(ret == 0);
		if (test == 3)
			func = "getpids";
		else
			func = "getfullpids";
		break;
	}
	default:
		fprintf(stderr, "1 <= test <= 4\n");
		exit(1);
	}

	for (i = 0; i < numiter; i++) {
		switch (test) {
		case 1: 
		case 2:
			{
			for (j = 0; j < numobj; j++) {
				if (test == 1) {
					ret = obj_insert(osd->dbc, 1, j, 
							 USEROBJECT);
				} else {
					ret = obj_insert(osd->dbc, 1, j, 
							 COLLECTION);
				}
				assert(ret == 0);
			}
			cp = (uint8_t *)ids;
			usedlen = addlen = contid = 0;
			if (test == 1) {
				rdtsc(start);
				ret = obj_get_oids_in_pid(osd->dbc, 1, 0, 
							  numobj*sizeof(*ids),
							  cp, &usedlen, 
							  &addlen, &contid);
				rdtsc(end);
			} else {
				rdtsc(start);
				ret = obj_get_cids_in_pid(osd->dbc, 1, 0, 
							  numobj*sizeof(*ids),
							  cp, &usedlen, 
							  &addlen, &contid);
				rdtsc(end);
			}
			assert(usedlen == numobj * sizeof(*ids));
			assert(addlen == usedlen);
			assert(contid == 0);
			ret = obj_delete_pid(osd->dbc, 1);
			assert(ret == 0);
			break;
			}
		case 3: 
			for (j = 0; j < numobj; j++) {
				ret = obj_insert(osd->dbc, j+1, 0, 
						 PARTITION);
				assert(ret == 0);
			}
			cp = (uint8_t *)ids;
			usedlen = addlen = contid = 0;
			rdtsc(start);
			ret = obj_get_all_pids(osd->dbc, 0, 
					       sizeof(*ids)*numobj, cp,
					       &usedlen, &addlen, &contid);
			rdtsc(end);
			assert(ret == 0);
			assert(usedlen == numobj*sizeof(*ids));
			assert(addlen == usedlen);
			assert(contid == 0);
			for (j = 0; j < numobj; j++) {
				ret = obj_delete_pid(osd->dbc, j+1);
				assert(ret == 0);
			}
		case 4: {
			numpid = numobj/32;
			if (numobj % 32 != 0)
				numpid++;
			for (j = 0; j < numpid; j++) {
				ret = obj_insert(osd->dbc, j+1, 0, PARTITION);
				assert(ret == 0);
				for (k = 1; k < 32+1; k++) {
					ret = obj_insert(osd->dbc, j+1, k, 
							 USEROBJECT);
					assert(ret == 0);
				}
			}
			cp = (uint8_t *)ids;
			usedlen = addlen = contid = 0;
			rdtsc(start);
			ret = obj_get_all_pids(osd->dbc, 0, 
					       sizeof(*ids)*numobj, cp,
					       &usedlen, &addlen, &contid);
			rdtsc(end);
			assert(ret == 0);
			assert(usedlen == numpid*sizeof(*ids));
			assert(addlen == usedlen);
			assert(contid == 0);
			for (j = 0; j < numpid; j++) {
				ret = obj_delete_pid(osd->dbc, j+1);
				assert(ret == 0);
			}
			numpid = 0;
			break;
		}
		default:
			fprintf(stderr, "1 <= test <= 4\n");
			exit(1);
		}

		t[i] = (double) (end - start) / mhz;
		start = end = 0;
	}

	mu = mean(t, numiter);
	sd = stddev(t, mu, numiter);
	printf("%s numiter %d numobj %d test, %d avg %lf +- %lf us\n", func,
	       numiter, numobj, test, mu, sd); 

	free(t);
	free(ids);
}
/*
 * test == 1: get next pid
 * test == 2: get next oid
 * test == 3: check existing obj
 * test == 4: check non existing obj
 * test == 5: check if pid empty
 * test == 6: get type
 */
static void time_obj_generic(struct osd_device *osd, int numobj, int numiter,
			     int test)
{
	int ret = 0;
	int i = 0, j = 0;
	uint64_t start, end;
	uint64_t oid = 0, pid = 0;
	int present = 0;
	int isempty = 0;
	uint8_t obj_type = ILLEGAL_OBJ;
	double *t = 0;
	double mu, sd;
	const char *func = NULL;

	if (test < 1 || test > 6)
		return;

	t = Malloc(sizeof(*t) * numiter);
	if (!t)
		return;

	/* run a pilot */
	switch (test) {
	case 1: {
		ret = obj_insert(osd->dbc, 20, 0, 2);
		assert(ret == 0);
		pid = 0;
		ret = obj_get_nextpid(osd->dbc, &pid);
		assert(ret == 0);
		assert(pid == 21);
		ret = obj_delete(osd->dbc, 20, 0);
		assert(ret == 0);
		func = "get_next_pid";
		break;
	}
	case 2: {
		ret = obj_insert(osd->dbc, 1, 2, 128);
		assert(ret == 0);
		oid = 0;
		ret = obj_get_nextoid(osd->dbc, 1, &oid);
		assert(ret == 0);
		assert(oid == 3);
		ret = obj_delete(osd->dbc, 1, 2);
		assert(ret == 0);
		func = "get_next_oid";
		break;
	}
	case 3: 
	case 4: {
		ret = obj_insert(osd->dbc, 1, 2, 128);
		assert(ret == 0);
		ret = obj_ispresent(osd->dbc, 1, 2, &present);
		assert(ret == 0 && present == 1);
		ret = obj_delete(osd->dbc, 1, 2);
		assert(ret == 0);
		ret = obj_ispresent(osd->dbc, 1, 2, &present);
		assert(ret == 0 && present == 0);
		if (test == 3)
			func = "objpresent";
		else
			func = "objnotpresent";
		break;
	}
	case 5: {
		ret = obj_insert(osd->dbc, 1, 2, 128);
		assert(ret == 0);
		ret = obj_isempty_pid(osd->dbc, 1, &isempty);
		assert(ret == 0 && isempty == 0);
		ret = obj_delete(osd->dbc, 1, 2);
		assert(ret == 0);
		ret = obj_isempty_pid(osd->dbc, 1, &isempty);
		assert(ret == 0 && isempty == 1);
		func = "objemptypid";
		break;
	}
	case 6: {
		ret = obj_insert(osd->dbc, 1, 2, USEROBJECT);
		assert(ret == 0);
		ret = obj_get_type(osd->dbc, 1, 2, &obj_type);
		assert(ret == 0 && obj_type == USEROBJECT);
		ret = obj_delete(osd->dbc, 1, 2);
		assert(ret == 0);
		func = "objgettype";
		break;
	}
	default:
		fprintf(stderr, "1 <= test <= 6\n");
		exit(1);
	}

	for (i = 0; i < numiter; i++) {
		for (j = 1; j < numobj+1; j++) {
			if (test == 1) {
				ret = obj_insert(osd->dbc, j, 0, PARTITION);
			} else {
				ret = obj_insert(osd->dbc, 1, j, USEROBJECT);
			}
			assert(ret == 0);
		}

		switch (test) {
		case 1: {
			pid = 0;
			rdtsc(start);
			ret = obj_get_nextpid(osd->dbc, &pid);
			rdtsc(end);
			assert(ret == 0);
			assert(pid == (uint64_t)(numobj+1));
			break;
		}
		case 2: {
			oid = 0;
			rdtsc(start);
			ret = obj_get_nextoid(osd->dbc, 1, &oid);
			rdtsc(end);
			assert(ret == 0);
			assert(oid == (uint64_t)(numobj+1));
			break;
		}
		case 3: {
			oid = numobj;
			rdtsc(start);
			ret = obj_ispresent(osd->dbc, 1, oid, &present);
			rdtsc(end);
			assert(ret == 0 && present == 1);
			break;
		}
		case 4: {
			oid = numobj+2;
			rdtsc(start);
			ret = obj_ispresent(osd->dbc, 1, oid, &present);
			rdtsc(end);
			assert(ret == 0 && present == 0);
			break;
		}
		case 5: {
			rdtsc(start);
			ret = obj_isempty_pid(osd->dbc, 1, &isempty);
			rdtsc(end);
			assert(ret == 0 && isempty == 0);
			break;
		}
		case 6: {
			oid = numobj;
			rdtsc(start);
			ret = obj_get_type(osd->dbc, 1, oid, &obj_type);
			rdtsc(end);
			assert(ret == 0 && obj_type == USEROBJECT);
			break;
		}
		default:
			fprintf(stderr, "1 <= test <= 6\n");
			exit(1);
		}

		t[i] = (double) (end - start) / mhz;
		start = end = 0;

		switch (test) {
		case 1: {
			for (j = 1; j < numobj+1; j++) {
				ret = obj_delete(osd->dbc, j, 0);
				assert(ret == 0);
			}
			break;
		}
		case 2:
		case 3:
		case 4:
		case 5:
		case 6: {
			ret = obj_delete_pid(osd->dbc, 1);
			assert(ret == 0);
			break;
		}
		default:
			fprintf(stderr, "1 <= test <= 6\n");
			exit(1);
		}
	}

	mu = mean(t, numiter);
	sd = stddev(t, mu, numiter);
	printf("%s numiter %d numobj %d test, %d avg %lf +- %lf us\n", func,
	       numiter, numobj, test, mu, sd); 
	free(t);
}