Merge branch 'pw/xdiff-alloc'
Add a level of redirection to array allocation API in xdiff part, to make it easier to share with the libgit2 project. * pw/xdiff-alloc: xdiff: introduce XDL_ALLOC_GROW() xdiff: introduce XDL_CALLOC_ARRAY() xdiff: introduce xdl_calloc xdiff: introduce XDL_ALLOC_ARRAY()
This commit is contained in:
@ -120,6 +120,7 @@ typedef struct s_bdiffparam {
|
|||||||
|
|
||||||
|
|
||||||
#define xdl_malloc(x) xmalloc(x)
|
#define xdl_malloc(x) xmalloc(x)
|
||||||
|
#define xdl_calloc(n, sz) xcalloc(n, sz)
|
||||||
#define xdl_free(ptr) free(ptr)
|
#define xdl_free(ptr) free(ptr)
|
||||||
#define xdl_realloc(ptr,x) xrealloc(ptr,x)
|
#define xdl_realloc(ptr,x) xrealloc(ptr,x)
|
||||||
|
|
||||||
|
@ -337,7 +337,7 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
|
|||||||
* One is to store the forward path and one to store the backward path.
|
* One is to store the forward path and one to store the backward path.
|
||||||
*/
|
*/
|
||||||
ndiags = xe->xdf1.nreff + xe->xdf2.nreff + 3;
|
ndiags = xe->xdf1.nreff + xe->xdf2.nreff + 3;
|
||||||
if (!(kvd = (long *) xdl_malloc((2 * ndiags + 2) * sizeof(long)))) {
|
if (!XDL_ALLOC_ARRAY(kvd, 2 * ndiags + 2)) {
|
||||||
|
|
||||||
xdl_free_env(xe);
|
xdl_free_env(xe);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -251,7 +251,7 @@ static int find_lcs(xpparam_t const *xpp, xdfenv_t *env,
|
|||||||
int line1, int count1, int line2, int count2)
|
int line1, int count1, int line2, int count2)
|
||||||
{
|
{
|
||||||
int b_ptr;
|
int b_ptr;
|
||||||
int sz, ret = -1;
|
int ret = -1;
|
||||||
struct histindex index;
|
struct histindex index;
|
||||||
|
|
||||||
memset(&index, 0, sizeof(index));
|
memset(&index, 0, sizeof(index));
|
||||||
@ -265,23 +265,16 @@ static int find_lcs(xpparam_t const *xpp, xdfenv_t *env,
|
|||||||
index.rcha.head = NULL;
|
index.rcha.head = NULL;
|
||||||
|
|
||||||
index.table_bits = xdl_hashbits(count1);
|
index.table_bits = xdl_hashbits(count1);
|
||||||
sz = index.records_size = 1 << index.table_bits;
|
index.records_size = 1 << index.table_bits;
|
||||||
sz *= sizeof(struct record *);
|
if (!XDL_CALLOC_ARRAY(index.records, index.records_size))
|
||||||
if (!(index.records = (struct record **) xdl_malloc(sz)))
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
memset(index.records, 0, sz);
|
|
||||||
|
|
||||||
sz = index.line_map_size = count1;
|
index.line_map_size = count1;
|
||||||
sz *= sizeof(struct record *);
|
if (!XDL_CALLOC_ARRAY(index.line_map, index.line_map_size))
|
||||||
if (!(index.line_map = (struct record **) xdl_malloc(sz)))
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
memset(index.line_map, 0, sz);
|
|
||||||
|
|
||||||
sz = index.line_map_size;
|
if (!XDL_CALLOC_ARRAY(index.next_ptrs, index.line_map_size))
|
||||||
sz *= sizeof(unsigned int);
|
|
||||||
if (!(index.next_ptrs = (unsigned int *) xdl_malloc(sz)))
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
memset(index.next_ptrs, 0, sz);
|
|
||||||
|
|
||||||
/* lines / 4 + 1 comes from xprepare.c:xdl_prepare_ctx() */
|
/* lines / 4 + 1 comes from xprepare.c:xdl_prepare_ctx() */
|
||||||
if (xdl_cha_init(&index.rcha, sizeof(struct record), count1 / 4 + 1) < 0)
|
if (xdl_cha_init(&index.rcha, sizeof(struct record), count1 / 4 + 1) < 0)
|
||||||
|
@ -49,5 +49,23 @@ do { \
|
|||||||
((unsigned long) __p[2]) << 16 | ((unsigned long) __p[3]) << 24; \
|
((unsigned long) __p[2]) << 16 | ((unsigned long) __p[3]) << 24; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
/* Allocate an array of nr elements, returns NULL on failure */
|
||||||
|
#define XDL_ALLOC_ARRAY(p, nr) \
|
||||||
|
((p) = SIZE_MAX / sizeof(*(p)) >= (size_t)(nr) \
|
||||||
|
? xdl_malloc((nr) * sizeof(*(p))) \
|
||||||
|
: NULL)
|
||||||
|
|
||||||
|
/* Allocate an array of nr zeroed out elements, returns NULL on failure */
|
||||||
|
#define XDL_CALLOC_ARRAY(p, nr) ((p) = xdl_calloc(nr, sizeof(*(p))))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensure array p can accommodate at least nr elements, growing the
|
||||||
|
* array and updating alloc (which is the number of allocated
|
||||||
|
* elements) as necessary. Frees p and returns -1 on failure, returns
|
||||||
|
* 0 on success
|
||||||
|
*/
|
||||||
|
#define XDL_ALLOC_GROW(p, nr, alloc) \
|
||||||
|
(-!((nr) <= (alloc) || \
|
||||||
|
((p) = xdl_alloc_grow_helper((p), (nr), &(alloc), sizeof(*(p))))))
|
||||||
|
|
||||||
#endif /* #if !defined(XMACROS_H) */
|
#endif /* #if !defined(XMACROS_H) */
|
||||||
|
@ -151,11 +151,8 @@ static int fill_hashmap(mmfile_t *file1, mmfile_t *file2,
|
|||||||
|
|
||||||
/* We know exactly how large we want the hash map */
|
/* We know exactly how large we want the hash map */
|
||||||
result->alloc = count1 * 2;
|
result->alloc = count1 * 2;
|
||||||
result->entries = (struct entry *)
|
if (!XDL_CALLOC_ARRAY(result->entries, result->alloc))
|
||||||
xdl_malloc(result->alloc * sizeof(struct entry));
|
|
||||||
if (!result->entries)
|
|
||||||
return -1;
|
return -1;
|
||||||
memset(result->entries, 0, result->alloc * sizeof(struct entry));
|
|
||||||
|
|
||||||
/* First, fill with entries from the first file */
|
/* First, fill with entries from the first file */
|
||||||
while (count1--)
|
while (count1--)
|
||||||
@ -200,7 +197,7 @@ static int binary_search(struct entry **sequence, int longest,
|
|||||||
*/
|
*/
|
||||||
static int find_longest_common_sequence(struct hashmap *map, struct entry **res)
|
static int find_longest_common_sequence(struct hashmap *map, struct entry **res)
|
||||||
{
|
{
|
||||||
struct entry **sequence = xdl_malloc(map->nr * sizeof(struct entry *));
|
struct entry **sequence;
|
||||||
int longest = 0, i;
|
int longest = 0, i;
|
||||||
struct entry *entry;
|
struct entry *entry;
|
||||||
|
|
||||||
@ -211,7 +208,7 @@ static int find_longest_common_sequence(struct hashmap *map, struct entry **res)
|
|||||||
*/
|
*/
|
||||||
int anchor_i = -1;
|
int anchor_i = -1;
|
||||||
|
|
||||||
if (!sequence)
|
if (!XDL_ALLOC_ARRAY(sequence, map->nr))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
for (entry = map->first; entry; entry = entry->next) {
|
for (entry = map->first; entry; entry = entry->next) {
|
||||||
|
@ -78,15 +78,14 @@ static int xdl_init_classifier(xdlclassifier_t *cf, long size, long flags) {
|
|||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (!(cf->rchash = (xdlclass_t **) xdl_malloc(cf->hsize * sizeof(xdlclass_t *)))) {
|
if (!XDL_CALLOC_ARRAY(cf->rchash, cf->hsize)) {
|
||||||
|
|
||||||
xdl_cha_free(&cf->ncha);
|
xdl_cha_free(&cf->ncha);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memset(cf->rchash, 0, cf->hsize * sizeof(xdlclass_t *));
|
|
||||||
|
|
||||||
cf->alloc = size;
|
cf->alloc = size;
|
||||||
if (!(cf->rcrecs = (xdlclass_t **) xdl_malloc(cf->alloc * sizeof(xdlclass_t *)))) {
|
if (!XDL_ALLOC_ARRAY(cf->rcrecs, cf->alloc)) {
|
||||||
|
|
||||||
xdl_free(cf->rchash);
|
xdl_free(cf->rchash);
|
||||||
xdl_cha_free(&cf->ncha);
|
xdl_cha_free(&cf->ncha);
|
||||||
@ -112,7 +111,6 @@ static int xdl_classify_record(unsigned int pass, xdlclassifier_t *cf, xrecord_t
|
|||||||
long hi;
|
long hi;
|
||||||
char const *line;
|
char const *line;
|
||||||
xdlclass_t *rcrec;
|
xdlclass_t *rcrec;
|
||||||
xdlclass_t **rcrecs;
|
|
||||||
|
|
||||||
line = rec->ptr;
|
line = rec->ptr;
|
||||||
hi = (long) XDL_HASHLONG(rec->ha, cf->hbits);
|
hi = (long) XDL_HASHLONG(rec->ha, cf->hbits);
|
||||||
@ -128,14 +126,8 @@ static int xdl_classify_record(unsigned int pass, xdlclassifier_t *cf, xrecord_t
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
rcrec->idx = cf->count++;
|
rcrec->idx = cf->count++;
|
||||||
if (cf->count > cf->alloc) {
|
if (XDL_ALLOC_GROW(cf->rcrecs, cf->count, cf->alloc))
|
||||||
cf->alloc *= 2;
|
|
||||||
if (!(rcrecs = (xdlclass_t **) xdl_realloc(cf->rcrecs, cf->alloc * sizeof(xdlclass_t *)))) {
|
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
cf->rcrecs = rcrecs;
|
|
||||||
}
|
|
||||||
cf->rcrecs[rcrec->idx] = rcrec;
|
cf->rcrecs[rcrec->idx] = rcrec;
|
||||||
rcrec->line = line;
|
rcrec->line = line;
|
||||||
rcrec->size = rec->size;
|
rcrec->size = rec->size;
|
||||||
@ -164,7 +156,7 @@ static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_
|
|||||||
unsigned long hav;
|
unsigned long hav;
|
||||||
char const *blk, *cur, *top, *prev;
|
char const *blk, *cur, *top, *prev;
|
||||||
xrecord_t *crec;
|
xrecord_t *crec;
|
||||||
xrecord_t **recs, **rrecs;
|
xrecord_t **recs;
|
||||||
xrecord_t **rhash;
|
xrecord_t **rhash;
|
||||||
unsigned long *ha;
|
unsigned long *ha;
|
||||||
char *rchg;
|
char *rchg;
|
||||||
@ -178,26 +170,21 @@ static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_
|
|||||||
|
|
||||||
if (xdl_cha_init(&xdf->rcha, sizeof(xrecord_t), narec / 4 + 1) < 0)
|
if (xdl_cha_init(&xdf->rcha, sizeof(xrecord_t), narec / 4 + 1) < 0)
|
||||||
goto abort;
|
goto abort;
|
||||||
if (!(recs = (xrecord_t **) xdl_malloc(narec * sizeof(xrecord_t *))))
|
if (!XDL_ALLOC_ARRAY(recs, narec))
|
||||||
goto abort;
|
goto abort;
|
||||||
|
|
||||||
hbits = xdl_hashbits((unsigned int) narec);
|
hbits = xdl_hashbits((unsigned int) narec);
|
||||||
hsize = 1 << hbits;
|
hsize = 1 << hbits;
|
||||||
if (!(rhash = (xrecord_t **) xdl_malloc(hsize * sizeof(xrecord_t *))))
|
if (!XDL_CALLOC_ARRAY(rhash, hsize))
|
||||||
goto abort;
|
goto abort;
|
||||||
memset(rhash, 0, hsize * sizeof(xrecord_t *));
|
|
||||||
|
|
||||||
nrec = 0;
|
nrec = 0;
|
||||||
if ((cur = blk = xdl_mmfile_first(mf, &bsize))) {
|
if ((cur = blk = xdl_mmfile_first(mf, &bsize))) {
|
||||||
for (top = blk + bsize; cur < top; ) {
|
for (top = blk + bsize; cur < top; ) {
|
||||||
prev = cur;
|
prev = cur;
|
||||||
hav = xdl_hash_record(&cur, top, xpp->flags);
|
hav = xdl_hash_record(&cur, top, xpp->flags);
|
||||||
if (nrec >= narec) {
|
if (XDL_ALLOC_GROW(recs, nrec + 1, narec))
|
||||||
narec *= 2;
|
goto abort;
|
||||||
if (!(rrecs = (xrecord_t **) xdl_realloc(recs, narec * sizeof(xrecord_t *))))
|
|
||||||
goto abort;
|
|
||||||
recs = rrecs;
|
|
||||||
}
|
|
||||||
if (!(crec = xdl_cha_alloc(&xdf->rcha)))
|
if (!(crec = xdl_cha_alloc(&xdf->rcha)))
|
||||||
goto abort;
|
goto abort;
|
||||||
crec->ptr = prev;
|
crec->ptr = prev;
|
||||||
@ -209,15 +196,14 @@ static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(rchg = (char *) xdl_malloc((nrec + 2) * sizeof(char))))
|
if (!XDL_CALLOC_ARRAY(rchg, nrec + 2))
|
||||||
goto abort;
|
goto abort;
|
||||||
memset(rchg, 0, (nrec + 2) * sizeof(char));
|
|
||||||
|
|
||||||
if ((XDF_DIFF_ALG(xpp->flags) != XDF_PATIENCE_DIFF) &&
|
if ((XDF_DIFF_ALG(xpp->flags) != XDF_PATIENCE_DIFF) &&
|
||||||
(XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF)) {
|
(XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF)) {
|
||||||
if (!(rindex = xdl_malloc((nrec + 1) * sizeof(*rindex))))
|
if (!XDL_ALLOC_ARRAY(rindex, nrec + 1))
|
||||||
goto abort;
|
goto abort;
|
||||||
if (!(ha = xdl_malloc((nrec + 1) * sizeof(*ha))))
|
if (!XDL_ALLOC_ARRAY(ha, nrec + 1))
|
||||||
goto abort;
|
goto abort;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,11 +369,8 @@ static int xdl_cleanup_records(xdlclassifier_t *cf, xdfile_t *xdf1, xdfile_t *xd
|
|||||||
xdlclass_t *rcrec;
|
xdlclass_t *rcrec;
|
||||||
char *dis, *dis1, *dis2;
|
char *dis, *dis1, *dis2;
|
||||||
|
|
||||||
if (!(dis = (char *) xdl_malloc(xdf1->nrec + xdf2->nrec + 2))) {
|
if (!XDL_CALLOC_ARRAY(dis, xdf1->nrec + xdf2->nrec + 2))
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
memset(dis, 0, xdf1->nrec + xdf2->nrec + 2);
|
|
||||||
dis1 = dis;
|
dis1 = dis;
|
||||||
dis2 = dis1 + xdf1->nrec + 1;
|
dis2 = dis1 + xdf1->nrec + 1;
|
||||||
|
|
||||||
|
@ -432,3 +432,20 @@ int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* xdl_alloc_grow_helper(void *p, long nr, long *alloc, size_t size)
|
||||||
|
{
|
||||||
|
void *tmp = NULL;
|
||||||
|
size_t n = ((LONG_MAX - 16) / 2 >= *alloc) ? 2 * *alloc + 16 : LONG_MAX;
|
||||||
|
if (nr > n)
|
||||||
|
n = nr;
|
||||||
|
if (SIZE_MAX / size >= n)
|
||||||
|
tmp = xdl_realloc(p, n * size);
|
||||||
|
if (tmp) {
|
||||||
|
*alloc = n;
|
||||||
|
} else {
|
||||||
|
xdl_free(p);
|
||||||
|
*alloc = 0;
|
||||||
|
}
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
@ -42,6 +42,7 @@ int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,
|
|||||||
int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp,
|
int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp,
|
||||||
int line1, int count1, int line2, int count2);
|
int line1, int count1, int line2, int count2);
|
||||||
|
|
||||||
|
/* Do not call this function, use XDL_ALLOC_GROW instead */
|
||||||
|
void* xdl_alloc_grow_helper(void* p, long nr, long* alloc, size_t size);
|
||||||
|
|
||||||
#endif /* #if !defined(XUTILS_H) */
|
#endif /* #if !defined(XUTILS_H) */
|
||||||
|
Reference in New Issue
Block a user