Hash :
0c468633
Author :
Date :
2013-03-14T13:40:15
Improved tree iterator internals This updates the tree iterator internals to be more efficient. The tree_iterator_entry objects are now kept as pointers that are allocated from a git_pool, so that we may use git__tsort_r for sorting (which is better than qsort, given that the tree is likely mostly ordered already). Those tree_iterator_entry objects now keep direct pointers to the data they refer to instead of keeping indirect index values. This simplifies a lot of the data structure traversal code. This also adds bsearch to find the start item position for range- limited tree iterators, and is more explicit about using git_path_cmp instead of reimplementing it. The git_path_cmp changed a bit to make it easier for tree_iterators to use it (but it was barely being used previously, so not a big deal). This adds a git_pool_free_array function that efficiently frees a list of pool allocated pointers (which the tree_iterator keeps). Also, added new tests for the git_pool free list functionality that was not previously being tested (or used).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
#include "clar_libgit2.h"
#include "pool.h"
#include "git2/oid.h"
void test_core_pool__0(void)
{
int i;
git_pool p;
void *ptr;
cl_git_pass(git_pool_init(&p, 1, 4000));
for (i = 1; i < 10000; i *= 2) {
ptr = git_pool_malloc(&p, i);
cl_assert(ptr != NULL);
cl_assert(git_pool__ptr_in_pool(&p, ptr));
cl_assert(!git_pool__ptr_in_pool(&p, &i));
}
/* 1+2+4+8+16+32+64+128+256+512+1024 -> original block */
/* 2048 -> 1 block */
/* 4096 -> 1 block */
/* 8192 -> 1 block */
cl_assert(git_pool__open_pages(&p) + git_pool__full_pages(&p) == 4);
git_pool_clear(&p);
}
void test_core_pool__1(void)
{
int i;
git_pool p;
cl_git_pass(git_pool_init(&p, 1, 4000));
for (i = 2010; i > 0; i--)
cl_assert(git_pool_malloc(&p, i) != NULL);
/* with fixed page size, allocation must end up with these values */
cl_assert(git_pool__open_pages(&p) == 1);
cl_assert(git_pool__full_pages(&p) == 505);
git_pool_clear(&p);
cl_git_pass(git_pool_init(&p, 1, 4100));
for (i = 2010; i > 0; i--)
cl_assert(git_pool_malloc(&p, i) != NULL);
/* with fixed page size, allocation must end up with these values */
cl_assert(git_pool__open_pages(&p) == 1);
cl_assert(git_pool__full_pages(&p) == 492);
git_pool_clear(&p);
}
static char to_hex[] = "0123456789abcdef";
void test_core_pool__2(void)
{
git_pool p;
char oid_hex[GIT_OID_HEXSZ];
git_oid *oid;
int i, j;
memset(oid_hex, '0', sizeof(oid_hex));
cl_git_pass(git_pool_init(&p, sizeof(git_oid), 100));
for (i = 1000; i < 10000; i++) {
oid = git_pool_malloc(&p, 1);
cl_assert(oid != NULL);
for (j = 0; j < 8; j++)
oid_hex[j] = to_hex[(i >> (4 * j)) & 0x0f];
cl_git_pass(git_oid_fromstr(oid, oid_hex));
}
/* with fixed page size, allocation must end up with these values */
cl_assert(git_pool__open_pages(&p) == 0);
cl_assert(git_pool__full_pages(&p) == 90);
git_pool_clear(&p);
}
void test_core_pool__free_list(void)
{
int i;
git_pool p;
void *ptr, *ptrs[50];
cl_git_pass(git_pool_init(&p, 100, 100));
for (i = 0; i < 10; ++i) {
ptr = git_pool_malloc(&p, 1);
cl_assert(ptr != NULL);
}
cl_assert_equal_i(10, (int)p.items);
for (i = 0; i < 50; ++i) {
ptrs[i] = git_pool_malloc(&p, 1);
cl_assert(ptrs[i] != NULL);
}
cl_assert_equal_i(60, (int)p.items);
git_pool_free(&p, ptr);
cl_assert_equal_i(60, (int)p.items);
git_pool_free_array(&p, 50, ptrs);
cl_assert_equal_i(60, (int)p.items);
for (i = 0; i < 50; ++i) {
ptrs[i] = git_pool_malloc(&p, 1);
cl_assert(ptrs[i] != NULL);
}
cl_assert_equal_i(60, (int)p.items);
for (i = 0; i < 111; ++i) {
ptr = git_pool_malloc(&p, 1);
cl_assert(ptr != NULL);
}
cl_assert_equal_i(170, (int)p.items);
git_pool_free_array(&p, 50, ptrs);
cl_assert_equal_i(170, (int)p.items);
for (i = 0; i < 50; ++i) {
ptrs[i] = git_pool_malloc(&p, 1);
cl_assert(ptrs[i] != NULL);
}
cl_assert_equal_i(170, (int)p.items);
git_pool_clear(&p);
}