changeset 7436:bea4f38a0f8d

Make multithread-safe.
author Bruno Haible <bruno@clisp.org>
date Sat, 07 Oct 2006 16:52:57 +0000
parents 483a70ceec47
children e70f23471c45
files lib/analyze.c lib/diffseq.h
diffstat 2 files changed, 56 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- a/lib/analyze.c	Sat Oct 07 16:52:38 2006 +0000
+++ b/lib/analyze.c	Sat Oct 07 16:52:57 2006 +0000
@@ -465,7 +465,6 @@
 int
 diff_2_files (struct comparison *cmp)
 {
-  lin diags;
   int f;
   struct change *e, *p;
   struct change *script;
@@ -535,6 +534,10 @@
     }
   else
     {
+      struct context ctxt;
+      lin diags;
+      OFFSET too_expensive;
+
       /* Allocate vectors for the results of comparison:
 	 a flag for each line of each file, saying whether that line
 	 is an insertion or deletion.
@@ -554,31 +557,31 @@
       /* Now do the main comparison algorithm, considering just the
 	 undiscarded lines.  */
 
-      xvec = cmp->file[0].undiscarded;
-      yvec = cmp->file[1].undiscarded;
+      ctxt.xvec = cmp->file[0].undiscarded;
+      ctxt.yvec = cmp->file[1].undiscarded;
       diags = (cmp->file[0].nondiscarded_lines
 	       + cmp->file[1].nondiscarded_lines + 3);
-      fdiag = xmalloc (diags * (2 * sizeof *fdiag));
-      bdiag = fdiag + diags;
-      fdiag += cmp->file[1].nondiscarded_lines + 1;
-      bdiag += cmp->file[1].nondiscarded_lines + 1;
+      ctxt.fdiag = xmalloc (diags * (2 * sizeof *fdiag));
+      ctxt.bdiag = fdiag + diags;
+      ctxt.fdiag += cmp->file[1].nondiscarded_lines + 1;
+      ctxt.bdiag += cmp->file[1].nondiscarded_lines + 1;
 
-      heuristic = speed_large_files;
+      ctxt.heuristic = speed_large_files;
 
       /* Set TOO_EXPENSIVE to be approximate square root of input size,
 	 bounded below by 256.  */
       too_expensive = 1;
       for (;  diags != 0;  diags >>= 2)
 	too_expensive <<= 1;
-      too_expensive = MAX (256, too_expensive);
+      ctxt.too_expensive = MAX (256, too_expensive);
 
       files[0] = cmp->file[0];
       files[1] = cmp->file[1];
 
       compareseq (0, cmp->file[0].nondiscarded_lines,
-		  0, cmp->file[1].nondiscarded_lines, minimal);
+		  0, cmp->file[1].nondiscarded_lines, minimal, &ctxt);
 
-      free (fdiag - (cmp->file[1].nondiscarded_lines + 1));
+      free (ctxt.fdiag - (cmp->file[1].nondiscarded_lines + 1));
 
       /* Modify the results slightly to make them prettier
 	 in cases where that can validly be done.  */
--- a/lib/diffseq.h	Sat Oct 07 16:52:38 2006 +0000
+++ b/lib/diffseq.h	Sat Oct 07 16:52:57 2006 +0000
@@ -52,33 +52,38 @@
 #define OFFSET_MAX \
   ((((OFFSET)1 << (sizeof (OFFSET_MAX) * CHAR_BIT - 2)) - 1) * 2 + 1)
 
-/* Vectors being compared. */
-static const ELEMENT *xvec, *yvec;
+/*
+ * Context of comparison operation.
+ */
+struct context
+{
+  /* Vectors being compared. */
+  const ELEMENT *xvec;
+  const ELEMENT *yvec;
 
-/* Vector, indexed by diagonal, containing 1 + the X coordinate of the point
-   furthest along the given diagonal in the forward search of the edit
-   matrix. */
-static OFFSET *fdiag;
-
-/* Vector, indexed by diagonal, containing the X coordinate of the point
-   furthest along the given diagonal in the backward search of the edit
-   matrix. */
-static OFFSET *bdiag;
+  /* Vector, indexed by diagonal, containing 1 + the X coordinate of the point
+     furthest along the given diagonal in the forward search of the edit
+     matrix. */
+  OFFSET *fdiag;
 
-#ifdef USE_HEURISTIC
-/* This corresponds to the diff -H flag.  With this heuristic, for
-   vectors with a constant small density of changes, the algorithm is
-   linear in the vectors size.  This is unlikely in typical uses of
-   fstrcmp, and so is usually compiled out.  Besides, there is no
-   interface to set it true.  */
-int heuristic;
-#endif
+  /* Vector, indexed by diagonal, containing the X coordinate of the point
+     furthest along the given diagonal in the backward search of the edit
+     matrix. */
+  OFFSET *bdiag;
 
-/* Edit scripts longer than this are too expensive to compute.  */
-static OFFSET too_expensive;
+  #ifdef USE_HEURISTIC
+  /* This corresponds to the diff -H flag.  With this heuristic, for
+     vectors with a constant small density of changes, the algorithm is
+     linear in the vectors size.  */
+  int heuristic;
+  #endif
 
-/* Snakes bigger than this are considered `big'.  */
-#define SNAKE_LIMIT 20
+  /* Edit scripts longer than this are too expensive to compute.  */
+  OFFSET too_expensive;
+
+  /* Snakes bigger than this are considered `big'.  */
+  #define SNAKE_LIMIT 20
+};
 
 struct partition
 {
@@ -119,12 +124,12 @@
 
 static void
 diag (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, bool find_minimal,
-      struct partition *part)
+      struct partition *part, struct context *ctxt)
 {
-  OFFSET *const fd = fdiag;	/* Give the compiler a chance. */
-  OFFSET *const bd = bdiag;	/* Additional help for the compiler. */
-  const ELEMENT *const xv = xvec;	/* Still more help for the compiler. */
-  const ELEMENT *const yv = yvec;	/* And more and more . . . */
+  OFFSET *const fd = ctxt->fdiag;	/* Give the compiler a chance. */
+  OFFSET *const bd = ctxt->bdiag;	/* Additional help for the compiler. */
+  const ELEMENT *const xv = ctxt->xvec;	/* Still more help for the compiler. */
+  const ELEMENT *const yv = ctxt->yvec;	/* And more and more . . . */
   const OFFSET dmin = xoff - ylim;	/* Minimum valid diagonal. */
   const OFFSET dmax = xlim - yoff;	/* Maximum valid diagonal. */
   const OFFSET fmid = xoff - yoff;	/* Center diagonal of top-down search. */
@@ -227,7 +232,7 @@
 	 With this heuristic, for vectors with a constant small density
 	 of changes, the algorithm is linear in the vector size.  */
 
-      if (c > 200 && big_snake && heuristic)
+      if (c > 200 && big_snake && ctxt->heuristic)
 	{
 	  OFFSET best = 0;
 
@@ -304,7 +309,7 @@
 
       /* Heuristic: if we've gone well beyond the call of duty,
 	 give up and report halfway between our best results so far.  */
-      if (c >= too_expensive)
+      if (c >= ctxt->too_expensive)
 	{
 	  OFFSET fxybest;
 	  OFFSET bxybest;
@@ -376,10 +381,11 @@
    expensive it is.  */
 
 static void
-compareseq (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, bool find_minimal)
+compareseq (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim,
+	    bool find_minimal, struct context *ctxt)
 {
-  const ELEMENT *xv = xvec; /* Help the compiler.  */
-  const ELEMENT *yv = yvec;
+  const ELEMENT *xv = ctxt->xvec; /* Help the compiler.  */
+  const ELEMENT *yv = ctxt->yvec;
 
   /* Slide down the bottom initial diagonal. */
   while (xoff < xlim && yoff < ylim && xv[xoff] == yv[yoff])
@@ -406,11 +412,11 @@
       struct partition part IF_LINT (= {0});
 
       /* Find a point of correspondence in the middle of the vectors.  */
-      diag (xoff, xlim, yoff, ylim, find_minimal, &part);
+      diag (xoff, xlim, yoff, ylim, find_minimal, &part, ctxt);
 
       /* Use the partitions to split this problem into subproblems.  */
-      compareseq (xoff, part.xmid, yoff, part.ymid, part.lo_minimal);
-      compareseq (part.xmid, xlim, part.ymid, ylim, part.hi_minimal);
+      compareseq (xoff, part.xmid, yoff, part.ymid, part.lo_minimal, ctxt);
+      compareseq (part.xmid, xlim, part.ymid, ylim, part.hi_minimal, ctxt);
     }
 }