cache.c 7.27 KB
Newer Older
1 2 3 4
#include "clar_libgit2.h"
#include "repository.h"

static git_repository *g_repo;
5 6
static size_t cache_limit;
static int object_type;
7

8
void test_object_cache__initialize_cache_no_blobs(void)
9
{
Russell Belfer committed
10
	g_repo = NULL;
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
	object_type = GIT_OBJECT_BLOB;
	cache_limit = 0;
}

void test_object_cache__initialize_cache_tiny_blobs(void)
{
	g_repo = NULL;
	object_type = GIT_OBJECT_BLOB;
	cache_limit = 10;
}

void test_object_cache__initialize_cache_all_blobs(void)
{
	g_repo = NULL;
	object_type = GIT_OBJECT_BLOB;
	cache_limit = 32767;
}

void test_object_cache__initialize_cache_no_trees(void)
{
	g_repo = NULL;
	object_type = GIT_OBJECT_TREE;
	cache_limit = 0;
34 35 36 37 38 39 40
}

void test_object_cache__cleanup(void)
{
	git_repository_free(g_repo);
	g_repo = NULL;

41
	git_libgit2_opts(GIT_OPT_SET_CACHE_OBJECT_LIMIT, (int)GIT_OBJECT_BLOB, (size_t)0);
42 43
	git_libgit2_opts(GIT_OPT_SET_CACHE_OBJECT_LIMIT, (int)GIT_OBJECT_TREE, (size_t)4096);
	git_libgit2_opts(GIT_OPT_SET_CACHE_OBJECT_LIMIT, (int)GIT_OBJECT_COMMIT, (size_t)4096);
44 45 46
}

static struct {
47
	git_object_t type;
48
	const char *sha;
49
	size_t size;
50 51
} g_data[] = {
	/* HEAD */
52 53 54
	{ GIT_OBJECT_BLOB, "a8233120f6ad708f843d861ce2b7228ec4e3dec6", 10 }, /* README */
	{ GIT_OBJECT_BLOB, "3697d64be941a53d4ae8f6a271e4e3fa56b022cc",  8 }, /* branch_file.txt */
	{ GIT_OBJECT_BLOB, "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd", 12 }, /* new.txt */
55 56

	/* refs/heads/subtrees */
57 58 59 60 61 62 63 64 65 66 67
	{ GIT_OBJECT_BLOB, "1385f264afb75a56a5bec74243be9b367ba4ca08",  4 }, /* README */
	{ GIT_OBJECT_TREE, "f1425cef211cc08caa31e7b545ffb232acb098c3", 90 }, /* ab */
	{ GIT_OBJECT_BLOB, "d6c93164c249c8000205dd4ec5cbca1b516d487f",  6 }, /* ab/4.txt */
	{ GIT_OBJECT_TREE, "9a03079b8a8ee85a0bee58bf9be3da8b62414ed4", 33 }, /* ab/c */
	{ GIT_OBJECT_BLOB, "270b8ea76056d5cad83af921837702d3e3c2924d",  6 }, /* ab/c/3.txt */
	{ GIT_OBJECT_TREE, "b6361fc6a97178d8fc8639fdeed71c775ab52593", 63 }, /* ab/de */
	{ GIT_OBJECT_BLOB, "e7b4ad382349ff96dd8199000580b9b1e2042eb0",  6 }, /* ab/de/2.txt */
	{ GIT_OBJECT_TREE, "3259a6bd5b57fb9c1281bb7ed3167b50f224cb54", 33 }, /* ab/de/fgh */
	{ GIT_OBJECT_BLOB, "1f67fc4386b2d171e0d21be1c447e12660561f9b",  6 }, /* ab/de/fgh/1.txt */
	{ GIT_OBJECT_BLOB, "45b983be36b73c0788dc9cbcb76cbb80fc7bb057",  3 }, /* branch_file.txt */
	{ GIT_OBJECT_BLOB, "fa49b077972391ad58037050f2a75f74e3671e92",  9 }, /* new.txt */
68 69

	/* refs/heads/chomped */
70
	{ GIT_OBJECT_BLOB, "0266163a49e280c4f5ed1e08facd36a2bd716bcf", 51 }, /* readme.txt */
71

72 73
	{ 0, NULL, 0 },
	{ 0, NULL, 0 }
74 75
};

76
void test_object_cache__cache_counts(void)
77
{
78
	int i, start, nonmatching = 0;
79 80 81 82 83
	git_oid oid;
	git_odb_object *odb_obj;
	git_object *obj;
	git_odb *odb;

84
	git_libgit2_opts(GIT_OPT_SET_CACHE_OBJECT_LIMIT, object_type, cache_limit);
85

Russell Belfer committed
86
	cl_git_pass(git_repository_open(&g_repo, cl_fixture("testrepo.git")));
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
	cl_git_pass(git_repository_odb(&odb, g_repo));

	start = (int)git_cache_size(&g_repo->objects);

	for (i = 0; g_data[i].sha != NULL; ++i) {
		int count = (int)git_cache_size(&g_repo->objects);

		cl_git_pass(git_oid_fromstr(&oid, g_data[i].sha));

		/* alternate between loading raw and parsed objects */
		if ((i & 1) == 0) {
			cl_git_pass(git_odb_read(&odb_obj, odb, &oid));
			cl_assert(g_data[i].type == git_odb_object_type(odb_obj));
			git_odb_object_free(odb_obj);
		} else {
102
			cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJECT_ANY));
103 104 105 106
			cl_assert(g_data[i].type == git_object_type(obj));
			git_object_free(obj);
		}

107 108 109 110 111 112 113
		if ((g_data[i].type == object_type && g_data[i].size >= cache_limit) ||
		    (g_data[i].type != object_type && g_data[i].type == GIT_OBJECT_BLOB))
			cl_assert_equal_i(count, (int)git_cache_size(&g_repo->objects));
		else {
			cl_assert_equal_i(count + 1, (int)git_cache_size(&g_repo->objects));
			nonmatching++;
		}
114 115
	}

116
	cl_assert_equal_i(nonmatching, (int)git_cache_size(&g_repo->objects) - start);
117 118 119 120 121

	for (i = 0; g_data[i].sha != NULL; ++i) {
		int count = (int)git_cache_size(&g_repo->objects);

		cl_git_pass(git_oid_fromstr(&oid, g_data[i].sha));
122
		cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJECT_ANY));
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
		cl_assert(g_data[i].type == git_object_type(obj));
		git_object_free(obj);

		cl_assert_equal_i(count, (int)git_cache_size(&g_repo->objects));
	}

	git_odb_free(odb);
}

static void *cache_parsed(void *arg)
{
	int i;
	git_oid oid;
	git_object *obj;

	for (i = ((int *)arg)[1]; g_data[i].sha != NULL; i += 2) {
		cl_git_pass(git_oid_fromstr(&oid, g_data[i].sha));
140
		cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJECT_ANY));
141 142 143 144 145 146
		cl_assert(g_data[i].type == git_object_type(obj));
		git_object_free(obj);
	}

	for (i = 0; i < ((int *)arg)[1]; i += 2) {
		cl_git_pass(git_oid_fromstr(&oid, g_data[i].sha));
147
		cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJECT_ANY));
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
		cl_assert(g_data[i].type == git_object_type(obj));
		git_object_free(obj);
	}

	return arg;
}

static void *cache_raw(void *arg)
{
	int i;
	git_oid oid;
	git_odb *odb;
	git_odb_object *odb_obj;

	cl_git_pass(git_repository_odb(&odb, g_repo));

	for (i = ((int *)arg)[1]; g_data[i].sha != NULL; i += 2) {
		cl_git_pass(git_oid_fromstr(&oid, g_data[i].sha));
		cl_git_pass(git_odb_read(&odb_obj, odb, &oid));
		cl_assert(g_data[i].type == git_odb_object_type(odb_obj));
		git_odb_object_free(odb_obj);
	}

	for (i = 0; i < ((int *)arg)[1]; i += 2) {
		cl_git_pass(git_oid_fromstr(&oid, g_data[i].sha));
		cl_git_pass(git_odb_read(&odb_obj, odb, &oid));
		cl_assert(g_data[i].type == git_odb_object_type(odb_obj));
		git_odb_object_free(odb_obj);
	}

	git_odb_free(odb);

	return arg;
}

Russell Belfer committed
183 184
#define REPEAT 20
#define THREADCOUNT 50
185 186 187 188 189 190 191

void test_object_cache__threadmania(void)
{
	int try, th, max_i;
	void *data;
	void *(*fn)(void *);

192 193 194 195
#ifdef GIT_THREADS
	git_thread t[THREADCOUNT];
#endif

196 197 198 199 200
	for (max_i = 0; g_data[max_i].sha != NULL; ++max_i)
		/* count up */;

	for (try = 0; try < REPEAT; ++try) {

Russell Belfer committed
201 202
		cl_git_pass(git_repository_open(&g_repo, cl_fixture("testrepo.git")));

203 204 205 206 207 208 209 210 211
		for (th = 0; th < THREADCOUNT; ++th) {
			data = git__malloc(2 * sizeof(int));

			((int *)data)[0] = th;
			((int *)data)[1] = th % max_i;

			fn = (th & 1) ? cache_parsed : cache_raw;

#ifdef GIT_THREADS
212
			cl_git_pass(git_thread_create(&t[th], fn, data));
213
#else
214
			cl_assert(fn(data) == data);
215 216 217 218 219 220
			git__free(data);
#endif
		}

#ifdef GIT_THREADS
		for (th = 0; th < THREADCOUNT; ++th) {
221
			cl_git_pass(git_thread_join(&t[th], &data));
222 223 224 225 226
			cl_assert_equal_i(th, ((int *)data)[0]);
			git__free(data);
		}
#endif

Russell Belfer committed
227 228 229 230 231 232 233 234 235 236 237
		git_repository_free(g_repo);
		g_repo = NULL;
	}
}

static void *cache_quick(void *arg)
{
	git_oid oid;
	git_object *obj;

	cl_git_pass(git_oid_fromstr(&oid, g_data[4].sha));
238
	cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJECT_ANY));
Russell Belfer committed
239 240 241 242 243 244 245 246
	cl_assert(g_data[4].type == git_object_type(obj));
	git_object_free(obj);

	return arg;
}

void test_object_cache__fast_thread_rush(void)
{
247
	int try, th, data[THREADCOUNT];
Russell Belfer committed
248
#ifdef GIT_THREADS
249
	git_thread t[THREADCOUNT];
Russell Belfer committed
250 251 252 253 254
#endif

	for (try = 0; try < REPEAT; ++try) {
		cl_git_pass(git_repository_open(&g_repo, cl_fixture("testrepo.git")));

255
		for (th = 0; th < THREADCOUNT; ++th) {
Russell Belfer committed
256 257 258
			data[th] = th;
#ifdef GIT_THREADS
			cl_git_pass(
259
				git_thread_create(&t[th], cache_quick, &data[th]));
Russell Belfer committed
260 261 262 263 264 265
#else
			cl_assert(cache_quick(&data[th]) == &data[th]);
#endif
		}

#ifdef GIT_THREADS
266
		for (th = 0; th < THREADCOUNT; ++th) {
Russell Belfer committed
267
			void *rval;
268
			cl_git_pass(git_thread_join(&t[th], &rval));
Russell Belfer committed
269 270 271 272 273 274
			cl_assert_equal_i(th, *((int *)rval));
		}
#endif

		git_repository_free(g_repo);
		g_repo = NULL;
275 276
	}
}