Example #1
0
int xdl_merge(mmfile_t *orig, mmfile_t *mf1, mmfile_t *mf2,
		xmparam_t const *xmp, mmbuffer_t *result)
{
	xdchange_t *xscr1, *xscr2;
	xdfenv_t xe1, xe2;
	int status;
	xpparam_t const *xpp = &xmp->xpp;

	result->ptr = NULL;
	result->size = 0;

	if (xdl_do_diff(orig, mf1, xpp, &xe1) < 0) {
		return -1;
	}
	if (xdl_do_diff(orig, mf2, xpp, &xe2) < 0) {
		xdl_free_env(&xe1);
		return -1;
	}
	if (xdl_change_compact(&xe1.xdf1, &xe1.xdf2, xpp->flags) < 0 ||
	    xdl_change_compact(&xe1.xdf2, &xe1.xdf1, xpp->flags) < 0 ||
	    xdl_build_script(&xe1, &xscr1) < 0) {
		xdl_free_env(&xe1);
		return -1;
	}
	if (xdl_change_compact(&xe2.xdf1, &xe2.xdf2, xpp->flags) < 0 ||
	    xdl_change_compact(&xe2.xdf2, &xe2.xdf1, xpp->flags) < 0 ||
	    xdl_build_script(&xe2, &xscr2) < 0) {
		xdl_free_script(xscr1);
		xdl_free_env(&xe1);
		xdl_free_env(&xe2);
		return -1;
	}
	status = 0;
	if (!xscr1) {
		result->ptr = xdl_malloc(mf2->size);
		memcpy(result->ptr, mf2->ptr, mf2->size);
		result->size = mf2->size;
	} else if (!xscr2) {
		result->ptr = xdl_malloc(mf1->size);
		memcpy(result->ptr, mf1->ptr, mf1->size);
		result->size = mf1->size;
	} else {
		status = xdl_do_merge(&xe1, xscr1,
				      &xe2, xscr2,
				      xmp, result);
	}
	xdl_free_script(xscr1);
	xdl_free_script(xscr2);

	xdl_free_env(&xe1);
	xdl_free_env(&xe2);

	return status;
}
Example #2
0
void *xdl_mmfile_writeallocate(mmfile_t *mmf, long size) {
	long bsize;
	mmblock_t *wcur;
	char *blk;

	if (!(wcur = mmf->wcur) || wcur->size + size > wcur->bsize) {
		bsize = XDL_MAX(mmf->bsize, size);
		if (!(wcur = (mmblock_t *) xdl_malloc(sizeof(mmblock_t) + bsize))) {

			return NULL;
		}
		wcur->flags = 0;
		wcur->ptr = (char *) wcur + sizeof(mmblock_t);
		wcur->size = 0;
		wcur->bsize = bsize;
		wcur->next = NULL;
		if (!mmf->head)
			mmf->head = wcur;
		if (mmf->tail)
			mmf->tail->next = wcur;
		mmf->tail = wcur;
		mmf->wcur = wcur;
	}

	blk = wcur->ptr + wcur->size;
	wcur->size += size;
	mmf->fsize += size;

	return blk;
}
Example #3
0
static int xdl_append_merge(xdmerge_t **merge, int mode,
			    long i0, long chg0,
			    long i1, long chg1,
			    long i2, long chg2)
{
	xdmerge_t *m = *merge;
	if (m && (i1 <= m->i1 + m->chg1 || i2 <= m->i2 + m->chg2)) {
		if (mode != m->mode)
			m->mode = 0;
		m->chg0 = i0 + chg0 - m->i0;
		m->chg1 = i1 + chg1 - m->i1;
		m->chg2 = i2 + chg2 - m->i2;
	} else {
		m = xdl_malloc(sizeof(xdmerge_t));
		if (!m)
			return -1;
		m->next = NULL;
		m->mode = mode;
		m->i0 = i0;
		m->chg0 = chg0;
		m->i1 = i1;
		m->chg1 = chg1;
		m->i2 = i2;
		m->chg2 = chg2;
		if (*merge)
			(*merge)->next = m;
		*merge = m;
	}
	return 0;
}
Example #4
0
int xdl_bpatch_multi(mmbuffer_t *base, mmbuffer_t *mbpch, int n, xdemitcb_t *ecb) {
	int i, nobf, fnobf;
	mmoffbuffer_t *obf, *fobf;

	nobf = 1;
	if ((obf = (mmoffbuffer_t *) xdl_malloc(nobf * sizeof(mmoffbuffer_t))) == NULL) {

		return -1;
	}
	obf->off = 0;
	obf->ptr = base->ptr;
	obf->size = base->size;
	for (i = 0; i < n; i++) {
		if (xdl_bmerge(obf, nobf, &mbpch[i], &fobf, &fnobf) < 0) {

			xdl_free(obf);
			return -1;
		}
		xdl_free(obf);

		obf = fobf;
		nobf = fnobf;
	}
	if (xdl_bmerge_synt(obf, nobf, ecb) < 0) {

		xdl_free(obf);
		return -1;
	}
	xdl_free(obf);

	return 0;
}
Example #5
0
File: xdiffi.c Project: Advael/git
int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
		xdfenv_t *xe) {
	long ndiags;
	long *kvd, *kvdf, *kvdb;
	xdalgoenv_t xenv;
	diffdata_t dd1, dd2;

	if (XDF_DIFF_ALG(xpp->flags) == XDF_PATIENCE_DIFF)
		return xdl_do_patience_diff(mf1, mf2, xpp, xe);

	if (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF)
		return xdl_do_histogram_diff(mf1, mf2, xpp, xe);

	if (xdl_prepare_env(mf1, mf2, xpp, xe) < 0) {

		return -1;
	}

	/*
	 * Allocate and setup K vectors to be used by the differential algorithm.
	 * One is to store the forward path and one to store the backward path.
	 */
	ndiags = xe->xdf1.nreff + xe->xdf2.nreff + 3;
	if (!(kvd = (long *) xdl_malloc((2 * ndiags + 2) * sizeof(long)))) {

		xdl_free_env(xe);
		return -1;
	}
	kvdf = kvd;
	kvdb = kvdf + ndiags;
	kvdf += xe->xdf2.nreff + 1;
	kvdb += xe->xdf2.nreff + 1;

	xenv.mxcost = xdl_bogosqrt(ndiags);
	if (xenv.mxcost < XDL_MAX_COST_MIN)
		xenv.mxcost = XDL_MAX_COST_MIN;
	xenv.snake_cnt = XDL_SNAKE_CNT;
	xenv.heur_min = XDL_HEUR_MIN_COST;

	dd1.nrec = xe->xdf1.nreff;
	dd1.ha = xe->xdf1.ha;
	dd1.rchg = xe->xdf1.rchg;
	dd1.rindex = xe->xdf1.rindex;
	dd2.nrec = xe->xdf2.nreff;
	dd2.ha = xe->xdf2.ha;
	dd2.rchg = xe->xdf2.rchg;
	dd2.rindex = xe->xdf2.rindex;

	if (xdl_recs_cmp(&dd1, 0, dd1.nrec, &dd2, 0, dd2.nrec,
			 kvdf, kvdb, (xpp->flags & XDF_NEED_MINIMAL) != 0, &xenv) < 0) {

		xdl_free(kvd);
		xdl_free_env(xe);
		return -1;
	}

	xdl_free(kvd);

	return 0;
}
Example #6
0
/*
 * The idea is to start with the list of common unique lines sorted by
 * the order in file1.  For each of these pairs, the longest (partial)
 * sequence whose last element's line2 is smaller is determined.
 *
 * For efficiency, the sequences are kept in a list containing exactly one
 * item per sequence length: the sequence with the smallest last
 * element (in terms of line2).
 */
static struct entry *find_longest_common_sequence(struct hashmap *map)
{
	struct entry **sequence = xdl_malloc(map->nr * sizeof(struct entry *));
	int longest = 0, i;
	struct entry *entry;

	for (entry = map->first; entry; entry = entry->next) {
		if (!entry->line2 || entry->line2 == NON_UNIQUE)
			continue;
		i = binary_search(sequence, longest, entry);
		entry->previous = i < 0 ? NULL : sequence[i];
		sequence[++i] = entry;
		if (i == longest)
			longest++;
	}

	/* No common unique lines were found */
	if (!longest) {
		xdl_free(sequence);
		return NULL;
	}

	/* Iterate starting at the last element, adjusting the "next" members */
	entry = sequence[longest - 1];
	entry->next = NULL;
	while (entry->previous) {
		entry->previous->next = entry;
		entry = entry->previous;
	}
	xdl_free(sequence);
	return entry;
}
Example #7
0
/*
 * This function has to be called for each recursion into the inter-hunk
 * parts, as previously non-unique lines can become unique when being
 * restricted to a smaller part of the files.
 *
 * It is assumed that env has been prepared using xdl_prepare().
 */
static int fill_hashmap(mmfile_t *file1, mmfile_t *file2,
		xpparam_t const *xpp, xdfenv_t *env,
		struct hashmap *result,
		int line1, int count1, int line2, int count2)
{
	result->file1 = file1;
	result->file2 = file2;
	result->xpp = xpp;
	result->env = env;

	/* We know exactly how large we want the hash map */
	result->alloc = count1 * 2;
	result->entries = (struct entry *)
		xdl_malloc(result->alloc * sizeof(struct entry));
	if (!result->entries)
		return -1;
	memset(result->entries, 0, result->alloc * sizeof(struct entry));

	/* First, fill with entries from the first file */
	while (count1--)
		insert_record(xpp, line1++, result, 1);

	/* Then search for matches in the second file */
	while (count2--)
		insert_record(xpp, line2++, result, 2);

	return 0;
}
Example #8
0
int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
                xdfenv_t *xe) {
    long ndiags;
    long *kvd, *kvdf, *kvdb;
    xdalgoenv_t xenv;
    diffdata_t dd1, dd2;

    if (xdl_prepare_env(mf1, mf2, xpp, xe) < 0) {

        return -1;
    }

    /*
     * Allocate and setup K vectors to be used by the differential algorithm.
     * One is to store the forward path and one to store the backward path.
     */
    ndiags = xe->xdf1.nreff + xe->xdf2.nreff + 3;
    if (!(kvd = (long *) xdl_malloc((2 * ndiags + 2) * sizeof(long)))) {

        xdl_free_env(xe);
        return -1;
    }
    kvdf = kvd;
    kvdb = kvdf + ndiags;
    kvdf += xe->xdf2.nreff + 1;
    kvdb += xe->xdf2.nreff + 1;

    /*
     * Classical integer square root approximation using shifts.
     */
    xenv.mxcost = 1;
    for (; ndiags; ndiags >>= 2)
        xenv.mxcost <<= 1;
    if (xenv.mxcost < XDL_MAX_COST_MIN)
        xenv.mxcost = XDL_MAX_COST_MIN;
    xenv.snake_cnt = XDL_SNAKE_CNT;
    xenv.heur_min = XDL_HEUR_MIN_COST;

    dd1.nrec = xe->xdf1.nreff;
    dd1.ha = xe->xdf1.ha;
    dd1.rchg = xe->xdf1.rchg;
    dd1.rindex = xe->xdf1.rindex;
    dd2.nrec = xe->xdf2.nreff;
    dd2.ha = xe->xdf2.ha;
    dd2.rchg = xe->xdf2.rchg;
    dd2.rindex = xe->xdf2.rindex;

    if (xdl_recs_cmp(&dd1, 0, dd1.nrec, &dd2, 0, dd2.nrec,
                     kvdf, kvdb, (xpp->flags & XDF_NEED_MINIMAL) != 0, &xenv) < 0) {

        xdl_free(kvd);
        xdl_free_env(xe);
        return -1;
    }

    xdl_free(kvd);

    return 0;
}
Example #9
0
File: xdiffi.c Project: Advael/git
static xdchange_t *xdl_add_change(xdchange_t *xscr, long i1, long i2, long chg1, long chg2) {
	xdchange_t *xch;

	if (!(xch = (xdchange_t *) xdl_malloc(sizeof(xdchange_t))))
		return NULL;

	xch->next = xscr;
	xch->i1 = i1;
	xch->i2 = i2;
	xch->chg1 = chg1;
	xch->chg2 = chg2;

	return xch;
}
Example #10
0
/*
 * The idea is to start with the list of common unique lines sorted by
 * the order in file1.  For each of these pairs, the longest (partial)
 * sequence whose last element's line2 is smaller is determined.
 *
 * For efficiency, the sequences are kept in a list containing exactly one
 * item per sequence length: the sequence with the smallest last
 * element (in terms of line2).
 */
static struct entry *find_longest_common_sequence(struct hashmap *map)
{
	struct entry **sequence = (struct entry **)xdl_malloc(map->nr * sizeof(struct entry *));
	int longest = 0, i;
	struct entry *entry;
	/*
	 * If not -1, this entry in sequence must never be overridden.
	 * Therefore, overriding entries before this has no effect, so
	 * do not do that either.
	 */
	int anchor_i = -1;

	/* Added to silence Coverity. */
	if (sequence == NULL)
		return map->first;

	for (entry = map->first; entry; entry = entry->next) {
		if (!entry->line2 || entry->line2 == NON_UNIQUE)
			continue;
		i = binary_search(sequence, longest, entry);
		entry->previous = i < 0 ? NULL : sequence[i];
		++i;
		if (i <= anchor_i)
			continue;
		sequence[i] = entry;
		if (entry->anchor) {
			anchor_i = i;
			longest = anchor_i + 1;
		} else if (i == longest) {
			longest++;
		}
	}

	/* No common unique lines were found */
	if (!longest) {
		xdl_free(sequence);
		return NULL;
	}

	/* Iterate starting at the last element, adjusting the "next" members */
	entry = sequence[longest - 1];
	entry->next = NULL;
	while (entry->previous) {
		entry->previous->next = entry;
		entry = entry->previous;
	}
	xdl_free(sequence);
	return entry;
}
Example #11
0
static int xdl_init_recfile(mmfile_t *mf, int ispatch, recfile_t *rf) {
	long narec, nrec, bsize;
	recinfo_t *recs, *rrecs;
	char const *blk, *cur, *top, *eol;

	narec = xdl_guess_lines(mf);
	if (!(recs = (recinfo_t *) xdl_malloc(narec * sizeof(recinfo_t)))) {

		return -1;
	}
	nrec = 0;
	if ((cur = blk = (char const *)xdl_mmfile_first(mf, &bsize)) != NULL) {
		for (top = blk + bsize;;) {
			if (cur >= top) {
				if (!(cur = blk = (char const *)xdl_mmfile_next(mf, &bsize)))
					break;
				top = blk + bsize;
			}
			if (nrec >= narec) {
				narec *= 2;
				if (!(rrecs = (recinfo_t *)
				      xdl_realloc(recs, narec * sizeof(recinfo_t)))) {

					xdl_free(recs);
					return -1;
				}
				recs = rrecs;
			}
			recs[nrec].ptr = cur;
			if (!(eol = (char*)memchr(cur, '\n', top - cur)))
				eol = top - 1;
			recs[nrec].size = (long) (eol - cur) + 1;
			if (ispatch && *cur == '\\' && nrec > 0 && recs[nrec - 1].size > 0 &&
			    recs[nrec - 1].ptr[recs[nrec - 1].size - 1] == '\n')
				recs[nrec - 1].size--;
			else
				nrec++;
			cur = eol + 1;
		}
	}
	rf->mf = mf;
	rf->nrec = nrec;
	rf->recs = recs;

	return 0;
}
Example #12
0
static int xdl_bmerge_synt(mmoffbuffer_t *obf, int n, xdemitcb_t *ecb) {
	int i;
	mmbuffer_t *mb;

	if ((mb = (mmbuffer_t *) xdl_malloc(n * sizeof(mmbuffer_t))) == NULL) {

		return -1;
	}
	for (i = 0; i < n; i++) {
		mb[i].ptr = obf[i].ptr;
		mb[i].size = obf[i].size;
	}
	if (ecb->outf(ecb->priv, mb, n) < 0) {

		xdl_free(mb);
		return -1;
	}
	xdl_free(mb);

	return 0;
}
Example #13
0
long xdl_mmfile_ptradd(mmfile_t *mmf, char *ptr, long size, unsigned long flags) {
	mmblock_t *wcur;

	if (!(wcur = (mmblock_t *) xdl_malloc(sizeof(mmblock_t)))) {

		return -1;
	}
	wcur->flags = flags;
	wcur->ptr = ptr;
	wcur->size = wcur->bsize = size;
	wcur->next = NULL;
	if (!mmf->head)
		mmf->head = wcur;
	if (mmf->tail)
		mmf->tail->next = wcur;
	mmf->tail = wcur;
	mmf->wcur = wcur;

	mmf->fsize += size;

	return size;
}
Example #14
0
static int xdl_init_classifier(xdlclassifier_t *cf, long size, long flags) {
	long i;

	cf->flags = flags;

	cf->hbits = xdl_hashbits((unsigned int) size);
	cf->hsize = 1 << cf->hbits;

	if (xdl_cha_init(&cf->ncha, sizeof(xdlclass_t), size / 4 + 1) < 0) {

		return -1;
	}
	if (!(cf->rchash = (xdlclass_t **) xdl_malloc(cf->hsize * sizeof(xdlclass_t *)))) {

		xdl_cha_free(&cf->ncha);
		return -1;
	}
	for (i = 0; i < cf->hsize; i++)
		cf->rchash[i] = NULL;

	cf->count = 0;

	return 0;
}
Example #15
0
void *xdl_cha_alloc(chastore_t *cha) {
	chanode_t *ancur;
	void *data;

	if (!(ancur = cha->ancur) || ancur->icurr == cha->nsize) {
		if (!(ancur = (chanode_t *) xdl_malloc(sizeof(chanode_t) + cha->nsize))) {

			return NULL;
		}
		ancur->icurr = 0;
		ancur->next = NULL;
		if (cha->tail)
			cha->tail->next = ancur;
		if (!cha->head)
			cha->head = ancur;
		cha->tail = ancur;
		cha->ancur = ancur;
	}

	data = (char *) ancur + sizeof(chanode_t) + ancur->icurr;
	ancur->icurr += cha->isize;

	return data;
}
Example #16
0
long xdl_write_mmfile(mmfile_t *mmf, void const *data, long size) {
	long wsize, bsize, csize;
	mmblock_t *wcur;

	for (wsize = 0; wsize < size;) {
		wcur = mmf->wcur;
		if (wcur && (wcur->flags & XDL_MMB_READONLY))
			return wsize;
		if (!wcur || wcur->size == wcur->bsize ||
		    (mmf->flags & XDL_MMF_ATOMIC && wcur->size + size > wcur->bsize)) {
			bsize = XDL_MAX(mmf->bsize, size);
			if (!(wcur = (mmblock_t *) xdl_malloc(sizeof(mmblock_t) + bsize))) {

				return wsize;
			}
			wcur->flags = 0;
			wcur->ptr = (char *) wcur + sizeof(mmblock_t);
			wcur->size = 0;
			wcur->bsize = bsize;
			wcur->next = NULL;
			if (!mmf->head)
				mmf->head = wcur;
			if (mmf->tail)
				mmf->tail->next = wcur;
			mmf->tail = wcur;
			mmf->wcur = wcur;
		}
		csize = XDL_MIN(size - wsize, wcur->bsize - wcur->size);
		memcpy(wcur->ptr + wcur->size, (char const *) data + wsize, csize);
		wsize += csize;
		wcur->size += csize;
		mmf->fsize += csize;
	}

	return size;
}
Example #17
0
static int xdl_prepare_ctx(mmfile_t *mf, long narec, xpparam_t const *xpp,
			   xdlclassifier_t *cf, xdfile_t *xdf) {
	unsigned int hbits;
	long i, nrec, hsize, bsize;
	unsigned long hav;
	char const *blk, *cur, *top, *prev;
	xrecord_t *crec;
	xrecord_t **recs, **rrecs;
	xrecord_t **rhash;
	unsigned long *ha;
	char *rchg;
	long *rindex;

	if (xdl_cha_init(&xdf->rcha, sizeof(xrecord_t), narec / 4 + 1) < 0) {

		return -1;
	}
	if (!(recs = (xrecord_t **) xdl_malloc(narec * sizeof(xrecord_t *)))) {

		xdl_cha_free(&xdf->rcha);
		return -1;
	}

	hbits = xdl_hashbits((unsigned int) narec);
	hsize = 1 << hbits;
	if (!(rhash = (xrecord_t **) xdl_malloc(hsize * sizeof(xrecord_t *)))) {

		xdl_free(recs);
		xdl_cha_free(&xdf->rcha);
		return -1;
	}
	for (i = 0; i < hsize; i++)
		rhash[i] = NULL;

	nrec = 0;
	if ((cur = blk = xdl_mmfile_first(mf, &bsize)) != NULL) {
		for (top = blk + bsize;;) {
			if (cur >= top) {
				if (!(cur = blk = xdl_mmfile_next(mf, &bsize)))
					break;
				top = blk + bsize;
			}
			prev = cur;
			hav = xdl_hash_record(&cur, top, xpp->flags);
			if (nrec >= narec) {
				narec *= 2;
				if (!(rrecs = (xrecord_t **) xdl_realloc(recs, narec * sizeof(xrecord_t *)))) {

					xdl_free(rhash);
					xdl_free(recs);
					xdl_cha_free(&xdf->rcha);
					return -1;
				}
				recs = rrecs;
			}
			if (!(crec = xdl_cha_alloc(&xdf->rcha))) {

				xdl_free(rhash);
				xdl_free(recs);
				xdl_cha_free(&xdf->rcha);
				return -1;
			}
			crec->ptr = prev;
			crec->size = (long) (cur - prev);
			crec->ha = hav;
			recs[nrec++] = crec;

			if (xdl_classify_record(cf, rhash, hbits, crec) < 0) {

				xdl_free(rhash);
				xdl_free(recs);
				xdl_cha_free(&xdf->rcha);
				return -1;
			}
		}
	}

	if (!(rchg = (char *) xdl_malloc((nrec + 2) * sizeof(char)))) {

		xdl_free(rhash);
		xdl_free(recs);
		xdl_cha_free(&xdf->rcha);
		return -1;
	}
	memset(rchg, 0, (nrec + 2) * sizeof(char));

	if (!(rindex = (long *) xdl_malloc((nrec + 1) * sizeof(long)))) {

		xdl_free(rchg);
		xdl_free(rhash);
		xdl_free(recs);
		xdl_cha_free(&xdf->rcha);
		return -1;
	}
	if (!(ha = (unsigned long *) xdl_malloc((nrec + 1) * sizeof(unsigned long)))) {

		xdl_free(rindex);
		xdl_free(rchg);
		xdl_free(rhash);
		xdl_free(recs);
		xdl_cha_free(&xdf->rcha);
		return -1;
	}

	xdf->nrec = nrec;
	xdf->recs = recs;
	xdf->hbits = hbits;
	xdf->rhash = rhash;
	xdf->rchg = rchg + 1;
	xdf->rindex = rindex;
	xdf->nreff = 0;
	xdf->ha = ha;
	xdf->dstart = 0;
	xdf->dend = nrec - 1;

	return 0;
}
Example #18
0
int xdlt_auto_mbinregress(bdiffparam_t const *bdp, long size,
			  double rmod, int chmax, int n) {
	int i, res;
	mmbuffer_t *mbb;
	mmfile_t *mf, *mfc, *mfx;
	mmfile_t mfn, mff, mfd, mfb;
	xdemitcb_t ecb;

	if ((mbb = (mmbuffer_t *) xdl_malloc((n + 2) * sizeof(mmbuffer_t))) == NULL) {

		return -1;
	}
	if ((mf = mfc = (mmfile_t *) xdl_malloc((n + 2) * sizeof(mmfile_t))) == NULL) {

		xdl_free(mbb);
		return -1;
	}
	if (xdlt_create_file(mfc, size) < 0) {

		xdl_free(mf);
		xdl_free(mbb);
		return -1;
	}
	mbb[0].ptr = (char *) xdl_mmfile_first(mfc, &mbb[0].size);
	mfc++;
	mfx = mf;
	for (i = 0; i < n; i++) {
		if (xdlt_change_file(mfx, &mfn, rmod, chmax) < 0) {

			if (mfx != mf) xdl_free_mmfile(mfx);
			for (; i >= 0; i--)
				xdl_free_mmfile(mf + i);
			xdl_free(mf);
			xdl_free(mbb);
			return -1;
		}
		if (xdl_mmfile_compact(&mfn, &mff, XDLT_STD_BLKSIZE, XDL_MMF_ATOMIC) < 0) {

			xdl_free_mmfile(&mfn);
			if (mfx != mf) xdl_free_mmfile(mfx);
			for (; i >= 0; i--)
				xdl_free_mmfile(mf + i);
			xdl_free(mf);
			xdl_free(mbb);
			return -1;
		}
		xdl_free_mmfile(&mfn);
		if (xdlt_do_bindiff(mfx, &mff, bdp, &mfd) < 0) {

			xdl_free_mmfile(&mff);
			if (mfx != mf) xdl_free_mmfile(mfx);
			for (; i >= 0; i--)
				xdl_free_mmfile(mf + i);
			xdl_free(mf);
			xdl_free(mbb);
			return -1;
		}
		if (mfx != mf) xdl_free_mmfile(mfx);
		mfx = &mfb;
		*mfx = mff;
		if (xdl_mmfile_compact(&mfd, mfc, XDLT_STD_BLKSIZE, XDL_MMF_ATOMIC) < 0) {

			xdl_free_mmfile(&mfd);
			xdl_free_mmfile(mfx);
			for (; i >= 0; i--)
				xdl_free_mmfile(mf + i);
			xdl_free(mf);
			xdl_free(mbb);
			return -1;
		}
		mbb[i + 1].ptr = (char *) xdl_mmfile_first(mfc, &mbb[i + 1].size);
		mfc++;
		xdl_free_mmfile(&mfd);
	}
	if (xdl_init_mmfile(mfc, XDLT_STD_BLKSIZE, XDL_MMF_ATOMIC) < 0) {

		xdl_free_mmfile(mfx);
		for (i = n; i >= 0; i--)
			xdl_free_mmfile(mf + i);
		xdl_free(mf);
		xdl_free(mbb);
		return -1;
	}
	ecb.priv = mfc;
	ecb.outf = xdlt_mmfile_outf;
	if ((res = xdl_bpatch_multi(&mbb[0], &mbb[1], n, &ecb)) == 0)
		res = xdl_mmfile_cmp(mfx, mfc);

	xdl_free_mmfile(mfx);
	for (i = n + 1; i >= 0; i--)
		xdl_free_mmfile(mf + i);
	xdl_free(mf);
	xdl_free(mbb);

	return res;
}
Example #19
0
static int find_lcs(xpparam_t const *xpp, xdfenv_t *env,
		    struct region *lcs,
		    int line1, int count1, int line2, int count2)
{
	int b_ptr;
	int sz, ret = -1;
	struct histindex index;

	memset(&index, 0, sizeof(index));

	index.env = env;
	index.xpp = xpp;

	index.records = NULL;
	index.line_map = NULL;
	/* in case of early xdl_cha_free() */
	index.rcha.head = NULL;

	index.table_bits = xdl_hashbits(count1);
	sz = index.records_size = 1 << index.table_bits;
	sz *= sizeof(struct record *);
	if (!(index.records = (struct record **) xdl_malloc(sz)))
		goto cleanup;
	memset(index.records, 0, sz);

	sz = index.line_map_size = count1;
	sz *= sizeof(struct record *);
	if (!(index.line_map = (struct record **) xdl_malloc(sz)))
		goto cleanup;
	memset(index.line_map, 0, sz);

	sz = index.line_map_size;
	sz *= sizeof(unsigned int);
	if (!(index.next_ptrs = (unsigned int *) xdl_malloc(sz)))
		goto cleanup;
	memset(index.next_ptrs, 0, sz);

	/* lines / 4 + 1 comes from xprepare.c:xdl_prepare_ctx() */
	if (xdl_cha_init(&index.rcha, sizeof(struct record), count1 / 4 + 1) < 0)
		goto cleanup;

	index.ptr_shift = line1;
	index.max_chain_length = 64;

	if (scanA(&index, line1, count1))
		goto cleanup;

	index.cnt = index.max_chain_length + 1;

	for (b_ptr = line2; b_ptr <= LINE_END(2); )
		b_ptr = try_lcs(&index, lcs, b_ptr, line1, count1, line2, count2);

	if (index.has_common && index.max_chain_length < index.cnt)
		ret = 1;
	else
		ret = 0;

cleanup:
	free_index(&index);
	return ret;
}
Example #20
0
/*
 * Sometimes, changes are not quite identical, but differ in only a few
 * lines. Try hard to show only these few lines as conflicting.
 */
static int xdl_refine_conflicts(xdfenv_t *xe1, xdfenv_t *xe2, xdmerge_t *m,
		xpparam_t const *xpp)
{
	for (; m; m = m->next) {
		mmfile_t t1, t2;
		xdfenv_t xe;
		xdchange_t *xscr, *x;
		int i1 = m->i1, i2 = m->i2;

		/* let's handle just the conflicts */
		if (m->mode)
			continue;

		/* no sense refining a conflict when one side is empty */
		if (m->chg1 == 0 || m->chg2 == 0)
			continue;

		/*
		 * This probably does not work outside git, since
		 * we have a very simple mmfile structure.
		 */
		t1.ptr = (char *)xe1->xdf2.recs[m->i1]->ptr;
		t1.size = xe1->xdf2.recs[m->i1 + m->chg1 - 1]->ptr
			+ xe1->xdf2.recs[m->i1 + m->chg1 - 1]->size - t1.ptr;
		t2.ptr = (char *)xe2->xdf2.recs[m->i2]->ptr;
		t2.size = xe2->xdf2.recs[m->i2 + m->chg2 - 1]->ptr
			+ xe2->xdf2.recs[m->i2 + m->chg2 - 1]->size - t2.ptr;
		if (xdl_do_diff(&t1, &t2, xpp, &xe) < 0)
			return -1;
		if (xdl_change_compact(&xe.xdf1, &xe.xdf2, xpp->flags) < 0 ||
		    xdl_change_compact(&xe.xdf2, &xe.xdf1, xpp->flags) < 0 ||
		    xdl_build_script(&xe, &xscr) < 0) {
			xdl_free_env(&xe);
			return -1;
		}
		if (!xscr) {
			/* If this happens, the changes are identical. */
			xdl_free_env(&xe);
			m->mode = 4;
			continue;
		}
		x = xscr;
		m->i1 = xscr->i1 + i1;
		m->chg1 = xscr->chg1;
		m->i2 = xscr->i2 + i2;
		m->chg2 = xscr->chg2;
		while (xscr->next) {
			xdmerge_t *m2 = xdl_malloc(sizeof(xdmerge_t));
			if (!m2) {
				xdl_free_env(&xe);
				xdl_free_script(x);
				return -1;
			}
			xscr = xscr->next;
			m2->next = m->next;
			m->next = m2;
			m = m2;
			m->mode = 0;
			m->i1 = xscr->i1 + i1;
			m->chg1 = xscr->chg1;
			m->i2 = xscr->i2 + i2;
			m->chg2 = xscr->chg2;
		}
		xdl_free_env(&xe);
		xdl_free_script(x);
	}
	return 0;
}
Example #21
0
static int xdl_bmerge(mmoffbuffer_t *obf, int n, mmbuffer_t *mbfp, mmoffbuffer_t **probf,
		      int *pnobf) {
	int i, aobf, nobf;
	long ooff, off, csize;
	unsigned long fp, ofp;
	unsigned char const *data, *top;
	mmoffbuffer_t *robf, *cobf;

	if (mbfp->size < XDL_BPATCH_HDR_SIZE) {

		return -1;
	}
	data = (unsigned char const *) mbfp->ptr;
	top = data + mbfp->size;

	ofp = xdl_mmob_adler32(obf, n);
	XDL_LE32_GET(data, fp);
	data += 4;
	XDL_LE32_GET(data, csize);
	data += 4;
	if (fp != ofp || csize != xdl_mmob_size(obf, n)) {

		return -1;
	}
	aobf = XDL_MOBF_MINALLOC;
	nobf = 0;
	if ((robf = (mmoffbuffer_t *) xdl_malloc(aobf * sizeof(mmoffbuffer_t))) == NULL) {

		return -1;
	}

	for (ooff = 0; data < top;) {
		if (*data == XDL_BDOP_INS) {
			data++;

			if ((cobf = xdl_mmob_new(&robf, &nobf, &aobf)) == NULL) {

				xdl_free(robf);
				return -1;
			}
			cobf->off = ooff;
			cobf->size = (long) *data++;
			cobf->ptr = (char *) data;

			data += cobf->size;
			ooff += cobf->size;
		} else if (*data == XDL_BDOP_INSB) {
			data++;
			XDL_LE32_GET(data, csize);
			data += 4;

			if ((cobf = xdl_mmob_new(&robf, &nobf, &aobf)) == NULL) {

				xdl_free(robf);
				return -1;
			}
			cobf->off = ooff;
			cobf->size = csize;
			cobf->ptr = (char *) data;

			data += cobf->size;
			ooff += cobf->size;
		} else if (*data == XDL_BDOP_CPY) {
			data++;
			XDL_LE32_GET(data, off);
			data += 4;
			XDL_LE32_GET(data, csize);
			data += 4;

			if ((i = xdl_mmob_find_cntr(obf, n, off)) < 0) {

				xdl_free(robf);
				return -1;
			}
			off -= obf[i].off;
			for (; i < n && csize > 0; i++, off = 0) {
				if ((cobf = xdl_mmob_new(&robf, &nobf, &aobf)) == NULL) {

					xdl_free(robf);
					return -1;
				}
				cobf->off = ooff;
				cobf->size = XDL_MIN(csize, obf[i].size - off);
				cobf->ptr = obf[i].ptr + off;

				ooff += cobf->size;
				csize -= cobf->size;
			}
			if (csize > 0) {

				xdl_free(robf);
				return -1;
			}
		} else {

			xdl_free(robf);
			return -1;
		}
	}
	*probf = robf;
	*pnobf = nobf;

	return 0;
}
Example #22
0
static int histogram_diff(xpparam_t const *xpp, xdfenv_t *env,
	int line1, int count1, int line2, int count2)
{
	struct histindex index;
	struct region lcs;
	int sz;
	int result = -1;

	if (count1 <= 0 && count2 <= 0)
		return 0;

	if (LINE_END(1) >= MAX_PTR)
		return -1;

	if (!count1) {
		while(count2--)
			env->xdf2.rchg[line2++ - 1] = 1;
		return 0;
	} else if (!count2) {
		while(count1--)
			env->xdf1.rchg[line1++ - 1] = 1;
		return 0;
	}

	memset(&index, 0, sizeof(index));

	index.env = env;
	index.xpp = xpp;

	index.records = NULL;
	index.line_map = NULL;
	/* in case of early xdl_cha_free() */
	index.rcha.head = NULL;

	index.table_bits = xdl_hashbits(count1);
	sz = index.records_size = 1 << index.table_bits;
	sz *= sizeof(struct record *);
	if (!(index.records = (struct record **) xdl_malloc(sz)))
		goto cleanup;
	memset(index.records, 0, sz);

	sz = index.line_map_size = count1;
	sz *= sizeof(struct record *);
	if (!(index.line_map = (struct record **) xdl_malloc(sz)))
		goto cleanup;
	memset(index.line_map, 0, sz);

	sz = index.line_map_size;
	sz *= sizeof(unsigned int);
	if (!(index.next_ptrs = (unsigned int *) xdl_malloc(sz)))
		goto cleanup;
	memset(index.next_ptrs, 0, sz);

	/* lines / 4 + 1 comes from xprepare.c:xdl_prepare_ctx() */
	if (xdl_cha_init(&index.rcha, sizeof(struct record), count1 / 4 + 1) < 0)
		goto cleanup;

	index.ptr_shift = line1;
	index.max_chain_length = 64;

	memset(&lcs, 0, sizeof(lcs));
	if (find_lcs(&index, &lcs, line1, count1, line2, count2))
		result = fall_back_to_classic_diff(&index, line1, count1, line2, count2);
	else {
		if (lcs.begin1 == 0 && lcs.begin2 == 0) {
			while (count1--)
				env->xdf1.rchg[line1++ - 1] = 1;
			while (count2--)
				env->xdf2.rchg[line2++ - 1] = 1;
			result = 0;
		} else {
			result = histogram_diff(xpp, env,
						line1, lcs.begin1 - line1,
						line2, lcs.begin2 - line2);
			if (result)
				goto cleanup;
			result = histogram_diff(xpp, env,
						lcs.end1 + 1, LINE_END(1) - lcs.end1,
						lcs.end2 + 1, LINE_END(2) - lcs.end2);
			if (result)
				goto cleanup;
		}
	}

cleanup:
	xdl_free(index.records);
	xdl_free(index.line_map);
	xdl_free(index.next_ptrs);
	xdl_cha_free(&index.rcha);

	return result;
}
Example #23
0
/*
 * level == 0: mark all overlapping changes as conflict
 * level == 1: mark overlapping changes as conflict only if not identical
 * level == 2: analyze non-identical changes for minimal conflict set
 * level == 3: analyze non-identical changes for minimal conflict set, but
 *             treat hunks not containing any letter or number as conflicting
 *
 * returns < 0 on error, == 0 for no conflicts, else number of conflicts
 */
static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1,
		xdfenv_t *xe2, xdchange_t *xscr2,
		xmparam_t const *xmp, mmbuffer_t *result)
{
	xdmerge_t *changes, *c;
	xpparam_t const *xpp = &xmp->xpp;
	const char *const ancestor_name = xmp->ancestor;
	const char *const name1 = xmp->file1;
	const char *const name2 = xmp->file2;
	int i0, i1, i2, chg0, chg1, chg2;
	int level = xmp->level;
	int style = xmp->style;
	int favor = xmp->favor;

	if (style == XDL_MERGE_DIFF3) {
		/*
		 * "diff3 -m" output does not make sense for anything
		 * more aggressive than XDL_MERGE_EAGER.
		 */
		if (XDL_MERGE_EAGER < level)
			level = XDL_MERGE_EAGER;
	}

	c = changes = NULL;

	while (xscr1 && xscr2) {
		if (!changes)
			changes = c;
		if (xscr1->i1 + xscr1->chg1 < xscr2->i1) {
			i0 = xscr1->i1;
			i1 = xscr1->i2;
			i2 = xscr2->i2 - xscr2->i1 + xscr1->i1;
			chg0 = xscr1->chg1;
			chg1 = xscr1->chg2;
			chg2 = xscr1->chg1;
			if (xdl_append_merge(&c, 1,
					     i0, chg0, i1, chg1, i2, chg2)) {
				xdl_cleanup_merge(changes);
				return -1;
			}
			xscr1 = xscr1->next;
			continue;
		}
		if (xscr2->i1 + xscr2->chg1 < xscr1->i1) {
			i0 = xscr2->i1;
			i1 = xscr1->i2 - xscr1->i1 + xscr2->i1;
			i2 = xscr2->i2;
			chg0 = xscr2->chg1;
			chg1 = xscr2->chg1;
			chg2 = xscr2->chg2;
			if (xdl_append_merge(&c, 2,
					     i0, chg0, i1, chg1, i2, chg2)) {
				xdl_cleanup_merge(changes);
				return -1;
			}
			xscr2 = xscr2->next;
			continue;
		}
		if (level == XDL_MERGE_MINIMAL || xscr1->i1 != xscr2->i1 ||
				xscr1->chg1 != xscr2->chg1 ||
				xscr1->chg2 != xscr2->chg2 ||
				xdl_merge_cmp_lines(xe1, xscr1->i2,
					xe2, xscr2->i2,
					xscr1->chg2, xpp->flags)) {
			/* conflict */
			int off = xscr1->i1 - xscr2->i1;
			int ffo = off + xscr1->chg1 - xscr2->chg1;

			i0 = xscr1->i1;
			i1 = xscr1->i2;
			i2 = xscr2->i2;
			if (off > 0) {
				i0 -= off;
				i1 -= off;
			}
			else
				i2 += off;
			chg0 = xscr1->i1 + xscr1->chg1 - i0;
			chg1 = xscr1->i2 + xscr1->chg2 - i1;
			chg2 = xscr2->i2 + xscr2->chg2 - i2;
			if (ffo < 0) {
				chg0 -= ffo;
				chg1 -= ffo;
			} else
				chg2 += ffo;
			if (xdl_append_merge(&c, 0,
					     i0, chg0, i1, chg1, i2, chg2)) {
				xdl_cleanup_merge(changes);
				return -1;
			}
		}

		i1 = xscr1->i1 + xscr1->chg1;
		i2 = xscr2->i1 + xscr2->chg1;

		if (i1 >= i2)
			xscr2 = xscr2->next;
		if (i2 >= i1)
			xscr1 = xscr1->next;
	}
	while (xscr1) {
		if (!changes)
			changes = c;
		i0 = xscr1->i1;
		i1 = xscr1->i2;
		i2 = xscr1->i1 + xe2->xdf2.nrec - xe2->xdf1.nrec;
		chg0 = xscr1->chg1;
		chg1 = xscr1->chg2;
		chg2 = xscr1->chg1;
		if (xdl_append_merge(&c, 1,
				     i0, chg0, i1, chg1, i2, chg2)) {
			xdl_cleanup_merge(changes);
			return -1;
		}
		xscr1 = xscr1->next;
	}
	while (xscr2) {
		if (!changes)
			changes = c;
		i0 = xscr2->i1;
		i1 = xscr2->i1 + xe1->xdf2.nrec - xe1->xdf1.nrec;
		i2 = xscr2->i2;
		chg0 = xscr2->chg1;
		chg1 = xscr2->chg1;
		chg2 = xscr2->chg2;
		if (xdl_append_merge(&c, 2,
				     i0, chg0, i1, chg1, i2, chg2)) {
			xdl_cleanup_merge(changes);
			return -1;
		}
		xscr2 = xscr2->next;
	}
	if (!changes)
		changes = c;
	/* refine conflicts */
	if (XDL_MERGE_ZEALOUS <= level &&
	    (xdl_refine_conflicts(xe1, xe2, changes, xpp) < 0 ||
	     xdl_simplify_non_conflicts(xe1, changes,
					XDL_MERGE_ZEALOUS < level) < 0)) {
		xdl_cleanup_merge(changes);
		return -1;
	}
	/* output */
	if (result) {
		int marker_size = xmp->marker_size;
		int mark_all = xmp->mark_all;
		int size = xdl_fill_merge_buffer(xe1, name1, xe2, name2,
						 ancestor_name,
						 favor, changes, NULL, style,
						 marker_size, mark_all);
		result->ptr = xdl_malloc(size);
		if (!result->ptr) {
			xdl_cleanup_merge(changes);
			return -1;
		}
		result->size = size;
		xdl_fill_merge_buffer(xe1, name1, xe2, name2,
				      ancestor_name, favor, changes,
				      result->ptr, style, marker_size, mark_all);
	}
	return xdl_cleanup_merge(changes);
}
Example #24
0
/*
 * Try to reduce the problem complexity, discard records that have no
 * matches on the other file. Also, lines that have multiple matches
 * might be potentially discarded if they happear in a run of discardable.
 */
static int xdl_cleanup_records(xdfile_t *xdf1, xdfile_t *xdf2) {
	long i, nm, rhi, nreff, mlim;
	unsigned long hav;
	xrecord_t **recs;
	xrecord_t *rec;
	char *dis, *dis1, *dis2;

	if (!(dis = (char *) xdl_malloc(xdf1->nrec + xdf2->nrec + 2))) {

		return -1;
	}
	memset(dis, 0, xdf1->nrec + xdf2->nrec + 2);
	dis1 = dis;
	dis2 = dis1 + xdf1->nrec + 1;

	if ((mlim = xdl_bogosqrt(xdf1->nrec)) > XDL_MAX_EQLIMIT)
		mlim = XDL_MAX_EQLIMIT;
	for (i = xdf1->dstart, recs = &xdf1->recs[xdf1->dstart]; i <= xdf1->dend; i++, recs++) {
		hav = (*recs)->ha;
		rhi = (long) XDL_HASHLONG(hav, xdf2->hbits);
		for (nm = 0, rec = xdf2->rhash[rhi]; rec; rec = rec->next)
			if (rec->ha == hav && ++nm == mlim)
				break;
		dis1[i] = (nm == 0) ? 0: (nm >= mlim) ? 2: 1;
	}

	if ((mlim = xdl_bogosqrt(xdf2->nrec)) > XDL_MAX_EQLIMIT)
		mlim = XDL_MAX_EQLIMIT;
	for (i = xdf2->dstart, recs = &xdf2->recs[xdf2->dstart]; i <= xdf2->dend; i++, recs++) {
		hav = (*recs)->ha;
		rhi = (long) XDL_HASHLONG(hav, xdf1->hbits);
		for (nm = 0, rec = xdf1->rhash[rhi]; rec; rec = rec->next)
			if (rec->ha == hav && ++nm == mlim)
				break;
		dis2[i] = (nm == 0) ? 0: (nm >= mlim) ? 2: 1;
	}

	for (nreff = 0, i = xdf1->dstart, recs = &xdf1->recs[xdf1->dstart];
	     i <= xdf1->dend; i++, recs++) {
		if (dis1[i] == 1 ||
		    (dis1[i] == 2 && !xdl_clean_mmatch(dis1, i, xdf1->dstart, xdf1->dend))) {
			xdf1->rindex[nreff] = i;
			xdf1->ha[nreff] = (*recs)->ha;
			nreff++;
		} else
			xdf1->rchg[i] = 1;
	}
	xdf1->nreff = nreff;

	for (nreff = 0, i = xdf2->dstart, recs = &xdf2->recs[xdf2->dstart];
	     i <= xdf2->dend; i++, recs++) {
		if (dis2[i] == 1 ||
		    (dis2[i] == 2 && !xdl_clean_mmatch(dis2, i, xdf2->dstart, xdf2->dend))) {
			xdf2->rindex[nreff] = i;
			xdf2->ha[nreff] = (*recs)->ha;
			nreff++;
		} else
			xdf2->rchg[i] = 1;
	}
	xdf2->nreff = nreff;

	xdl_free(dis);

	return 0;
}